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
@@ -9,13 +9,15 @@ export function registerQueryCommands(
9
9
  getVault,
10
10
  resolveVaultPath,
11
11
  QmdUnavailableError,
12
- printQmdMissing
12
+ QmdConfigurationError,
13
+ printQmdMissing,
14
+ printQmdConfigError
13
15
  }
14
16
  ) {
15
17
  // === SEARCH ===
16
18
  program
17
19
  .command('search <query>')
18
- .description('Search the vault via qmd (BM25)')
20
+ .description('Search the vault via qmd (BM25), optionally with semantic hybrid search')
19
21
  .option('-n, --limit <n>', 'Max results (default: 10)', '10')
20
22
  .option('-c, --category <category>', 'Filter by category')
21
23
  .option('--tags <tags>', 'Filter by tags (comma-separated)')
@@ -23,20 +25,57 @@ export function registerQueryCommands(
23
25
  .option('--full', 'Include full content in results')
24
26
  .option('-v, --vault <path>', 'Vault path')
25
27
  .option('--json', 'Output as JSON')
28
+ .option('--semantic', 'Enable hybrid search (BM25 + semantic with RRF)')
29
+ .option('--rebuild-embeddings', 'Rebuild the embedding cache before searching')
26
30
  .action(async (query, options) => {
27
31
  try {
32
+ const vaultPath = resolveVaultPath(options.vault);
28
33
  const vault = await getVault(options.vault);
29
34
 
30
- const results = await vault.find(query, {
31
- limit: parseInt(options.limit, 10),
35
+ // Handle --rebuild-embeddings flag
36
+ if (options.rebuildEmbeddings) {
37
+ const { rebuildEmbeddingsForVault } = await import('../dist/commands/rebuild-embeddings.js');
38
+ console.log(chalk.cyan('Rebuilding embedding cache...'));
39
+ const stats = await rebuildEmbeddingsForVault(vaultPath, {
40
+ onProgress: (current, total) => {
41
+ process.stdout.write(`\r Embedding ${current}/${total} documents...`);
42
+ }
43
+ });
44
+ console.log(chalk.green(`\n Done. ${stats.total} embeddings (${stats.added} new, ${stats.skipped} cached)`));
45
+ console.log();
46
+ }
47
+
48
+ // Get BM25 results
49
+ const bm25Results = await vault.find(query, {
50
+ limit: options.semantic ? 50 : parseInt(options.limit, 10),
32
51
  category: options.category,
33
52
  tags: options.tags?.split(',').map((value) => value.trim()),
34
53
  fullContent: options.full,
35
54
  temporalBoost: options.recent
36
55
  });
37
56
 
57
+ let results = bm25Results;
58
+ let searchMode = 'BM25';
59
+
60
+ // Apply hybrid search if --semantic flag is set
61
+ if (options.semantic) {
62
+ const { EmbeddingCache, hybridSearch } = await import('../dist/lib/hybrid-search.js');
63
+ const cache = new EmbeddingCache(vaultPath);
64
+ cache.load();
65
+
66
+ if (cache.size === 0) {
67
+ console.log(chalk.yellow('Warning: No embeddings found. Run with --rebuild-embeddings to build the cache.'));
68
+ } else {
69
+ results = await hybridSearch(query, bm25Results, cache, {
70
+ topK: parseInt(options.limit, 10),
71
+ rrfK: 60
72
+ });
73
+ searchMode = 'Hybrid (BM25 + Semantic)';
74
+ }
75
+ }
76
+
38
77
  if (options.json) {
39
- console.log(JSON.stringify(results, null, 2));
78
+ console.log(JSON.stringify({ searchMode, results }, null, 2));
40
79
  return;
41
80
  }
42
81
 
@@ -45,7 +84,8 @@ export function registerQueryCommands(
45
84
  return;
46
85
  }
47
86
 
48
- console.log(chalk.cyan(`\n🔍 Found ${results.length} result(s) for "${query}":\n`));
87
+ const icon = options.semantic ? '🔍🧠' : '🔍';
88
+ console.log(chalk.cyan(`\n${icon} Found ${results.length} result(s) for "${query}" [${searchMode}]:\n`));
49
89
 
50
90
  for (const result of results) {
51
91
  const scoreBar = '█'.repeat(Math.round(result.score * 10)).padEnd(10, '░');
@@ -62,6 +102,10 @@ export function registerQueryCommands(
62
102
  printQmdMissing();
63
103
  process.exit(1);
64
104
  }
105
+ if (err instanceof QmdConfigurationError) {
106
+ printQmdConfigError(err);
107
+ process.exit(1);
108
+ }
65
109
  console.error(chalk.red(`Error: ${err.message}`));
66
110
  process.exit(1);
67
111
  }
@@ -117,6 +161,10 @@ export function registerQueryCommands(
117
161
  printQmdMissing();
118
162
  process.exit(1);
119
163
  }
164
+ if (err instanceof QmdConfigurationError) {
165
+ printQmdConfigError(err);
166
+ process.exit(1);
167
+ }
120
168
  console.error(chalk.red(`Error: ${err.message}`));
121
169
  process.exit(1);
122
170
  }
@@ -163,6 +211,10 @@ export function registerQueryCommands(
163
211
  printQmdMissing();
164
212
  process.exit(1);
165
213
  }
214
+ if (err instanceof QmdConfigurationError) {
215
+ printQmdConfigError(err);
216
+ process.exit(1);
217
+ }
166
218
  console.error(chalk.red(`Error: ${err.message}`));
167
219
  process.exit(1);
168
220
  }
@@ -292,29 +344,6 @@ export function registerQueryCommands(
292
344
  }
293
345
  });
294
346
 
295
- // === REWEAVE ===
296
- program
297
- .command('reweave')
298
- .description('Backward memory consolidation — detect and mark superseded observations')
299
- .option('--since <date>', 'Only check observations since this date (YYYY-MM-DD)')
300
- .option('--dry-run', 'Show what would be superseded without writing')
301
- .option('--threshold <n>', 'Entity similarity threshold (0-1, default 0.3)', '0.3')
302
- .option('-v, --vault <path>', 'Vault path')
303
- .action(async (options) => {
304
- try {
305
- const { reweaveCommand } = await import('../dist/commands/reweave.js');
306
- await reweaveCommand({
307
- vaultPath: resolveVaultPath(options.vault),
308
- since: options.since,
309
- dryRun: options.dryRun,
310
- threshold: parseFloat(options.threshold),
311
- });
312
- } catch (err) {
313
- console.error(chalk.red(`Error: ${err.message}`));
314
- process.exit(1);
315
- }
316
- });
317
-
318
347
  // === SESSION-RECAP ===
319
348
  program
320
349
  .command('session-recap <sessionKey>')
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Task tracking command registrations for ClawVault
3
- * Registers task, backlog, and blocked commands
3
+ * Registers task, backlog, blocked, and canvas commands
4
4
  */
5
5
 
6
6
  function parseCsvList(value) {
@@ -328,4 +328,21 @@ export function registerTaskCommands(
328
328
  });
329
329
 
330
330
  // === CANVAS ===
331
+ program
332
+ .command('canvas')
333
+ .description('Generate an Obsidian canvas dashboard file')
334
+ .option('-v, --vault <path>', 'Vault path (default: find nearest)')
335
+ .option('--output <path>', 'Output file path (default: dashboard.canvas)')
336
+ .action(async (options) => {
337
+ try {
338
+ const vaultPath = resolveVaultPath(options.vault);
339
+ const { canvasCommand } = await import('../dist/commands/canvas.js');
340
+ await canvasCommand(vaultPath, {
341
+ output: options.output
342
+ });
343
+ } catch (err) {
344
+ console.error(chalk.red(`Error: ${err.message}`));
345
+ process.exit(1);
346
+ }
347
+ });
331
348
  }
@@ -50,4 +50,20 @@ describe('register-task-commands', () => {
50
50
  ]));
51
51
  });
52
52
 
53
+ it('adds simplified canvas flags', () => {
54
+ const program = new Command();
55
+ registerTaskCommands(program, {
56
+ chalk: chalkStub,
57
+ resolveVaultPath: stubResolveVaultPath
58
+ });
59
+
60
+ const canvasCommand = program.commands.find((command) => command.name() === 'canvas');
61
+ expect(canvasCommand).toBeDefined();
62
+
63
+ const optionFlags = canvasCommand?.options.map((option) => option.flags) ?? [];
64
+ expect(optionFlags).toEqual(expect.arrayContaining([
65
+ '-v, --vault <path>',
66
+ '--output <path>'
67
+ ]));
68
+ });
53
69
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Vault operation command registrations (browse/sync/reindex/remember/shell-init).
2
+ * Vault operation command registrations (browse/sync/reindex/remember/shell-init/dashboard).
3
3
  */
4
4
 
5
5
  import { validatePathWithinBase } from './command-runtime.js';
@@ -269,4 +269,32 @@ export function registerVaultOperationsCommands(
269
269
  }
270
270
  });
271
271
 
272
+ // === DASHBOARD ===
273
+ program
274
+ .command('dashboard')
275
+ .description('Run the local vault graph dashboard server')
276
+ .option('-p, --port <port>', 'Dashboard port (default: 3377)', '3377')
277
+ .option('-v, --vault <path>', 'Vault path')
278
+ .action(async (options) => {
279
+ try {
280
+ const parsedPort = Number.parseInt(options.port, 10);
281
+ if (Number.isNaN(parsedPort)) {
282
+ console.error(chalk.red(`Error: Invalid port: ${options.port}`));
283
+ process.exit(1);
284
+ }
285
+
286
+ const vaultPath = options.vault
287
+ ? path.resolve(options.vault)
288
+ : resolveVaultPath(undefined);
289
+
290
+ const { startDashboard } = await import('../dashboard/server.js');
291
+ await startDashboard({
292
+ port: parsedPort,
293
+ vaultPath
294
+ });
295
+ } catch (err) {
296
+ console.error(chalk.red(`Error: ${err.message}`));
297
+ process.exit(1);
298
+ }
299
+ });
272
300
  }