clawvault 2.6.0 → 3.0.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 (232) hide show
  1. package/bin/command-registration.test.js +1 -3
  2. package/bin/register-core-commands.js +10 -23
  3. package/bin/register-maintenance-commands.js +3 -20
  4. package/bin/register-query-commands.js +23 -0
  5. package/bin/register-task-commands.js +1 -18
  6. package/bin/register-task-commands.test.js +0 -16
  7. package/bin/register-vault-operations-commands.js +1 -29
  8. package/dist/{chunk-QVMXF7FY.js → chunk-3D6BCTP6.js} +39 -1
  9. package/dist/{chunk-R2MIW5G7.js → chunk-3DHXQHYG.js} +1 -1
  10. package/dist/{chunk-Q2J5YTUF.js → chunk-3NSBOUT3.js} +73 -36
  11. package/dist/chunk-3RG5ZIWI.js +10 -0
  12. package/dist/{chunk-AZYOKJYC.js → chunk-62YTUT6J.js} +2 -2
  13. package/dist/chunk-6U6MK36V.js +205 -0
  14. package/dist/{chunk-4QYGFWRM.js → chunk-7R7O6STJ.js} +4 -4
  15. package/dist/{chunk-VXEOHTSL.js → chunk-C7OK5WKP.js} +4 -4
  16. package/dist/chunk-CMB7UL7C.js +327 -0
  17. package/dist/chunk-DEFFDRVP.js +938 -0
  18. package/dist/{chunk-K3CDT7IH.js → chunk-E7MFQB6D.js} +61 -20
  19. package/dist/{chunk-ME37YNW3.js → chunk-F2JEUD4J.js} +6 -4
  20. package/dist/chunk-GAJV4IGR.js +82 -0
  21. package/dist/chunk-GQSLDZTS.js +560 -0
  22. package/dist/{chunk-4OXMU5S2.js → chunk-GUKMRGM7.js} +1 -1
  23. package/dist/{chunk-YOSEUUNB.js → chunk-H34S76MB.js} +6 -6
  24. package/dist/{chunk-4TE4JMLA.js → chunk-JY6FYXIT.js} +10 -5
  25. package/dist/chunk-K234IDRJ.js +1073 -0
  26. package/dist/{chunk-IEVLHNLU.js → chunk-LNJA2UGL.js} +86 -9
  27. package/dist/{chunk-MFAWT5O5.js → chunk-LYHGEHXG.js} +1 -0
  28. package/dist/chunk-MFM6K7PU.js +374 -0
  29. package/dist/{chunk-QWQ3TIKS.js → chunk-N2AXRYLC.js} +1 -1
  30. package/dist/chunk-PAH27GSN.js +108 -0
  31. package/dist/{chunk-OIWVQYQF.js → chunk-QBLMXKF2.js} +1 -1
  32. package/dist/{chunk-FHFUXL6G.js → chunk-QK3UCXWL.js} +2 -2
  33. package/dist/{chunk-2YDBJS7M.js → chunk-SJSFRIYS.js} +1 -1
  34. package/dist/{chunk-GSD4ALSI.js → chunk-U55BGUAU.js} +2 -2
  35. package/dist/{chunk-PBEE567J.js → chunk-VGLOTGAS.js} +1 -1
  36. package/dist/{chunk-F55HGNU4.js → chunk-WAZ3NLWL.js} +47 -0
  37. package/dist/{chunk-KL4NAOMO.js → chunk-WGRQ6HDV.js} +1 -1
  38. package/dist/{chunk-UEOUADMO.js → chunk-YKTA5JOJ.js} +13 -10
  39. package/dist/{chunk-XAVB4GB4.js → chunk-ZVVFWOLW.js} +4 -4
  40. package/dist/cli/index.cjs +10033 -0
  41. package/dist/cli/index.d.cts +5 -0
  42. package/dist/cli/index.js +20 -18
  43. package/dist/commands/archive.cjs +287 -0
  44. package/dist/commands/archive.d.cts +11 -0
  45. package/dist/commands/archive.js +1 -0
  46. package/dist/commands/backlog.cjs +721 -0
  47. package/dist/commands/backlog.d.cts +53 -0
  48. package/dist/commands/backlog.js +3 -2
  49. package/dist/commands/blocked.cjs +204 -0
  50. package/dist/commands/blocked.d.cts +26 -0
  51. package/dist/commands/blocked.js +3 -2
  52. package/dist/commands/checkpoint.cjs +244 -0
  53. package/dist/commands/checkpoint.d.cts +41 -0
  54. package/dist/commands/checkpoint.js +2 -1
  55. package/dist/commands/compat.cjs +369 -0
  56. package/dist/commands/compat.d.cts +28 -0
  57. package/dist/commands/compat.js +2 -1
  58. package/dist/commands/context.cjs +2989 -0
  59. package/dist/commands/context.d.cts +2 -0
  60. package/dist/commands/context.js +5 -4
  61. package/dist/commands/doctor.cjs +3062 -0
  62. package/dist/commands/doctor.d.cts +21 -0
  63. package/dist/commands/doctor.d.ts +6 -1
  64. package/dist/commands/doctor.js +13 -11
  65. package/dist/commands/embed.cjs +232 -0
  66. package/dist/commands/embed.d.cts +17 -0
  67. package/dist/commands/embed.js +5 -2
  68. package/dist/commands/entities.cjs +141 -0
  69. package/dist/commands/entities.d.cts +7 -0
  70. package/dist/commands/entities.js +1 -0
  71. package/dist/commands/graph.cjs +501 -0
  72. package/dist/commands/graph.d.cts +21 -0
  73. package/dist/commands/graph.js +1 -0
  74. package/dist/commands/inject.cjs +1636 -0
  75. package/dist/commands/inject.d.cts +2 -0
  76. package/dist/commands/inject.d.ts +1 -1
  77. package/dist/commands/inject.js +4 -2
  78. package/dist/commands/kanban.cjs +884 -0
  79. package/dist/commands/kanban.d.cts +63 -0
  80. package/dist/commands/kanban.js +4 -3
  81. package/dist/commands/link.cjs +965 -0
  82. package/dist/commands/link.d.cts +11 -0
  83. package/dist/commands/link.js +1 -0
  84. package/dist/commands/migrate-observations.cjs +362 -0
  85. package/dist/commands/migrate-observations.d.cts +19 -0
  86. package/dist/commands/migrate-observations.js +3 -2
  87. package/dist/commands/observe.cjs +4099 -0
  88. package/dist/commands/observe.d.cts +23 -0
  89. package/dist/commands/observe.d.ts +1 -0
  90. package/dist/commands/observe.js +11 -9
  91. package/dist/commands/project.cjs +1341 -0
  92. package/dist/commands/project.d.cts +85 -0
  93. package/dist/commands/project.js +5 -4
  94. package/dist/commands/rebuild.cjs +3136 -0
  95. package/dist/commands/rebuild.d.cts +11 -0
  96. package/dist/commands/rebuild.js +10 -8
  97. package/dist/commands/recover.cjs +361 -0
  98. package/dist/commands/recover.d.cts +38 -0
  99. package/dist/commands/recover.js +3 -2
  100. package/dist/commands/reflect.cjs +1008 -0
  101. package/dist/commands/reflect.d.cts +11 -0
  102. package/dist/commands/reflect.js +6 -4
  103. package/dist/commands/repair-session.cjs +457 -0
  104. package/dist/commands/repair-session.d.cts +38 -0
  105. package/dist/commands/repair-session.js +1 -0
  106. package/dist/commands/replay.cjs +4103 -0
  107. package/dist/commands/replay.d.cts +16 -0
  108. package/dist/commands/replay.js +12 -10
  109. package/dist/commands/session-recap.cjs +353 -0
  110. package/dist/commands/session-recap.d.cts +27 -0
  111. package/dist/commands/session-recap.js +1 -0
  112. package/dist/commands/setup.cjs +1345 -0
  113. package/dist/commands/setup.d.cts +100 -0
  114. package/dist/commands/setup.d.ts +90 -2
  115. package/dist/commands/setup.js +21 -2
  116. package/dist/commands/shell-init.cjs +75 -0
  117. package/dist/commands/shell-init.d.cts +7 -0
  118. package/dist/commands/shell-init.js +2 -0
  119. package/dist/commands/sleep.cjs +6028 -0
  120. package/dist/commands/sleep.d.cts +36 -0
  121. package/dist/commands/sleep.d.ts +1 -1
  122. package/dist/commands/sleep.js +17 -15
  123. package/dist/commands/status.cjs +2736 -0
  124. package/dist/commands/status.d.cts +52 -0
  125. package/dist/commands/status.js +12 -10
  126. package/dist/commands/tailscale.cjs +1532 -0
  127. package/dist/commands/tailscale.d.cts +52 -0
  128. package/dist/commands/tailscale.js +1 -0
  129. package/dist/commands/task.cjs +1236 -0
  130. package/dist/commands/task.d.cts +97 -0
  131. package/dist/commands/task.js +4 -3
  132. package/dist/commands/template.cjs +457 -0
  133. package/dist/commands/template.d.cts +36 -0
  134. package/dist/commands/template.js +2 -1
  135. package/dist/commands/wake.cjs +2626 -0
  136. package/dist/commands/wake.d.cts +22 -0
  137. package/dist/commands/wake.d.ts +1 -1
  138. package/dist/commands/wake.js +12 -11
  139. package/dist/context-BUGaWpyL.d.cts +46 -0
  140. package/dist/index.cjs +14526 -0
  141. package/dist/index.d.cts +858 -0
  142. package/dist/index.d.ts +192 -7
  143. package/dist/index.js +101 -75
  144. package/dist/{inject-x65KXWPk.d.ts → inject-Bzi5E-By.d.cts} +1 -1
  145. package/dist/inject-Bzi5E-By.d.ts +137 -0
  146. package/dist/lib/auto-linker.cjs +176 -0
  147. package/dist/lib/auto-linker.d.cts +26 -0
  148. package/dist/lib/auto-linker.js +1 -0
  149. package/dist/lib/canvas-layout.cjs +136 -0
  150. package/dist/lib/canvas-layout.d.cts +31 -0
  151. package/dist/lib/canvas-layout.d.ts +16 -100
  152. package/dist/lib/canvas-layout.js +78 -20
  153. package/dist/lib/config.cjs +78 -0
  154. package/dist/lib/config.d.cts +11 -0
  155. package/dist/lib/config.js +1 -0
  156. package/dist/lib/entity-index.cjs +84 -0
  157. package/dist/lib/entity-index.d.cts +26 -0
  158. package/dist/lib/entity-index.js +1 -0
  159. package/dist/lib/project-utils.cjs +864 -0
  160. package/dist/lib/project-utils.d.cts +97 -0
  161. package/dist/lib/project-utils.js +4 -3
  162. package/dist/lib/session-repair.cjs +239 -0
  163. package/dist/lib/session-repair.d.cts +110 -0
  164. package/dist/lib/session-repair.js +1 -0
  165. package/dist/lib/session-utils.cjs +209 -0
  166. package/dist/lib/session-utils.d.cts +63 -0
  167. package/dist/lib/session-utils.js +1 -0
  168. package/dist/lib/tailscale.cjs +1183 -0
  169. package/dist/lib/tailscale.d.cts +225 -0
  170. package/dist/lib/tailscale.js +1 -0
  171. package/dist/lib/task-utils.cjs +1137 -0
  172. package/dist/lib/task-utils.d.cts +208 -0
  173. package/dist/lib/task-utils.js +3 -2
  174. package/dist/lib/template-engine.cjs +47 -0
  175. package/dist/lib/template-engine.d.cts +11 -0
  176. package/dist/lib/template-engine.js +1 -0
  177. package/dist/lib/webdav.cjs +568 -0
  178. package/dist/lib/webdav.d.cts +109 -0
  179. package/dist/lib/webdav.js +1 -0
  180. package/dist/plugin/index.cjs +1907 -0
  181. package/dist/plugin/index.d.cts +36 -0
  182. package/dist/plugin/index.d.ts +36 -0
  183. package/dist/plugin/index.js +572 -0
  184. package/dist/plugin/inject.cjs +356 -0
  185. package/dist/plugin/inject.d.cts +54 -0
  186. package/dist/plugin/inject.d.ts +54 -0
  187. package/dist/plugin/inject.js +17 -0
  188. package/dist/plugin/observe.cjs +631 -0
  189. package/dist/plugin/observe.d.cts +39 -0
  190. package/dist/plugin/observe.d.ts +39 -0
  191. package/dist/plugin/observe.js +18 -0
  192. package/dist/plugin/templates.cjs +593 -0
  193. package/dist/plugin/templates.d.cts +52 -0
  194. package/dist/plugin/templates.d.ts +52 -0
  195. package/dist/plugin/templates.js +25 -0
  196. package/dist/plugin/types.cjs +18 -0
  197. package/dist/plugin/types.d.cts +209 -0
  198. package/dist/plugin/types.d.ts +209 -0
  199. package/dist/plugin/types.js +0 -0
  200. package/dist/plugin/vault.cjs +927 -0
  201. package/dist/plugin/vault.d.cts +68 -0
  202. package/dist/plugin/vault.d.ts +68 -0
  203. package/dist/plugin/vault.js +22 -0
  204. package/dist/{types-C74wgGL1.d.ts → types-Y2_Um2Ls.d.cts} +44 -1
  205. package/dist/types-Y2_Um2Ls.d.ts +205 -0
  206. package/hooks/clawvault/handler.js +70 -7
  207. package/hooks/clawvault/handler.test.js +91 -0
  208. package/openclaw.plugin.json +56 -0
  209. package/package.json +17 -7
  210. package/templates/memory-event.md +67 -0
  211. package/templates/party.md +63 -0
  212. package/templates/primitive-registry.yaml +551 -0
  213. package/templates/run.md +68 -0
  214. package/templates/trigger.md +68 -0
  215. package/templates/workspace.md +50 -0
  216. package/dashboard/lib/graph-diff.js +0 -104
  217. package/dashboard/lib/graph-diff.test.js +0 -75
  218. package/dashboard/lib/vault-parser.js +0 -556
  219. package/dashboard/lib/vault-parser.test.js +0 -254
  220. package/dashboard/public/app.js +0 -796
  221. package/dashboard/public/index.html +0 -52
  222. package/dashboard/public/styles.css +0 -221
  223. package/dashboard/server.js +0 -374
  224. package/dist/chunk-HA5M6KJB.js +0 -33
  225. package/dist/chunk-MAKNAHAW.js +0 -375
  226. package/dist/chunk-MDIH26GC.js +0 -183
  227. package/dist/chunk-MGDEINGP.js +0 -99
  228. package/dist/chunk-RVYA52PY.js +0 -363
  229. package/dist/commands/canvas.d.ts +0 -15
  230. package/dist/commands/canvas.js +0 -199
  231. package/dist/commands/sync-bd.d.ts +0 -10
  232. package/dist/commands/sync-bd.js +0 -9
@@ -1,375 +0,0 @@
1
- // src/lib/search.ts
2
- import { execFileSync, spawnSync } from "child_process";
3
- import * as fs from "fs";
4
- import * as path from "path";
5
- var QMD_INSTALL_URL = "https://github.com/tobi/qmd";
6
- var QMD_INSTALL_COMMAND = "bun install -g github:tobi/qmd";
7
- var QMD_NOT_INSTALLED_MESSAGE = `ClawVault requires qmd. Install: ${QMD_INSTALL_COMMAND}`;
8
- var QMD_INDEX_ENV_VAR = "CLAWVAULT_QMD_INDEX";
9
- var QmdUnavailableError = class extends Error {
10
- constructor(message = QMD_NOT_INSTALLED_MESSAGE) {
11
- super(message);
12
- this.name = "QmdUnavailableError";
13
- }
14
- };
15
- function ensureJsonArgs(args) {
16
- return args.includes("--json") ? args : [...args, "--json"];
17
- }
18
- function resolveQmdIndexName(indexName) {
19
- const explicit = indexName?.trim();
20
- if (explicit) {
21
- return explicit;
22
- }
23
- const fromEnv = process.env[QMD_INDEX_ENV_VAR]?.trim();
24
- return fromEnv || void 0;
25
- }
26
- function withQmdIndexArgs(args, indexName) {
27
- if (args.includes("--index")) {
28
- return [...args];
29
- }
30
- const resolvedIndexName = resolveQmdIndexName(indexName);
31
- if (!resolvedIndexName) {
32
- return [...args];
33
- }
34
- return ["--index", resolvedIndexName, ...args];
35
- }
36
- function tryParseJson(raw) {
37
- try {
38
- return JSON.parse(raw);
39
- } catch {
40
- return null;
41
- }
42
- }
43
- function extractJsonPayload(raw) {
44
- const start = raw.search(/[\[{]/);
45
- if (start === -1) return null;
46
- const end = Math.max(raw.lastIndexOf("]"), raw.lastIndexOf("}"));
47
- if (end <= start) return null;
48
- return raw.slice(start, end + 1);
49
- }
50
- function stripQmdNoise(raw) {
51
- return raw.split("\n").filter((line) => {
52
- const t = line.trim();
53
- if (!t) return true;
54
- if (t.startsWith("[node-llama-cpp]")) return false;
55
- if (t.startsWith("Expanding query")) return false;
56
- if (t.startsWith("Searching ") && t.endsWith("queries...")) return false;
57
- if (/^[├└─│]/.test(t)) return false;
58
- return true;
59
- }).join("\n");
60
- }
61
- function parseQmdOutput(raw) {
62
- const trimmed = stripQmdNoise(raw).trim();
63
- if (!trimmed) return [];
64
- const direct = tryParseJson(trimmed);
65
- const extracted = direct ? null : extractJsonPayload(trimmed);
66
- const parsed = direct ?? (extracted ? tryParseJson(extracted) : null);
67
- if (!parsed) {
68
- throw new Error("qmd returned non-JSON output. Ensure qmd supports --json.");
69
- }
70
- if (Array.isArray(parsed)) {
71
- return parsed;
72
- }
73
- if (parsed && typeof parsed === "object") {
74
- const candidate = parsed.results ?? parsed.items ?? parsed.data;
75
- if (Array.isArray(candidate)) {
76
- return candidate;
77
- }
78
- }
79
- throw new Error("qmd returned an unexpected JSON shape.");
80
- }
81
- function ensureQmdAvailable() {
82
- if (!hasQmd()) {
83
- throw new QmdUnavailableError();
84
- }
85
- }
86
- function execQmd(args, indexName) {
87
- ensureQmdAvailable();
88
- const finalArgs = withQmdIndexArgs(ensureJsonArgs(args), indexName);
89
- try {
90
- const result = execFileSync("qmd", finalArgs, {
91
- encoding: "utf-8",
92
- stdio: ["ignore", "pipe", "pipe"],
93
- maxBuffer: 10 * 1024 * 1024
94
- // 10MB
95
- });
96
- return parseQmdOutput(result);
97
- } catch (err) {
98
- if (err?.code === "ENOENT") {
99
- throw new QmdUnavailableError();
100
- }
101
- const output = [err?.stdout, err?.stderr].filter(Boolean).join("\n");
102
- if (output) {
103
- try {
104
- return parseQmdOutput(output);
105
- } catch {
106
- }
107
- }
108
- const message = err?.message ? `qmd failed: ${err.message}` : "qmd failed";
109
- throw new Error(message);
110
- }
111
- }
112
- function hasQmd() {
113
- const result = spawnSync("qmd", ["--version"], { stdio: "ignore" });
114
- return !result.error;
115
- }
116
- function qmdUpdate(collection, indexName) {
117
- ensureQmdAvailable();
118
- const args = ["update"];
119
- if (collection) {
120
- args.push("-c", collection);
121
- }
122
- execFileSync("qmd", withQmdIndexArgs(args, indexName), { stdio: "inherit" });
123
- }
124
- function qmdEmbed(collection, indexName) {
125
- ensureQmdAvailable();
126
- const args = ["embed"];
127
- if (collection) {
128
- args.push("-c", collection);
129
- }
130
- execFileSync("qmd", withQmdIndexArgs(args, indexName), { stdio: "inherit" });
131
- }
132
- var SearchEngine = class {
133
- documents = /* @__PURE__ */ new Map();
134
- collection = "clawvault";
135
- vaultPath = "";
136
- collectionRoot = "";
137
- qmdIndexName;
138
- /**
139
- * Set the collection name (usually vault name)
140
- */
141
- setCollection(name) {
142
- this.collection = name;
143
- }
144
- /**
145
- * Set the vault path for file resolution
146
- */
147
- setVaultPath(vaultPath) {
148
- this.vaultPath = vaultPath;
149
- }
150
- /**
151
- * Set the collection root for qmd:// URI resolution
152
- */
153
- setCollectionRoot(root) {
154
- this.collectionRoot = path.resolve(root);
155
- }
156
- /**
157
- * Set qmd index name (defaults to qmd global default when omitted)
158
- */
159
- setIndexName(indexName) {
160
- this.qmdIndexName = indexName;
161
- }
162
- /**
163
- * Add or update a document in the local cache
164
- * Note: qmd indexing happens via qmd update command
165
- */
166
- addDocument(doc) {
167
- this.documents.set(doc.id, doc);
168
- }
169
- /**
170
- * Remove a document from the local cache
171
- */
172
- removeDocument(id) {
173
- this.documents.delete(id);
174
- }
175
- /**
176
- * No-op for qmd - indexing is managed externally
177
- */
178
- rebuildIDF() {
179
- }
180
- /**
181
- * BM25 search via qmd
182
- */
183
- search(query, options = {}) {
184
- return this.runQmdQuery("search", query, options);
185
- }
186
- /**
187
- * Vector/semantic search via qmd vsearch
188
- */
189
- vsearch(query, options = {}) {
190
- return this.runQmdQuery("vsearch", query, options);
191
- }
192
- /**
193
- * Combined search with query expansion (qmd query command)
194
- */
195
- query(query, options = {}) {
196
- return this.runQmdQuery("query", query, options);
197
- }
198
- runQmdQuery(command, query, options) {
199
- const {
200
- limit = 10,
201
- minScore = 0,
202
- category,
203
- tags,
204
- fullContent = false,
205
- temporalBoost = false
206
- } = options;
207
- if (!query.trim()) return [];
208
- const args = [
209
- command,
210
- query,
211
- "-n",
212
- String(limit * 2),
213
- "--json"
214
- ];
215
- if (this.collection) {
216
- args.push("-c", this.collection);
217
- }
218
- const qmdResults = execQmd(args, this.qmdIndexName);
219
- return this.convertResults(qmdResults, {
220
- limit,
221
- minScore,
222
- category,
223
- tags,
224
- fullContent,
225
- temporalBoost
226
- });
227
- }
228
- /**
229
- * Convert qmd results to ClawVault SearchResult format
230
- */
231
- convertResults(qmdResults, options) {
232
- const { limit = 10, minScore = 0, category, tags, fullContent = false, temporalBoost = false } = options;
233
- const results = [];
234
- const maxScore = qmdResults[0]?.score || 1;
235
- for (const qr of qmdResults) {
236
- const filePath = this.qmdUriToPath(qr.file);
237
- const relativePath = this.vaultPath ? path.relative(this.vaultPath, filePath) : filePath;
238
- const normalizedRelativePath = relativePath.replace(/\\/g, "/");
239
- if (normalizedRelativePath.startsWith("ledger/archive/") || normalizedRelativePath.includes("/ledger/archive/")) {
240
- continue;
241
- }
242
- const docId = normalizedRelativePath.replace(/\.md$/, "");
243
- let doc = this.documents.get(docId) ?? this.documents.get(docId.split("/").join(path.sep));
244
- const modifiedAt = this.resolveModifiedAt(doc, filePath);
245
- const parts = normalizedRelativePath.split("/");
246
- const docCategory = parts.length > 1 ? parts[0] : "root";
247
- if (category && docCategory !== category) continue;
248
- if (tags && tags.length > 0 && doc) {
249
- const docTags = new Set(doc.tags);
250
- if (!tags.some((t) => docTags.has(t))) continue;
251
- }
252
- const normalizedScore = maxScore > 0 ? qr.score / maxScore : 0;
253
- const finalScore = temporalBoost ? normalizedScore * this.getRecencyFactor(modifiedAt) : normalizedScore;
254
- if (finalScore < minScore) continue;
255
- if (!doc) {
256
- doc = {
257
- id: docId,
258
- path: filePath,
259
- category: docCategory,
260
- title: qr.title || path.basename(relativePath, ".md"),
261
- content: "",
262
- // Content loaded separately if needed
263
- frontmatter: {},
264
- links: [],
265
- tags: [],
266
- modified: modifiedAt
267
- };
268
- }
269
- results.push({
270
- document: fullContent ? doc : { ...doc, content: "" },
271
- score: finalScore,
272
- snippet: this.cleanSnippet(qr.snippet),
273
- matchedTerms: []
274
- // qmd doesn't provide this
275
- });
276
- }
277
- return results.sort((a, b) => b.score - a.score).slice(0, limit);
278
- }
279
- resolveModifiedAt(doc, filePath) {
280
- if (doc) return doc.modified;
281
- try {
282
- return fs.statSync(filePath).mtime;
283
- } catch {
284
- return /* @__PURE__ */ new Date(0);
285
- }
286
- }
287
- getRecencyFactor(modifiedAt) {
288
- const ageMs = Math.max(0, Date.now() - modifiedAt.getTime());
289
- const ageDays = ageMs / (24 * 60 * 60 * 1e3);
290
- if (ageDays < 1) return 1;
291
- if (ageDays <= 7) return 0.9;
292
- return 0.7;
293
- }
294
- /**
295
- * Convert qmd:// URI to file path
296
- */
297
- qmdUriToPath(uri) {
298
- if (uri.startsWith("qmd://")) {
299
- const withoutScheme = uri.slice(6);
300
- const slashIndex = withoutScheme.indexOf("/");
301
- if (slashIndex > -1) {
302
- const relativePath = withoutScheme.slice(slashIndex + 1);
303
- const root = this.collectionRoot || this.vaultPath;
304
- if (root) {
305
- return path.join(root, relativePath);
306
- }
307
- return relativePath;
308
- }
309
- }
310
- return uri;
311
- }
312
- /**
313
- * Clean up qmd snippet format
314
- */
315
- cleanSnippet(snippet) {
316
- if (!snippet) return "";
317
- return snippet.replace(/@@ [-+]?\d+,?\d* @@ \([^)]+\)/g, "").trim().split("\n").slice(0, 3).join("\n").slice(0, 300);
318
- }
319
- /**
320
- * Get all cached documents
321
- */
322
- getAllDocuments() {
323
- return [...this.documents.values()];
324
- }
325
- /**
326
- * Get document count
327
- */
328
- get size() {
329
- return this.documents.size;
330
- }
331
- /**
332
- * Clear the local document cache
333
- */
334
- clear() {
335
- this.documents.clear();
336
- }
337
- /**
338
- * Export documents for persistence
339
- */
340
- export() {
341
- return {
342
- documents: [...this.documents.values()]
343
- };
344
- }
345
- /**
346
- * Import from persisted data
347
- */
348
- import(data) {
349
- this.clear();
350
- for (const doc of data.documents) {
351
- this.addDocument(doc);
352
- }
353
- }
354
- };
355
- function extractWikiLinks(content) {
356
- const matches = content.match(/\[\[([^\]]+)\]\]/g) || [];
357
- return matches.map((m) => m.slice(2, -2).toLowerCase());
358
- }
359
- function extractTags(content) {
360
- const matches = content.match(/#[\w-]+/g) || [];
361
- return [...new Set(matches.map((m) => m.slice(1).toLowerCase()))];
362
- }
363
-
364
- export {
365
- QMD_INSTALL_URL,
366
- QMD_INSTALL_COMMAND,
367
- QmdUnavailableError,
368
- withQmdIndexArgs,
369
- hasQmd,
370
- qmdUpdate,
371
- qmdEmbed,
372
- SearchEngine,
373
- extractWikiLinks,
374
- extractTags
375
- };
@@ -1,183 +0,0 @@
1
- // src/lib/canvas-layout.ts
2
- import * as crypto from "crypto";
3
- var CANVAS_COLORS = {
4
- RED: "1",
5
- // Critical, blocked
6
- ORANGE: "2",
7
- // High priority
8
- YELLOW: "3",
9
- // Medium priority
10
- GREEN: "4",
11
- // Done, success
12
- CYAN: "5",
13
- // Stats
14
- PURPLE: "6"
15
- // Knowledge graph
16
- };
17
- var LAYOUT = {
18
- LEFT_COLUMN_X: 0,
19
- LEFT_COLUMN_WIDTH: 500,
20
- RIGHT_COLUMN_X: 550,
21
- RIGHT_COLUMN_WIDTH: 450,
22
- GROUP_PADDING: 20,
23
- NODE_SPACING: 15,
24
- GROUP_SPACING: 50,
25
- DEFAULT_NODE_WIDTH: 280,
26
- DEFAULT_NODE_HEIGHT: 80,
27
- FILE_NODE_HEIGHT: 60,
28
- SMALL_NODE_HEIGHT: 50,
29
- GROUP_HEADER_HEIGHT: 40
30
- };
31
- function generateId() {
32
- return crypto.randomBytes(8).toString("hex");
33
- }
34
- function createTextNode(x, y, width, height, text, color) {
35
- const node = {
36
- id: generateId(),
37
- type: "text",
38
- x,
39
- y,
40
- width,
41
- height,
42
- text
43
- };
44
- if (color) node.color = color;
45
- return node;
46
- }
47
- function createFileNode(x, y, width, height, file, color) {
48
- const node = {
49
- id: generateId(),
50
- type: "file",
51
- x,
52
- y,
53
- width,
54
- height,
55
- file
56
- };
57
- if (color) node.color = color;
58
- return node;
59
- }
60
- function createGroupNode(x, y, width, height, label, color) {
61
- const node = {
62
- id: generateId(),
63
- type: "group",
64
- x,
65
- y,
66
- width,
67
- height,
68
- label
69
- };
70
- if (color) node.color = color;
71
- return node;
72
- }
73
- function createEdge(fromNode, fromSide, toNode, toSide, label, color) {
74
- const edge = {
75
- id: generateId(),
76
- fromNode,
77
- fromSide,
78
- toNode,
79
- toSide
80
- };
81
- if (label) edge.label = label;
82
- if (color) edge.color = color;
83
- return edge;
84
- }
85
- function stackNodesVertically(nodes, startX, startY, spacing = LAYOUT.NODE_SPACING) {
86
- let currentY = startY;
87
- const positionedNodes = [];
88
- for (const node of nodes) {
89
- positionedNodes.push({
90
- ...node,
91
- x: startX,
92
- y: currentY
93
- });
94
- currentY += node.height + spacing;
95
- }
96
- return {
97
- nodes: positionedNodes,
98
- totalHeight: currentY - startY - spacing
99
- };
100
- }
101
- function createGroupWithNodes(groupX, groupY, groupWidth, label, childNodes, color) {
102
- const padding = LAYOUT.GROUP_PADDING;
103
- const headerHeight = LAYOUT.GROUP_HEADER_HEIGHT;
104
- const stacked = stackNodesVertically(
105
- childNodes,
106
- groupX + padding,
107
- groupY + headerHeight + padding
108
- );
109
- const groupHeight = headerHeight + padding * 2 + stacked.totalHeight + LAYOUT.NODE_SPACING;
110
- const group = createGroupNode(groupX, groupY, groupWidth, groupHeight, label, color);
111
- return {
112
- group,
113
- nodes: stacked.nodes
114
- };
115
- }
116
- function getPriorityColor(priority) {
117
- switch (priority) {
118
- case "critical":
119
- return CANVAS_COLORS.RED;
120
- case "high":
121
- return CANVAS_COLORS.ORANGE;
122
- case "medium":
123
- return CANVAS_COLORS.YELLOW;
124
- default:
125
- return void 0;
126
- }
127
- }
128
- function truncateText(text, maxChars) {
129
- if (text.length <= maxChars) return text;
130
- return text.slice(0, maxChars - 3) + "...";
131
- }
132
- function formatCanvasText(lines) {
133
- return lines.join("\n");
134
- }
135
- function calculateColumnHeight(groups) {
136
- let height = 0;
137
- for (let i = 0; i < groups.length; i++) {
138
- height += groups[i].group.height;
139
- if (i < groups.length - 1) {
140
- height += LAYOUT.GROUP_SPACING;
141
- }
142
- }
143
- return height;
144
- }
145
- function positionGroupsVertically(groups, startY = 0) {
146
- let currentY = startY;
147
- const positioned = [];
148
- for (const { group, nodes } of groups) {
149
- const yOffset = currentY - group.y;
150
- positioned.push({
151
- group: { ...group, y: currentY },
152
- nodes: nodes.map((n) => ({ ...n, y: n.y + yOffset }))
153
- });
154
- currentY += group.height + LAYOUT.GROUP_SPACING;
155
- }
156
- return positioned;
157
- }
158
- function flattenGroups(groups) {
159
- const nodes = [];
160
- for (const { group, nodes: childNodes } of groups) {
161
- nodes.push(group);
162
- nodes.push(...childNodes);
163
- }
164
- return nodes;
165
- }
166
-
167
- export {
168
- CANVAS_COLORS,
169
- LAYOUT,
170
- generateId,
171
- createTextNode,
172
- createFileNode,
173
- createGroupNode,
174
- createEdge,
175
- stackNodesVertically,
176
- createGroupWithNodes,
177
- getPriorityColor,
178
- truncateText,
179
- formatCanvasText,
180
- calculateColumnHeight,
181
- positionGroupsVertically,
182
- flattenGroups
183
- };
@@ -1,99 +0,0 @@
1
- import {
2
- resolveVaultPath
3
- } from "./chunk-MXSSG3QU.js";
4
-
5
- // src/commands/sync-bd.ts
6
- import * as fs from "fs";
7
- import * as path from "path";
8
- import { spawnSync } from "child_process";
9
- function hasBdBinary() {
10
- const probe = spawnSync("bd", ["--version"], { stdio: "ignore" });
11
- return !probe.error;
12
- }
13
- function parseBdTasksFromJson(raw) {
14
- const parsed = JSON.parse(raw);
15
- if (!Array.isArray(parsed)) {
16
- return [];
17
- }
18
- return parsed.map((entry) => {
19
- if (!entry || typeof entry !== "object") return null;
20
- const record = entry;
21
- const title = typeof record.title === "string" ? record.title.trim() : typeof record.name === "string" ? record.name.trim() : "";
22
- const status = typeof record.status === "string" ? record.status.trim().toLowerCase() : void 0;
23
- if (!title) return null;
24
- return status ? { title, status } : { title };
25
- }).filter((entry) => entry !== null);
26
- }
27
- function loadActiveBdTasks() {
28
- const jsonAttempt = spawnSync("bd", ["list", "--json"], { encoding: "utf-8" });
29
- if (!jsonAttempt.error && typeof jsonAttempt.stdout === "string" && jsonAttempt.stdout.trim()) {
30
- const tasks = parseBdTasksFromJson(jsonAttempt.stdout);
31
- if (tasks.length > 0) {
32
- return tasks.filter((task) => task.status !== "done" && task.status !== "completed" && task.status !== "closed");
33
- }
34
- }
35
- const textAttempt = spawnSync("bd", ["list"], { encoding: "utf-8" });
36
- if (textAttempt.error || typeof textAttempt.stdout !== "string") {
37
- return [];
38
- }
39
- return textAttempt.stdout.split(/\r?\n/).map((line) => line.replace(/^\s*[-*]\s*/, "").trim()).filter(Boolean).map((title) => ({ title }));
40
- }
41
- function upsertSection(markdown, heading, bulletLines) {
42
- const lines = markdown.split(/\r?\n/);
43
- const headingIndex = lines.findIndex((line) => line.trim() === heading);
44
- const sectionContent = [heading, ...bulletLines];
45
- if (headingIndex === -1) {
46
- const prefix = markdown.trim() ? `${markdown.trim()}
47
-
48
- ` : "";
49
- return `${prefix}${sectionContent.join("\n")}
50
- `;
51
- }
52
- let sectionEnd = lines.length;
53
- for (let index = headingIndex + 1; index < lines.length; index += 1) {
54
- if (lines[index].startsWith("## ")) {
55
- sectionEnd = index;
56
- break;
57
- }
58
- }
59
- const updated = [
60
- ...lines.slice(0, headingIndex),
61
- ...sectionContent,
62
- ...lines.slice(sectionEnd)
63
- ];
64
- return `${updated.join("\n").trim()}
65
- `;
66
- }
67
- async function syncBdCommand(options) {
68
- if (!hasBdBinary()) {
69
- console.log("bd binary not found; skipping sync-bd.");
70
- return;
71
- }
72
- const tasks = loadActiveBdTasks();
73
- const vaultPath = resolveVaultPath({ explicitPath: options.vaultPath });
74
- const nowViewPath = path.join(vaultPath, "views", "now.md");
75
- const heading = "## Active Tasks (from bd)";
76
- const bulletLines = tasks.length > 0 ? tasks.map((task) => `- ${task.title}`) : ["- No active bd tasks."];
77
- const existing = fs.existsSync(nowViewPath) ? fs.readFileSync(nowViewPath, "utf-8") : "# Now\n";
78
- const next = upsertSection(existing, heading, bulletLines);
79
- if (options.dryRun) {
80
- console.log(`Dry run: would sync ${tasks.length} active bd task(s) to views/now.md.`);
81
- return;
82
- }
83
- fs.mkdirSync(path.dirname(nowViewPath), { recursive: true });
84
- fs.writeFileSync(nowViewPath, next, "utf-8");
85
- console.log(`Synced ${tasks.length} active bd task(s) to views/now.md.`);
86
- }
87
- function registerSyncBdCommand(program) {
88
- program.command("sync-bd").description("Sync active bd tasks into views/now.md").option("--dry-run", "Show task sync output without writing").option("-v, --vault <path>", "Vault path").action(async (rawOptions) => {
89
- await syncBdCommand({
90
- vaultPath: rawOptions.vault,
91
- dryRun: rawOptions.dryRun
92
- });
93
- });
94
- }
95
-
96
- export {
97
- syncBdCommand,
98
- registerSyncBdCommand
99
- };