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,364 @@
1
+ import {
2
+ hasQmd,
3
+ withQmdIndexArgs
4
+ } from "./chunk-EK6S23ZB.js";
5
+ import {
6
+ DEFAULT_CATEGORIES
7
+ } from "./chunk-2CDEETQN.js";
8
+
9
+ // src/commands/setup.ts
10
+ import * as fs from "fs";
11
+ import * as os from "os";
12
+ import * as path from "path";
13
+ import { execFileSync } from "child_process";
14
+ var CONFIG_FILE = ".clawvault.json";
15
+ function resolveVaultTarget(vaultOverride) {
16
+ if (vaultOverride) {
17
+ const vaultPath = path.resolve(vaultOverride);
18
+ return { vaultPath, source: "--vault flag", existed: fs.existsSync(vaultPath) };
19
+ }
20
+ const envPath = process.env.CLAWVAULT_PATH?.trim();
21
+ const home = os.homedir();
22
+ if (envPath) {
23
+ const vaultPath = path.resolve(envPath);
24
+ return { vaultPath, source: "CLAWVAULT_PATH", existed: fs.existsSync(vaultPath) };
25
+ }
26
+ const candidates = [
27
+ { vaultPath: path.join(home, ".openclaw", "workspace", "memory"), source: "OpenClaw default" },
28
+ { vaultPath: path.resolve(process.cwd(), "memory"), source: "./memory" },
29
+ { vaultPath: path.join(home, "memory"), source: "~/memory" }
30
+ ];
31
+ for (const candidate of candidates) {
32
+ if (fs.existsSync(candidate.vaultPath)) {
33
+ return { ...candidate, existed: true };
34
+ }
35
+ }
36
+ const fallback = candidates[0];
37
+ return { ...fallback, existed: false };
38
+ }
39
+ function ensureVaultStructure(vaultPath) {
40
+ fs.mkdirSync(vaultPath, { recursive: true });
41
+ for (const category of DEFAULT_CATEGORIES) {
42
+ fs.mkdirSync(path.join(vaultPath, category), { recursive: true });
43
+ }
44
+ const configPath = path.join(vaultPath, CONFIG_FILE);
45
+ if (fs.existsSync(configPath)) return false;
46
+ const now = (/* @__PURE__ */ new Date()).toISOString();
47
+ const name = path.basename(vaultPath);
48
+ const meta = {
49
+ name,
50
+ version: "1.0.0",
51
+ created: now,
52
+ lastUpdated: now,
53
+ categories: DEFAULT_CATEGORIES,
54
+ documentCount: 0,
55
+ qmdCollection: name,
56
+ qmdRoot: vaultPath
57
+ };
58
+ fs.writeFileSync(configPath, JSON.stringify(meta, null, 2));
59
+ return true;
60
+ }
61
+ function writeBases(vaultPath, force) {
62
+ const basesFiles = {
63
+ "all-tasks.base": `filters:
64
+ and:
65
+ - file.inFolder("tasks")
66
+ - status != "done"
67
+ formulas:
68
+ age: (now() - file.ctime).days
69
+ status_icon: if(status == "blocked", "\u{1F534}", if(status == "in-progress", "\u{1F528}", if(status == "open", "\u26AA", "\u2705")))
70
+ views:
71
+ - type: table
72
+ name: All Active Tasks
73
+ groupBy:
74
+ property: status
75
+ direction: ASC
76
+ order:
77
+ - formula.status_icon
78
+ - file.name
79
+ - status
80
+ - owner
81
+ - project
82
+ - priority
83
+ - blocked_by
84
+ - formula.age
85
+ - type: cards
86
+ name: Task Board
87
+ groupBy:
88
+ property: status
89
+ direction: ASC
90
+ order:
91
+ - file.name
92
+ - owner
93
+ - project
94
+ - priority`,
95
+ "blocked.base": `filters:
96
+ and:
97
+ - file.inFolder("tasks")
98
+ - status == "blocked"
99
+ formulas:
100
+ days_blocked: (now() - file.ctime).days
101
+ views:
102
+ - type: table
103
+ name: Blocked Tasks
104
+ order:
105
+ - file.name
106
+ - owner
107
+ - project
108
+ - blocked_by
109
+ - formula.days_blocked
110
+ - priority`,
111
+ "by-project.base": `filters:
112
+ and:
113
+ - file.inFolder("tasks")
114
+ - status != "done"
115
+ formulas:
116
+ status_icon: if(status == "blocked", "\u{1F534}", if(status == "in-progress", "\u{1F528}", "\u26AA"))
117
+ views:
118
+ - type: table
119
+ name: By Project
120
+ groupBy:
121
+ property: project
122
+ direction: ASC
123
+ order:
124
+ - formula.status_icon
125
+ - file.name
126
+ - status
127
+ - owner
128
+ - priority
129
+ - type: cards
130
+ name: Project Cards
131
+ groupBy:
132
+ property: project
133
+ direction: ASC
134
+ order:
135
+ - file.name
136
+ - owner
137
+ - status`,
138
+ "by-owner.base": `filters:
139
+ and:
140
+ - file.inFolder("tasks")
141
+ - status != "done"
142
+ views:
143
+ - type: table
144
+ name: By Owner
145
+ groupBy:
146
+ property: owner
147
+ direction: ASC
148
+ order:
149
+ - file.name
150
+ - status
151
+ - project
152
+ - priority`,
153
+ "backlog.base": `filters:
154
+ and:
155
+ - file.inFolder("backlog")
156
+ views:
157
+ - type: table
158
+ name: Backlog
159
+ order:
160
+ - file.name
161
+ - source
162
+ - project
163
+ - file.ctime`
164
+ };
165
+ let written = 0;
166
+ for (const [filename, content] of Object.entries(basesFiles)) {
167
+ const filePath = path.join(vaultPath, filename);
168
+ if (force || !fs.existsSync(filePath)) {
169
+ fs.writeFileSync(filePath, content);
170
+ written++;
171
+ }
172
+ }
173
+ return written;
174
+ }
175
+ var NEURAL_GRAPH_CSS = `/* ClawVault Graph Colors \u2014 Neural Neural Style */
176
+ /* Auto-generated by \`clawvault setup --theme neural\` */
177
+
178
+ body.theme-dark .graph-view .graph-view-container { background-color: #0a0a0a; }
179
+
180
+ body.theme-dark .graph-view .node.tag-person circle { fill: #00b4d8 !important; }
181
+ body.theme-dark .graph-view .node.tag-project circle { fill: #2d6a4f !important; }
182
+ body.theme-dark .graph-view .node.tag-decision circle { fill: #e8590c !important; }
183
+ body.theme-dark .graph-view .node.tag-lesson circle { fill: #fcc419 !important; }
184
+ body.theme-dark .graph-view .node.tag-commitment circle { fill: #e03131 !important; }
185
+ body.theme-dark .graph-view .node.tag-task circle { fill: #22b8cf !important; }
186
+ body.theme-dark .graph-view .node.tag-observation circle { fill: #7950f2 !important; }
187
+ body.theme-dark .graph-view .node.tag-handoff circle { fill: #845ef7 !important; }
188
+ body.theme-dark .graph-view .node.tag-daily circle { fill: #495057 !important; }
189
+
190
+ body.theme-dark .graph-view .node.is-focused circle {
191
+ fill: #e8a430 !important; stroke: #e8a430 !important;
192
+ stroke-width: 3px; filter: drop-shadow(0 0 6px #e8a430);
193
+ }
194
+
195
+ body.theme-dark .graph-view .link { stroke: rgba(45, 200, 120, 0.15) !important; }
196
+ body.theme-dark .graph-view .link.is-focused { stroke: rgba(45, 200, 120, 0.6) !important; }
197
+ body.theme-dark .graph-view .node text { fill: #c1c2c5 !important; font-size: 0.8em; }
198
+ `;
199
+ var MINIMAL_GRAPH_CSS = `/* ClawVault Graph Colors \u2014 Minimal */
200
+ /* Auto-generated by \`clawvault setup --theme minimal\` */
201
+
202
+ body.theme-dark .graph-view .node.tag-person circle { fill: #4a90e8 !important; }
203
+ body.theme-dark .graph-view .node.tag-project circle { fill: #4ae85d !important; }
204
+ body.theme-dark .graph-view .node.tag-decision circle { fill: #e85d4a !important; }
205
+ body.theme-dark .graph-view .node.tag-lesson circle { fill: #9b59b6 !important; }
206
+ body.theme-dark .graph-view .node.tag-task circle { fill: #e8a430 !important; }
207
+ `;
208
+ var NEURAL_COLOR_GROUPS = [
209
+ { query: "path:people", color: { a: 1, rgb: 47316 } },
210
+ { query: "path:projects", color: { a: 1, rgb: 2976335 } },
211
+ { query: "path:decisions", color: { a: 1, rgb: 15227916 } },
212
+ { query: "path:lessons", color: { a: 1, rgb: 16565273 } },
213
+ { query: "path:tasks", color: { a: 1, rgb: 2275535 } },
214
+ { query: "path:commitments", color: { a: 1, rgb: 14680369 } },
215
+ { query: "path:backlog", color: { a: 1, rgb: 9806262 } },
216
+ { query: "path:inbox", color: { a: 1, rgb: 15964178 } },
217
+ { query: "path:handoffs", color: { a: 1, rgb: 8675063 } },
218
+ { query: "path:ledger", color: { a: 1, rgb: 7950066 } }
219
+ ];
220
+ var MINIMAL_COLOR_GROUPS = [
221
+ { query: "path:people", color: { a: 1, rgb: 4886760 } },
222
+ { query: "path:projects", color: { a: 1, rgb: 4909149 } },
223
+ { query: "path:decisions", color: { a: 1, rgb: 15228234 } },
224
+ { query: "path:lessons", color: { a: 1, rgb: 10181046 } },
225
+ { query: "path:tasks", color: { a: 1, rgb: 15246384 } }
226
+ ];
227
+ function writeGraphColors(vaultPath, theme, force) {
228
+ const obsidianDir = path.join(vaultPath, ".obsidian");
229
+ if (!fs.existsSync(obsidianDir)) {
230
+ return false;
231
+ }
232
+ const snippetsDir = path.join(obsidianDir, "snippets");
233
+ fs.mkdirSync(snippetsDir, { recursive: true });
234
+ const snippetName = "clawvault-graph";
235
+ const snippetPath = path.join(snippetsDir, `${snippetName}.css`);
236
+ if (!force && fs.existsSync(snippetPath)) {
237
+ return false;
238
+ }
239
+ const css = theme === "neural" ? NEURAL_GRAPH_CSS : MINIMAL_GRAPH_CSS;
240
+ fs.writeFileSync(snippetPath, css);
241
+ const appearancePath = path.join(obsidianDir, "appearance.json");
242
+ let appearance = {};
243
+ if (fs.existsSync(appearancePath)) {
244
+ try {
245
+ appearance = JSON.parse(fs.readFileSync(appearancePath, "utf-8"));
246
+ } catch {
247
+ }
248
+ }
249
+ const snippets = appearance.enabledCssSnippets || [];
250
+ if (!snippets.includes(snippetName)) {
251
+ snippets.push(snippetName);
252
+ appearance.enabledCssSnippets = snippets;
253
+ fs.writeFileSync(appearancePath, JSON.stringify(appearance, null, 2));
254
+ }
255
+ const graphPath = path.join(obsidianDir, "graph.json");
256
+ let graphConfig = {};
257
+ if (fs.existsSync(graphPath)) {
258
+ try {
259
+ graphConfig = JSON.parse(fs.readFileSync(graphPath, "utf-8"));
260
+ } catch {
261
+ }
262
+ }
263
+ graphConfig.colorGroups = theme === "neural" ? NEURAL_COLOR_GROUPS : MINIMAL_COLOR_GROUPS;
264
+ if (theme === "neural") {
265
+ graphConfig.showTags = false;
266
+ graphConfig.showAttachments = false;
267
+ graphConfig.nodeSizeMultiplier = 1.2;
268
+ graphConfig.lineSizeMultiplier = 0.8;
269
+ graphConfig.textFadeMultiplier = 0;
270
+ graphConfig.repelStrength = 10;
271
+ graphConfig.linkDistance = 250;
272
+ graphConfig.centerStrength = 0.5;
273
+ }
274
+ fs.writeFileSync(graphPath, JSON.stringify(graphConfig, null, 2));
275
+ return true;
276
+ }
277
+ function getQmdConfig(vaultPath) {
278
+ const configPath = path.join(vaultPath, CONFIG_FILE);
279
+ if (fs.existsSync(configPath)) {
280
+ try {
281
+ const meta = JSON.parse(fs.readFileSync(configPath, "utf-8"));
282
+ return {
283
+ collection: meta.qmdCollection || meta.name || path.basename(vaultPath),
284
+ root: meta.qmdRoot || vaultPath
285
+ };
286
+ } catch {
287
+ return { collection: path.basename(vaultPath), root: vaultPath };
288
+ }
289
+ }
290
+ return { collection: path.basename(vaultPath), root: vaultPath };
291
+ }
292
+ async function setupCommand(options = {}) {
293
+ const target = resolveVaultTarget(options.vault);
294
+ if (target.existed && !fs.statSync(target.vaultPath).isDirectory()) {
295
+ throw new Error(`Vault path is not a directory: ${target.vaultPath}`);
296
+ }
297
+ if (!target.existed) fs.mkdirSync(target.vaultPath, { recursive: true });
298
+ console.log(`${target.existed ? "Found" : "Created"} vault path (${target.source}): ${target.vaultPath}`);
299
+ const initialized = ensureVaultStructure(target.vaultPath);
300
+ console.log(initialized ? "\u2713 Initialized vault structure." : "\u2713 Vault structure already present.");
301
+ const force = options.force ?? false;
302
+ const theme = options.theme ?? "neural";
303
+ const explicitFlags = options.graphColors !== void 0 || options.bases !== void 0 || options.canvas !== void 0;
304
+ const doGraphColors = explicitFlags ? options.graphColors !== false : true;
305
+ const doBases = explicitFlags ? options.bases !== false : true;
306
+ const doCanvas = explicitFlags ? options.canvas !== void 0 && options.canvas !== false : false;
307
+ if (doGraphColors && theme !== "none") {
308
+ const wrote = writeGraphColors(target.vaultPath, theme, force);
309
+ if (wrote) {
310
+ console.log(`\u2713 Graph colors configured (${theme} theme)`);
311
+ } else {
312
+ const obsidianDir = path.join(target.vaultPath, ".obsidian");
313
+ if (!fs.existsSync(obsidianDir)) {
314
+ console.log("\u2298 No .obsidian directory \u2014 skipping graph colors (not an Obsidian vault)");
315
+ } else {
316
+ console.log("\u2298 Graph colors already exist (use --force to overwrite)");
317
+ }
318
+ }
319
+ } else if (doGraphColors && theme === "none") {
320
+ console.log("\u2298 Graph colors skipped (--theme none)");
321
+ }
322
+ if (doBases) {
323
+ const count = writeBases(target.vaultPath, force);
324
+ if (count > 0) {
325
+ console.log(`\u2713 Created ${count} Obsidian Bases view${count > 1 ? "s" : ""}`);
326
+ } else {
327
+ console.log("\u2298 Bases views already exist (use --force to overwrite)");
328
+ }
329
+ }
330
+ if (doCanvas) {
331
+ try {
332
+ const { canvasCommand } = await import("./commands/canvas.js");
333
+ await canvasCommand(target.vaultPath);
334
+ } catch (err) {
335
+ console.log(`\u26A0 Canvas generation failed: ${err instanceof Error ? err.message : String(err)}`);
336
+ }
337
+ }
338
+ if (hasQmd()) {
339
+ const { collection, root } = getQmdConfig(target.vaultPath);
340
+ try {
341
+ execFileSync("qmd", withQmdIndexArgs(["collection", "add", root, "--name", collection, "--mask", "**/*.md"], options.qmdIndexName), {
342
+ stdio: "ignore",
343
+ shell: process.platform === "win32"
344
+ });
345
+ console.log(`\u2713 qmd collection ready: ${collection}`);
346
+ } catch {
347
+ console.log("\u2298 qmd collection already exists.");
348
+ }
349
+ } else {
350
+ console.log("\u2298 qmd not found \u2014 skipping semantic search setup.");
351
+ }
352
+ console.log("\nTip: add this to your shell config:");
353
+ console.log(` export CLAWVAULT_PATH="${target.vaultPath}"`);
354
+ console.log("\nCustomize further:");
355
+ console.log(" clawvault setup --theme neural # Neural neural graph colors");
356
+ console.log(" clawvault setup --theme minimal # Subtle category colors");
357
+ console.log(" clawvault setup --canvas # Generate vault status canvas");
358
+ console.log(" clawvault setup --no-bases --no-graph-colors # Structure only");
359
+ console.log(" clawvault setup --force # Overwrite existing configs");
360
+ }
361
+
362
+ export {
363
+ setupCommand
364
+ };
@@ -1,3 +1,7 @@
1
+ import {
2
+ loadVaultQmdConfig,
3
+ recoverQmdEmbeddingIfNeeded
4
+ } from "./chunk-6FH3IULF.js";
1
5
  import {
2
6
  QmdUnavailableError,
3
7
  SearchEngine,
@@ -6,14 +10,14 @@ import {
6
10
  hasQmd,
7
11
  qmdEmbed,
8
12
  qmdUpdate
9
- } from "./chunk-K234IDRJ.js";
13
+ } from "./chunk-EK6S23ZB.js";
10
14
  import {
11
15
  DEFAULT_CATEGORIES,
12
16
  TYPE_TO_CATEGORY
13
17
  } from "./chunk-2CDEETQN.js";
14
18
  import {
15
19
  buildOrUpdateMemoryGraphIndex
16
- } from "./chunk-ZZA73MFY.js";
20
+ } from "./chunk-33DOSHTA.js";
17
21
 
18
22
  // src/lib/vault.ts
19
23
  import * as fs from "fs";
@@ -28,8 +32,13 @@ var ClawVault = class {
28
32
  search;
29
33
  initialized = false;
30
34
  constructor(vaultPath) {
35
+ if (typeof vaultPath !== "string" || !vaultPath.trim()) {
36
+ throw new Error(`Invalid vault path: expected a non-empty string, received ${typeof vaultPath}`);
37
+ }
31
38
  if (!hasQmd()) {
32
- throw new QmdUnavailableError();
39
+ const error = new QmdUnavailableError("NOT_INSTALLED");
40
+ console.error(error.toUserMessage());
41
+ throw error;
33
42
  }
34
43
  this.config = {
35
44
  path: path.resolve(vaultPath),
@@ -46,7 +55,9 @@ var ClawVault = class {
46
55
  */
47
56
  async init(options = {}, initFlags) {
48
57
  if (!hasQmd()) {
49
- throw new QmdUnavailableError();
58
+ const error = new QmdUnavailableError("NOT_INSTALLED");
59
+ console.error(error.toUserMessage());
60
+ throw error;
50
61
  }
51
62
  const vaultPath = this.config.path;
52
63
  const flags = initFlags || {};
@@ -200,7 +211,9 @@ var ClawVault = class {
200
211
  */
201
212
  async load() {
202
213
  if (!hasQmd()) {
203
- throw new QmdUnavailableError();
214
+ const error = new QmdUnavailableError("NOT_INSTALLED");
215
+ console.error(error.toUserMessage());
216
+ throw error;
204
217
  }
205
218
  const vaultPath = this.config.path;
206
219
  const configPath = path.join(vaultPath, CONFIG_FILE);
@@ -208,16 +221,32 @@ var ClawVault = class {
208
221
  throw new Error(`Not a ClawVault: ${vaultPath} (missing ${CONFIG_FILE})`);
209
222
  }
210
223
  const meta = JSON.parse(fs.readFileSync(configPath, "utf-8"));
211
- this.config.name = meta.name;
212
- this.config.categories = meta.categories;
213
- this.config.qmdCollection = meta.qmdCollection;
214
- this.config.qmdRoot = meta.qmdRoot;
224
+ this.config.name = typeof meta.name === "string" ? meta.name : this.config.name;
225
+ this.config.categories = Array.isArray(meta.categories) ? meta.categories : this.config.categories;
226
+ this.config.qmdCollection = typeof meta.qmdCollection === "string" ? meta.qmdCollection : void 0;
227
+ this.config.qmdRoot = typeof meta.qmdRoot === "string" ? meta.qmdRoot : void 0;
215
228
  if (!meta.qmdCollection || !meta.qmdRoot) {
216
229
  meta.qmdCollection = meta.qmdCollection || meta.name;
217
230
  meta.qmdRoot = meta.qmdRoot || this.config.path;
218
231
  fs.writeFileSync(configPath, JSON.stringify(meta, null, 2));
219
232
  }
220
233
  this.applyQmdConfig(meta);
234
+ try {
235
+ const recovery = recoverQmdEmbeddingIfNeeded({
236
+ vaultPath: this.config.path,
237
+ collection: this.getQmdCollection(),
238
+ rootPath: this.getQmdRoot(),
239
+ mode: "marker-only",
240
+ onLog: (message) => console.warn(`[clawvault] ${message}`)
241
+ });
242
+ if (recovery.recovered) {
243
+ console.warn(`[clawvault] qmd embedding recovery finished for "${this.getQmdCollection()}".`);
244
+ }
245
+ } catch (err) {
246
+ console.warn(
247
+ `[clawvault] qmd embedding recovery failed: ${err?.message || "unknown error"}`
248
+ );
249
+ }
221
250
  await this.reindex();
222
251
  this.initialized = true;
223
252
  }
@@ -624,14 +653,15 @@ var ClawVault = class {
624
653
  md += `## Recent Sessions
625
654
  `;
626
655
  for (const h of recap.recentHandoffs) {
656
+ const datePart = this.extractDatePart(h.created);
627
657
  if (brief) {
628
- md += `- **${h.created.split("T")[0]}:** ${h.workingOn.slice(0, 2).join(", ")}`;
658
+ md += `- **${datePart}:** ${h.workingOn.slice(0, 2).join(", ")}`;
629
659
  if (h.nextSteps.length > 0) md += ` \u2192 ${h.nextSteps[0]}`;
630
660
  md += `
631
661
  `;
632
662
  } else {
633
663
  md += `
634
- ### ${h.created.split("T")[0]}
664
+ ### ${datePart}
635
665
  `;
636
666
  md += `**Working on:** ${h.workingOn.join(", ")}
637
667
  `;
@@ -689,7 +719,7 @@ var ClawVault = class {
689
719
  */
690
720
  parseHandoff(doc) {
691
721
  return {
692
- created: doc.frontmatter.date || doc.modified.toISOString(),
722
+ created: this.toDateString(doc.frontmatter.date, doc.modified.toISOString()),
693
723
  sessionKey: doc.frontmatter.sessionKey,
694
724
  workingOn: doc.frontmatter.workingOn || [],
695
725
  blocked: doc.frontmatter.blocked || [],
@@ -700,9 +730,39 @@ var ClawVault = class {
700
730
  };
701
731
  }
702
732
  // === Private helpers ===
733
+ /**
734
+ * Safely convert a date value to ISO string format.
735
+ * Handles Date objects, strings, and undefined values.
736
+ */
737
+ toDateString(value, fallback) {
738
+ if (value instanceof Date) {
739
+ return value.toISOString();
740
+ }
741
+ if (typeof value === "string" && value.length > 0) {
742
+ return value;
743
+ }
744
+ return fallback || (/* @__PURE__ */ new Date()).toISOString();
745
+ }
746
+ /**
747
+ * Extract the date portion (YYYY-MM-DD) from an ISO date string or Date object.
748
+ * Provides safe handling for various date formats.
749
+ */
750
+ extractDatePart(value) {
751
+ const dateStr = this.toDateString(value);
752
+ if (dateStr.includes("T")) {
753
+ return dateStr.split("T")[0];
754
+ }
755
+ return dateStr.slice(0, 10);
756
+ }
703
757
  applyQmdConfig(meta) {
704
- const collection = meta?.qmdCollection || this.config.qmdCollection || this.config.name;
705
- const root = meta?.qmdRoot || this.config.qmdRoot || this.config.path;
758
+ const explicitCollection = meta?.qmdCollection || this.config.qmdCollection;
759
+ const explicitRoot = meta?.qmdRoot || this.config.qmdRoot || this.config.path;
760
+ const qmdConfig = loadVaultQmdConfig(this.config.path);
761
+ const collection = explicitCollection || qmdConfig.qmdCollection || this.config.name;
762
+ const root = (typeof explicitRoot === "string" ? explicitRoot : void 0) || qmdConfig.qmdRoot || this.config.path;
763
+ if (qmdConfig.autoDetected) {
764
+ console.warn(`[clawvault] Auto-detected qmd collection: ${collection}`);
765
+ }
706
766
  this.config.qmdCollection = collection;
707
767
  this.config.qmdRoot = root;
708
768
  this.search.setVaultPath(this.config.path);