clawvault 2.6.3 → 2.6.5

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 (127) hide show
  1. package/README.md +351 -21
  2. package/bin/clawvault.js +8 -2
  3. package/bin/command-runtime.js +9 -1
  4. package/bin/register-maintenance-commands.js +19 -0
  5. package/bin/register-query-commands.js +58 -6
  6. package/bin/register-workgraph-commands.js +451 -0
  7. package/dist/chunk-2GKPENIR.js +66 -0
  8. package/dist/{chunk-VXEOHTSL.js → chunk-2JQ3O2YL.js} +1 -1
  9. package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
  10. package/dist/chunk-2ZDO52B4.js +52 -0
  11. package/dist/{chunk-ZZA73MFY.js → chunk-33DOSHTA.js} +176 -36
  12. package/dist/chunk-4BQTQMJP.js +93 -0
  13. package/dist/{chunk-MAKNAHAW.js → chunk-5PJ4STIC.js} +98 -8
  14. package/dist/{chunk-RVYA52PY.js → chunk-5UM4PMMM.js} +1 -1
  15. package/dist/{chunk-4VQTUVH7.js → chunk-7YZWHM36.js} +52 -26
  16. package/dist/{chunk-4VRIMU4O.js → chunk-A4EAUO7T.js} +5 -5
  17. package/dist/{chunk-R6SXNSFD.js → chunk-BV5KWZKR.js} +3 -3
  18. package/dist/chunk-FBITHIZF.js +351 -0
  19. package/dist/{chunk-Q2J5YTUF.js → chunk-FUSLEY6L.js} +751 -34
  20. package/dist/chunk-GNJL4YGR.js +79 -0
  21. package/dist/{chunk-42MXU7A6.js → chunk-K4GFGKFD.js} +51 -47
  22. package/dist/{chunk-PBEE567J.js → chunk-KSZROBFH.js} +2 -2
  23. package/dist/chunk-L4HSSQ6T.js +152 -0
  24. package/dist/{chunk-PZ2AUU2W.js → chunk-LMKQ7NIF.js} +206 -37
  25. package/dist/{chunk-6546Q4OR.js → chunk-M5O6FQ66.js} +6 -6
  26. package/dist/chunk-MM6QGW3P.js +207 -0
  27. package/dist/{chunk-T76H47ZS.js → chunk-MNPUYCHQ.js} +1 -1
  28. package/dist/{chunk-P5EPF6MB.js → chunk-MW5C6ZQA.js} +110 -13
  29. package/dist/{chunk-OZ7RIXTO.js → chunk-QSRRMEYM.js} +2 -2
  30. package/dist/chunk-RHISK3SZ.js +189 -0
  31. package/dist/{chunk-3BTHWPMB.js → chunk-S5OJEGFG.js} +2 -2
  32. package/dist/{chunk-MGDEINGP.js → chunk-SS4B7P7V.js} +1 -1
  33. package/dist/{chunk-ME37YNW3.js → chunk-SV7T4HRE.js} +4 -4
  34. package/dist/{chunk-IEVLHNLU.js → chunk-T3FKSZSN.js} +3 -3
  35. package/dist/{chunk-DTEHFAL7.js → chunk-TS6NDVOU.js} +2 -2
  36. package/dist/chunk-U4O6C46S.js +154 -0
  37. package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
  38. package/dist/chunk-WMGIIABP.js +15 -0
  39. package/dist/{chunk-QVMXF7FY.js → chunk-X3SPPUFG.js} +50 -0
  40. package/dist/{chunk-THRJVD4L.js → chunk-Y6VJKXGL.js} +1 -1
  41. package/dist/{chunk-RCBMXTWS.js → chunk-YD7SVXTF.js} +39 -7
  42. package/dist/{chunk-HIHOUSXS.js → chunk-YXQCA6B7.js} +105 -1
  43. package/dist/cli/index.js +20 -18
  44. package/dist/commands/archive.js +3 -2
  45. package/dist/commands/backlog.js +1 -0
  46. package/dist/commands/blocked.js +1 -0
  47. package/dist/commands/canvas.js +2 -1
  48. package/dist/commands/checkpoint.js +1 -0
  49. package/dist/commands/compat.js +2 -1
  50. package/dist/commands/context.js +6 -4
  51. package/dist/commands/doctor.d.ts +10 -1
  52. package/dist/commands/doctor.js +13 -10
  53. package/dist/commands/embed.js +5 -3
  54. package/dist/commands/entities.js +2 -1
  55. package/dist/commands/graph.js +4 -3
  56. package/dist/commands/inject.d.ts +1 -1
  57. package/dist/commands/inject.js +5 -4
  58. package/dist/commands/kanban.js +1 -0
  59. package/dist/commands/link.js +5 -4
  60. package/dist/commands/migrate-observations.js +3 -2
  61. package/dist/commands/observe.js +9 -7
  62. package/dist/commands/project.js +1 -0
  63. package/dist/commands/rebuild-embeddings.d.ts +21 -0
  64. package/dist/commands/rebuild-embeddings.js +91 -0
  65. package/dist/commands/rebuild.js +6 -4
  66. package/dist/commands/recover.js +1 -0
  67. package/dist/commands/reflect.js +5 -4
  68. package/dist/commands/repair-session.js +1 -0
  69. package/dist/commands/replay.js +7 -6
  70. package/dist/commands/session-recap.js +1 -0
  71. package/dist/commands/setup.js +3 -2
  72. package/dist/commands/shell-init.js +2 -0
  73. package/dist/commands/sleep.d.ts +1 -1
  74. package/dist/commands/sleep.js +10 -8
  75. package/dist/commands/status.js +13 -82
  76. package/dist/commands/sync-bd.js +3 -2
  77. package/dist/commands/tailscale.js +3 -2
  78. package/dist/commands/task.js +1 -0
  79. package/dist/commands/template.js +1 -0
  80. package/dist/commands/wake.d.ts +1 -1
  81. package/dist/commands/wake.js +5 -3
  82. package/dist/index.d.ts +254 -10
  83. package/dist/index.js +288 -155
  84. package/dist/{inject-x65KXWPk.d.ts → inject-DYUrDqQO.d.ts} +2 -2
  85. package/dist/ledger-B7g7jhqG.d.ts +44 -0
  86. package/dist/lib/auto-linker.js +2 -1
  87. package/dist/lib/canvas-layout.js +1 -0
  88. package/dist/lib/config.d.ts +27 -3
  89. package/dist/lib/config.js +4 -1
  90. package/dist/lib/entity-index.js +1 -0
  91. package/dist/lib/project-utils.js +1 -0
  92. package/dist/lib/session-repair.js +1 -0
  93. package/dist/lib/session-utils.js +1 -0
  94. package/dist/lib/tailscale.js +1 -0
  95. package/dist/lib/task-utils.js +1 -0
  96. package/dist/lib/template-engine.js +1 -0
  97. package/dist/lib/webdav.js +1 -0
  98. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  99. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  100. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  101. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  102. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  103. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  104. package/dist/registry-BR4326o0.d.ts +30 -0
  105. package/dist/store-CA-6sKCJ.d.ts +34 -0
  106. package/dist/thread-B9LhXNU0.d.ts +41 -0
  107. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  108. package/dist/{types-C74wgGL1.d.ts → types-BbWJoC1c.d.ts} +1 -1
  109. package/dist/workgraph/index.d.ts +5 -0
  110. package/dist/workgraph/index.js +23 -0
  111. package/dist/workgraph/ledger.d.ts +2 -0
  112. package/dist/workgraph/ledger.js +25 -0
  113. package/dist/workgraph/registry.d.ts +2 -0
  114. package/dist/workgraph/registry.js +19 -0
  115. package/dist/workgraph/store.d.ts +2 -0
  116. package/dist/workgraph/store.js +25 -0
  117. package/dist/workgraph/thread.d.ts +2 -0
  118. package/dist/workgraph/thread.js +25 -0
  119. package/dist/workgraph/types.d.ts +54 -0
  120. package/dist/workgraph/types.js +7 -0
  121. package/hooks/clawvault/handler.js +714 -2
  122. package/hooks/clawvault/handler.test.js +153 -0
  123. package/hooks/clawvault/openclaw.plugin.json +72 -0
  124. package/openclaw.plugin.json +14 -2
  125. package/package.json +5 -4
  126. package/dist/chunk-4QYGFWRM.js +0 -88
  127. package/dist/chunk-MXSSG3QU.js +0 -42
@@ -0,0 +1,79 @@
1
+ // src/lib/config.ts
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ function getVaultPath() {
5
+ const vaultPath = process.env.CLAWVAULT_PATH;
6
+ if (!vaultPath) {
7
+ throw new Error("CLAWVAULT_PATH environment variable not set");
8
+ }
9
+ return path.resolve(vaultPath);
10
+ }
11
+ function findNearestVaultPath(startPath = process.cwd()) {
12
+ let current = path.resolve(startPath);
13
+ while (true) {
14
+ if (fs.existsSync(path.join(current, ".clawvault.json"))) {
15
+ return current;
16
+ }
17
+ const parent = path.dirname(current);
18
+ if (parent === current) {
19
+ return null;
20
+ }
21
+ current = parent;
22
+ }
23
+ }
24
+ function validateVaultPath(vaultPath) {
25
+ if (!vaultPath || typeof vaultPath !== "string") return null;
26
+ const resolved = path.resolve(vaultPath);
27
+ if (!path.isAbsolute(resolved)) return null;
28
+ try {
29
+ const stat = fs.statSync(resolved);
30
+ if (!stat.isDirectory()) return null;
31
+ } catch {
32
+ return null;
33
+ }
34
+ const configPath = path.join(resolved, ".clawvault.json");
35
+ if (!fs.existsSync(configPath)) return null;
36
+ return resolved;
37
+ }
38
+ function resolveAgentVaultPath(agentVaults, agentId) {
39
+ if (!agentId || typeof agentId !== "string") return null;
40
+ if (!agentVaults || typeof agentVaults !== "object" || Array.isArray(agentVaults)) {
41
+ return null;
42
+ }
43
+ const agentPath = agentVaults[agentId];
44
+ if (!agentPath || typeof agentPath !== "string") return null;
45
+ return validateVaultPath(agentPath);
46
+ }
47
+ function resolveVaultPath(options = {}) {
48
+ if (options.explicitPath) {
49
+ return path.resolve(options.explicitPath);
50
+ }
51
+ if (options.agentId && options.pluginConfig?.agentVaults) {
52
+ const agentVaultPath = resolveAgentVaultPath(
53
+ options.pluginConfig.agentVaults,
54
+ options.agentId
55
+ );
56
+ if (agentVaultPath) {
57
+ return agentVaultPath;
58
+ }
59
+ }
60
+ if (options.pluginConfig?.vaultPath) {
61
+ const validated = validateVaultPath(options.pluginConfig.vaultPath);
62
+ if (validated) return validated;
63
+ }
64
+ if (process.env.CLAWVAULT_PATH) {
65
+ return path.resolve(process.env.CLAWVAULT_PATH);
66
+ }
67
+ const discovered = findNearestVaultPath(options.cwd ?? process.cwd());
68
+ if (discovered) {
69
+ return discovered;
70
+ }
71
+ throw new Error("No vault path found. Set CLAWVAULT_PATH, use --vault, or run inside a vault.");
72
+ }
73
+
74
+ export {
75
+ getVaultPath,
76
+ findNearestVaultPath,
77
+ resolveAgentVaultPath,
78
+ resolveVaultPath
79
+ };
@@ -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
  }
@@ -28,8 +28,42 @@ function findProtectedRanges(content) {
28
28
  }
29
29
  return ranges;
30
30
  }
31
- function isProtected(pos, ranges) {
32
- return ranges.some((r) => pos >= r.start && pos < r.end);
31
+ function isProtectedRange(start, end, ranges) {
32
+ return ranges.some((range) => start < range.end && end > range.start);
33
+ }
34
+ function createAliasRegex(alias) {
35
+ const escapedAlias = alias.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
36
+ return new RegExp(`\\b${escapedAlias}\\b`, "gi");
37
+ }
38
+ function formatWikiLink(path, originalText) {
39
+ return originalText.toLowerCase() === path.split("/").pop()?.toLowerCase() ? `[[${path}]]` : `[[${path}|${originalText}]]`;
40
+ }
41
+ function planLinks(content, index, protectedRanges) {
42
+ const sortedAliases = getSortedAliases(index);
43
+ const linkedEntities = /* @__PURE__ */ new Set();
44
+ const claimedRanges = [];
45
+ const plannedLinks = [];
46
+ for (const { alias, path } of sortedAliases) {
47
+ if (linkedEntities.has(path)) continue;
48
+ const regex = createAliasRegex(alias);
49
+ let match;
50
+ while ((match = regex.exec(content)) !== null) {
51
+ const start = match.index;
52
+ const end = start + match[0].length;
53
+ if (isProtectedRange(start, end, protectedRanges)) continue;
54
+ if (isProtectedRange(start, end, claimedRanges)) continue;
55
+ plannedLinks.push({
56
+ start,
57
+ end,
58
+ originalText: match[0],
59
+ path
60
+ });
61
+ claimedRanges.push({ start, end });
62
+ linkedEntities.add(path);
63
+ break;
64
+ }
65
+ }
66
+ return plannedLinks;
33
67
  }
34
68
  function createLineLookup(content) {
35
69
  const lines = content.split("\n");
@@ -48,56 +82,24 @@ function createLineLookup(content) {
48
82
  }
49
83
  function autoLink(content, index) {
50
84
  const protectedRanges = findProtectedRanges(content);
51
- const sortedAliases = getSortedAliases(index);
52
- const linkedEntities = /* @__PURE__ */ new Set();
85
+ const plannedLinks = planLinks(content, index, protectedRanges);
53
86
  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
- }
87
+ const sortedByPosition = plannedLinks.slice().sort((a, b) => b.start - a.start);
88
+ for (const planned of sortedByPosition) {
89
+ const replacement = formatWikiLink(planned.path, planned.originalText);
90
+ result = result.substring(0, planned.start) + replacement + result.substring(planned.end);
75
91
  }
76
92
  return result;
77
93
  }
78
94
  function dryRunLink(content, index) {
79
95
  const protectedRanges = findProtectedRanges(content);
80
- const sortedAliases = getSortedAliases(index);
81
- const linkedEntities = /* @__PURE__ */ new Set();
82
- const matches = [];
96
+ const plannedLinks = planLinks(content, index, protectedRanges);
83
97
  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;
98
+ return plannedLinks.map((planned) => ({
99
+ alias: planned.originalText,
100
+ path: planned.path,
101
+ line: getLineNumber(planned.start)
102
+ }));
101
103
  }
102
104
  function findUnlinkedMentions(content, index) {
103
105
  const protectedRanges = findProtectedRanges(content);
@@ -111,7 +113,9 @@ function findUnlinkedMentions(content, index) {
111
113
  const regex = new RegExp(`\\b${escapedAlias}\\b`, "gi");
112
114
  let match;
113
115
  while ((match = regex.exec(content)) !== null) {
114
- if (isProtected(match.index, protectedRanges)) continue;
116
+ const start = match.index;
117
+ const end = start + match[0].length;
118
+ if (isProtectedRange(start, end, protectedRanges)) continue;
115
119
  matches.push({
116
120
  alias: match[0],
117
121
  path,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Observer
3
- } from "./chunk-Q2J5YTUF.js";
3
+ } from "./chunk-FUSLEY6L.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,
@@ -0,0 +1,152 @@
1
+ import {
2
+ getType,
3
+ loadRegistry
4
+ } from "./chunk-MM6QGW3P.js";
5
+ import {
6
+ append
7
+ } from "./chunk-4BQTQMJP.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
+ };