clawvault 3.2.1 → 3.4.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 (161) hide show
  1. package/README.md +56 -16
  2. package/bin/clawvault.js +0 -2
  3. package/bin/command-registration.test.js +15 -2
  4. package/bin/help-contract.test.js +16 -0
  5. package/bin/register-core-commands.js +88 -0
  6. package/bin/register-core-commands.test.js +80 -0
  7. package/bin/register-maintenance-commands.js +84 -7
  8. package/bin/register-query-commands.js +45 -28
  9. package/bin/register-query-commands.test.js +15 -0
  10. package/bin/test-helpers/cli-command-fixtures.js +1 -0
  11. package/dist/chunk-2PKBIKDH.js +130 -0
  12. package/dist/{chunk-U67V476Y.js → chunk-2ZDO52B4.js} +18 -1
  13. package/dist/{chunk-ZZA73MFY.js → chunk-33DOSHTA.js} +176 -36
  14. package/dist/chunk-35JCYSRR.js +158 -0
  15. package/dist/{chunk-AZYOKJYC.js → chunk-4PY655YM.js} +13 -1
  16. package/dist/{chunk-2JQ3O2YL.js → chunk-5EFSWZO6.js} +3 -3
  17. package/dist/{chunk-Y3TIJEBP.js → chunk-7SWP5FKU.js} +34 -613
  18. package/dist/{chunk-4VQTUVH7.js → chunk-7YZWHM36.js} +52 -26
  19. package/dist/{chunk-URXDAUVH.js → chunk-AXSJIFOJ.js} +174 -1
  20. package/dist/{chunk-4ITRXIVT.js → chunk-BLQXXX7Q.js} +6 -6
  21. package/dist/chunk-CSHO3PJB.js +684 -0
  22. package/dist/chunk-D5U3Q4N5.js +872 -0
  23. package/dist/chunk-DCF4KMFD.js +158 -0
  24. package/dist/{chunk-S5OJEGFG.js → chunk-DOIUYIXV.js} +2 -2
  25. package/dist/{chunk-YXQCA6B7.js → chunk-DVOUSOR3.js} +112 -7
  26. package/dist/{chunk-YDWHS4LJ.js → chunk-ECGJYWNA.js} +205 -33
  27. package/dist/{chunk-QMHPQYUV.js → chunk-EL6UBSX5.js} +7 -6
  28. package/dist/chunk-FZ5I2NF7.js +352 -0
  29. package/dist/{chunk-WJVWINEM.js → chunk-GFCHWMGD.js} +55 -6
  30. package/dist/{chunk-GNJL4YGR.js → chunk-GJO3CFUN.js} +30 -6
  31. package/dist/chunk-H3JZIB5O.js +322 -0
  32. package/dist/chunk-HEHO7SMV.js +51 -0
  33. package/dist/{chunk-UCQAOZHW.js → chunk-HGDDW24U.js} +3 -3
  34. package/dist/chunk-J3YUXVID.js +907 -0
  35. package/dist/{chunk-Y6VJKXGL.js → chunk-KCYWJDDW.js} +1 -1
  36. package/dist/{chunk-P5EPF6MB.js → chunk-MW5C6ZQA.js} +110 -13
  37. package/dist/chunk-NSXYM6EZ.js +255 -0
  38. package/dist/{chunk-YNIPYN4F.js → chunk-OFOCU2V4.js} +6 -5
  39. package/dist/{chunk-42MXU7A6.js → chunk-P62WHA27.js} +58 -47
  40. package/dist/chunk-PTWPPVC7.js +972 -0
  41. package/dist/{chunk-FAKNOB7Y.js → chunk-QFWERBDP.js} +2 -2
  42. package/dist/chunk-QYQAGBTM.js +2097 -0
  43. package/dist/chunk-RL2L6I6K.js +223 -0
  44. package/dist/{chunk-IIOU45CK.js → chunk-S7N7HI5E.js} +2 -2
  45. package/dist/{chunk-ECRZL5XR.js → chunk-T7E764W3.js} +23 -7
  46. package/dist/{chunk-MNPUYCHQ.js → chunk-TWMI3SNN.js} +6 -5
  47. package/dist/{chunk-2RAZ4ZFE.js → chunk-VBILES4B.js} +1 -1
  48. package/dist/{chunk-PI4WMLMG.js → chunk-VXAGOLDP.js} +1 -1
  49. package/dist/{chunk-SS4B7P7V.js → chunk-YIDV4VV2.js} +1 -1
  50. package/dist/chunk-YTRZNA64.js +37 -0
  51. package/dist/chunk-ZKWPCBYT.js +600 -0
  52. package/dist/cli/index.js +28 -21
  53. package/dist/commands/archive.js +3 -3
  54. package/dist/commands/backlog.js +1 -1
  55. package/dist/commands/benchmark.d.ts +12 -0
  56. package/dist/commands/benchmark.js +12 -0
  57. package/dist/commands/blocked.js +1 -1
  58. package/dist/commands/canvas.js +2 -2
  59. package/dist/commands/checkpoint.js +1 -1
  60. package/dist/commands/compat.js +1 -1
  61. package/dist/commands/context.js +8 -7
  62. package/dist/commands/doctor.d.ts +8 -3
  63. package/dist/commands/doctor.js +8 -22
  64. package/dist/commands/embed.js +6 -5
  65. package/dist/commands/entities.d.ts +8 -1
  66. package/dist/commands/entities.js +46 -3
  67. package/dist/commands/graph.js +4 -4
  68. package/dist/commands/inbox.d.ts +23 -0
  69. package/dist/commands/inbox.js +11 -0
  70. package/dist/commands/inject.d.ts +1 -1
  71. package/dist/commands/inject.js +5 -5
  72. package/dist/commands/kanban.js +1 -1
  73. package/dist/commands/link.js +5 -5
  74. package/dist/commands/maintain.d.ts +32 -0
  75. package/dist/commands/maintain.js +13 -0
  76. package/dist/commands/migrate-observations.js +3 -3
  77. package/dist/commands/observe.js +11 -10
  78. package/dist/commands/project.js +2 -2
  79. package/dist/commands/rebuild-embeddings.js +48 -17
  80. package/dist/commands/rebuild.js +9 -8
  81. package/dist/commands/recall.d.ts +14 -0
  82. package/dist/commands/recall.js +15 -0
  83. package/dist/commands/recover.js +1 -1
  84. package/dist/commands/reflect.js +6 -6
  85. package/dist/commands/repair-session.js +1 -1
  86. package/dist/commands/replay.js +10 -9
  87. package/dist/commands/session-recap.js +1 -1
  88. package/dist/commands/setup.js +4 -3
  89. package/dist/commands/shell-init.js +1 -1
  90. package/dist/commands/sleep.d.ts +1 -1
  91. package/dist/commands/sleep.js +20 -18
  92. package/dist/commands/status.js +40 -26
  93. package/dist/commands/sync-bd.js +3 -3
  94. package/dist/commands/tailscale.js +3 -3
  95. package/dist/commands/task.js +1 -1
  96. package/dist/commands/template.js +1 -1
  97. package/dist/commands/wake.d.ts +1 -1
  98. package/dist/commands/wake.js +10 -9
  99. package/dist/index.d.ts +233 -16
  100. package/dist/index.js +325 -111
  101. package/dist/{inject-DYUrDqQO.d.ts → inject-DEb_jpLi.d.ts} +3 -1
  102. package/dist/lib/auto-linker.js +2 -2
  103. package/dist/lib/canvas-layout.js +1 -1
  104. package/dist/lib/config.js +2 -2
  105. package/dist/lib/entity-index.js +1 -1
  106. package/dist/lib/project-utils.js +2 -2
  107. package/dist/lib/session-repair.js +1 -1
  108. package/dist/lib/session-utils.js +1 -1
  109. package/dist/lib/tailscale.js +1 -1
  110. package/dist/lib/task-utils.js +1 -1
  111. package/dist/lib/template-engine.js +1 -1
  112. package/dist/lib/webdav.js +1 -1
  113. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  114. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  115. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  116. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  117. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  118. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  119. package/dist/openclaw-plugin--gqA2BZw.d.ts +267 -0
  120. package/dist/openclaw-plugin.d.ts +4 -0
  121. package/dist/openclaw-plugin.js +20 -0
  122. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  123. package/dist/types-CbL-wIKi.d.ts +36 -0
  124. package/dist/{types-BbWJoC1c.d.ts → types-DslKvCaj.d.ts} +51 -1
  125. package/hooks/clawvault/HOOK.md +25 -8
  126. package/hooks/clawvault/handler.js +215 -78
  127. package/hooks/clawvault/handler.test.js +109 -43
  128. package/hooks/clawvault/integrity.js +112 -0
  129. package/hooks/clawvault/integrity.test.js +32 -0
  130. package/hooks/clawvault/openclaw.plugin.json +133 -15
  131. package/openclaw.plugin.json +161 -194
  132. package/package.json +8 -5
  133. package/bin/register-workgraph-commands.js +0 -451
  134. package/dist/chunk-5PJ4STIC.js +0 -465
  135. package/dist/chunk-ERNE2FZ5.js +0 -189
  136. package/dist/chunk-HR4KN6S2.js +0 -152
  137. package/dist/chunk-IJBFGPCS.js +0 -33
  138. package/dist/chunk-K7PNYS45.js +0 -93
  139. package/dist/chunk-NTOPJI7W.js +0 -207
  140. package/dist/chunk-PG56HX5T.js +0 -154
  141. package/dist/chunk-QPDDIHXE.js +0 -501
  142. package/dist/chunk-WIOLLGAD.js +0 -190
  143. package/dist/chunk-WMGIIABP.js +0 -15
  144. package/dist/ledger-B7g7jhqG.d.ts +0 -44
  145. package/dist/plugin/index.d.ts +0 -352
  146. package/dist/plugin/index.js +0 -4264
  147. package/dist/registry-BR4326o0.d.ts +0 -30
  148. package/dist/store-CA-6sKCJ.d.ts +0 -34
  149. package/dist/thread-B9LhXNU0.d.ts +0 -41
  150. package/dist/workgraph/index.d.ts +0 -5
  151. package/dist/workgraph/index.js +0 -23
  152. package/dist/workgraph/ledger.d.ts +0 -2
  153. package/dist/workgraph/ledger.js +0 -25
  154. package/dist/workgraph/registry.d.ts +0 -2
  155. package/dist/workgraph/registry.js +0 -19
  156. package/dist/workgraph/store.d.ts +0 -2
  157. package/dist/workgraph/store.js +0 -25
  158. package/dist/workgraph/thread.d.ts +0 -2
  159. package/dist/workgraph/thread.js +0 -25
  160. package/dist/workgraph/types.d.ts +0 -54
  161. package/dist/workgraph/types.js +0 -7
@@ -1,152 +0,0 @@
1
- import {
2
- append
3
- } from "./chunk-K7PNYS45.js";
4
- import {
5
- getType,
6
- loadRegistry
7
- } from "./chunk-NTOPJI7W.js";
8
- import {
9
- __export
10
- } from "./chunk-U67V476Y.js";
11
-
12
- // src/workgraph/store.ts
13
- var store_exports = {};
14
- __export(store_exports, {
15
- activeThreads: () => activeThreads,
16
- blockedThreads: () => blockedThreads,
17
- create: () => create,
18
- findByField: () => findByField,
19
- list: () => list,
20
- openThreads: () => openThreads,
21
- read: () => read,
22
- remove: () => remove,
23
- update: () => update
24
- });
25
- import fs from "fs";
26
- import path from "path";
27
- import matter from "gray-matter";
28
- function create(vaultPath, typeName, fields, body, actor) {
29
- const typeDef = getType(vaultPath, typeName);
30
- if (!typeDef) {
31
- throw new Error(`Unknown primitive type "${typeName}". Run \`clawvault primitive list\` to see available types, or \`clawvault primitive define\` to create one.`);
32
- }
33
- const now = (/* @__PURE__ */ new Date()).toISOString();
34
- const merged = applyDefaults(typeDef, {
35
- ...fields,
36
- created: fields.created ?? now,
37
- updated: now
38
- });
39
- const slug = slugify(String(merged.title ?? merged.name ?? typeName));
40
- const relDir = typeDef.directory;
41
- const relPath = `${relDir}/${slug}.md`;
42
- const absDir = path.join(vaultPath, relDir);
43
- const absPath = path.join(vaultPath, relPath);
44
- if (!fs.existsSync(absDir)) fs.mkdirSync(absDir, { recursive: true });
45
- if (fs.existsSync(absPath)) {
46
- throw new Error(`File already exists: ${relPath}. Use update instead.`);
47
- }
48
- const content = matter.stringify(body, stripUndefined(merged));
49
- fs.writeFileSync(absPath, content, "utf-8");
50
- append(vaultPath, actor, "create", relPath, typeName, {
51
- title: merged.title ?? slug
52
- });
53
- return { path: relPath, type: typeName, fields: merged, body };
54
- }
55
- function read(vaultPath, relPath) {
56
- const absPath = path.join(vaultPath, relPath);
57
- if (!fs.existsSync(absPath)) return null;
58
- const raw = fs.readFileSync(absPath, "utf-8");
59
- const { data, content } = matter(raw);
60
- const typeName = inferType(vaultPath, relPath);
61
- return { path: relPath, type: typeName, fields: data, body: content.trim() };
62
- }
63
- function list(vaultPath, typeName) {
64
- const typeDef = getType(vaultPath, typeName);
65
- if (!typeDef) return [];
66
- const dir = path.join(vaultPath, typeDef.directory);
67
- if (!fs.existsSync(dir)) return [];
68
- const files = fs.readdirSync(dir).filter((f) => f.endsWith(".md"));
69
- const instances = [];
70
- for (const file of files) {
71
- const relPath = `${typeDef.directory}/${file}`;
72
- const inst = read(vaultPath, relPath);
73
- if (inst) instances.push(inst);
74
- }
75
- return instances;
76
- }
77
- function update(vaultPath, relPath, fieldUpdates, bodyUpdate, actor) {
78
- const existing = read(vaultPath, relPath);
79
- if (!existing) throw new Error(`Not found: ${relPath}`);
80
- const now = (/* @__PURE__ */ new Date()).toISOString();
81
- const newFields = { ...existing.fields, ...fieldUpdates, updated: now };
82
- const newBody = bodyUpdate ?? existing.body;
83
- const absPath = path.join(vaultPath, relPath);
84
- const content = matter.stringify(newBody, stripUndefined(newFields));
85
- fs.writeFileSync(absPath, content, "utf-8");
86
- append(vaultPath, actor, "update", relPath, existing.type, {
87
- changed: Object.keys(fieldUpdates)
88
- });
89
- return { path: relPath, type: existing.type, fields: newFields, body: newBody };
90
- }
91
- function remove(vaultPath, relPath, actor) {
92
- const absPath = path.join(vaultPath, relPath);
93
- if (!fs.existsSync(absPath)) throw new Error(`Not found: ${relPath}`);
94
- const archiveDir = path.join(vaultPath, ".clawvault", "archive");
95
- if (!fs.existsSync(archiveDir)) fs.mkdirSync(archiveDir, { recursive: true });
96
- const archivePath = path.join(archiveDir, path.basename(relPath));
97
- fs.renameSync(absPath, archivePath);
98
- const typeName = inferType(vaultPath, relPath);
99
- append(vaultPath, actor, "delete", relPath, typeName);
100
- }
101
- function findByField(vaultPath, typeName, field, value) {
102
- return list(vaultPath, typeName).filter((inst) => inst.fields[field] === value);
103
- }
104
- function openThreads(vaultPath) {
105
- return findByField(vaultPath, "thread", "status", "open");
106
- }
107
- function activeThreads(vaultPath) {
108
- return findByField(vaultPath, "thread", "status", "active");
109
- }
110
- function blockedThreads(vaultPath) {
111
- return findByField(vaultPath, "thread", "status", "blocked");
112
- }
113
- function slugify(text) {
114
- return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
115
- }
116
- function applyDefaults(typeDef, fields) {
117
- const result = { ...fields };
118
- for (const [key, def] of Object.entries(typeDef.fields)) {
119
- if (result[key] === void 0 && def.default !== void 0) {
120
- result[key] = def.default;
121
- }
122
- }
123
- return result;
124
- }
125
- function stripUndefined(obj) {
126
- const result = {};
127
- for (const [k, v] of Object.entries(obj)) {
128
- if (v !== void 0) result[k] = v;
129
- }
130
- return result;
131
- }
132
- function inferType(vaultPath, relPath) {
133
- const registry = loadRegistry(vaultPath);
134
- const dir = relPath.split("/")[0];
135
- for (const typeDef of Object.values(registry.types)) {
136
- if (typeDef.directory === dir) return typeDef.name;
137
- }
138
- return "unknown";
139
- }
140
-
141
- export {
142
- create,
143
- read,
144
- list,
145
- update,
146
- remove,
147
- findByField,
148
- openThreads,
149
- activeThreads,
150
- blockedThreads,
151
- store_exports
152
- };
@@ -1,33 +0,0 @@
1
- import {
2
- registerTailscaleCommands
3
- } from "./chunk-Y6VJKXGL.js";
4
- import {
5
- registerObserveCommand
6
- } from "./chunk-4ITRXIVT.js";
7
- import {
8
- registerReflectCommand
9
- } from "./chunk-S5OJEGFG.js";
10
- import {
11
- registerContextCommand
12
- } from "./chunk-WJVWINEM.js";
13
- import {
14
- registerEmbedCommand
15
- } from "./chunk-ECRZL5XR.js";
16
- import {
17
- registerInjectCommand
18
- } from "./chunk-YNIPYN4F.js";
19
-
20
- // src/cli/index.ts
21
- function registerCliCommands(program) {
22
- registerContextCommand(program);
23
- registerInjectCommand(program);
24
- registerObserveCommand(program);
25
- registerReflectCommand(program);
26
- registerEmbedCommand(program);
27
- registerTailscaleCommands(program);
28
- return program;
29
- }
30
-
31
- export {
32
- registerCliCommands
33
- };
@@ -1,93 +0,0 @@
1
- import {
2
- __export
3
- } from "./chunk-U67V476Y.js";
4
-
5
- // src/workgraph/ledger.ts
6
- var ledger_exports = {};
7
- __export(ledger_exports, {
8
- activityOf: () => activityOf,
9
- allClaims: () => allClaims,
10
- append: () => append,
11
- currentOwner: () => currentOwner,
12
- historyOf: () => historyOf,
13
- isClaimed: () => isClaimed,
14
- ledgerPath: () => ledgerPath,
15
- readAll: () => readAll,
16
- readSince: () => readSince,
17
- recent: () => recent
18
- });
19
- import fs from "fs";
20
- import path from "path";
21
- var LEDGER_FILE = ".clawvault/ledger.jsonl";
22
- function ledgerPath(vaultPath) {
23
- return path.join(vaultPath, LEDGER_FILE);
24
- }
25
- function append(vaultPath, actor, op, target, type, data) {
26
- const entry = {
27
- ts: (/* @__PURE__ */ new Date()).toISOString(),
28
- actor,
29
- op,
30
- target,
31
- ...type ? { type } : {},
32
- ...data && Object.keys(data).length > 0 ? { data } : {}
33
- };
34
- const lPath = ledgerPath(vaultPath);
35
- const dir = path.dirname(lPath);
36
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
37
- fs.appendFileSync(lPath, JSON.stringify(entry) + "\n", "utf-8");
38
- return entry;
39
- }
40
- function readAll(vaultPath) {
41
- const lPath = ledgerPath(vaultPath);
42
- if (!fs.existsSync(lPath)) return [];
43
- const lines = fs.readFileSync(lPath, "utf-8").split("\n").filter(Boolean);
44
- return lines.map((line) => JSON.parse(line));
45
- }
46
- function readSince(vaultPath, since) {
47
- return readAll(vaultPath).filter((e) => e.ts >= since);
48
- }
49
- function currentOwner(vaultPath, target) {
50
- const entries = readAll(vaultPath).filter((e) => e.target === target);
51
- let owner = null;
52
- for (const e of entries) {
53
- if (e.op === "claim") owner = e.actor;
54
- if (e.op === "release" || e.op === "done" || e.op === "cancel") owner = null;
55
- }
56
- return owner;
57
- }
58
- function isClaimed(vaultPath, target) {
59
- return currentOwner(vaultPath, target) !== null;
60
- }
61
- function historyOf(vaultPath, target) {
62
- return readAll(vaultPath).filter((e) => e.target === target);
63
- }
64
- function activityOf(vaultPath, actor) {
65
- return readAll(vaultPath).filter((e) => e.actor === actor);
66
- }
67
- function allClaims(vaultPath) {
68
- const claims = /* @__PURE__ */ new Map();
69
- const entries = readAll(vaultPath);
70
- for (const e of entries) {
71
- if (e.op === "claim") claims.set(e.target, e.actor);
72
- if (e.op === "release" || e.op === "done" || e.op === "cancel") claims.delete(e.target);
73
- }
74
- return claims;
75
- }
76
- function recent(vaultPath, count = 20) {
77
- const all = readAll(vaultPath);
78
- return all.slice(-count);
79
- }
80
-
81
- export {
82
- ledgerPath,
83
- append,
84
- readAll,
85
- readSince,
86
- currentOwner,
87
- isClaimed,
88
- historyOf,
89
- activityOf,
90
- allClaims,
91
- recent,
92
- ledger_exports
93
- };
@@ -1,207 +0,0 @@
1
- import {
2
- __export
3
- } from "./chunk-U67V476Y.js";
4
-
5
- // src/workgraph/registry.ts
6
- var registry_exports = {};
7
- __export(registry_exports, {
8
- defineType: () => defineType,
9
- extendType: () => extendType,
10
- getType: () => getType,
11
- listTypes: () => listTypes,
12
- loadRegistry: () => loadRegistry,
13
- registryPath: () => registryPath,
14
- saveRegistry: () => saveRegistry
15
- });
16
- import fs from "fs";
17
- import path from "path";
18
- var REGISTRY_FILE = ".clawvault/registry.json";
19
- var CURRENT_VERSION = 1;
20
- var BUILT_IN_TYPES = [
21
- {
22
- name: "thread",
23
- description: "A unit of coordinated work. The core workgraph node.",
24
- directory: "threads",
25
- builtIn: true,
26
- createdAt: "2026-01-01T00:00:00.000Z",
27
- createdBy: "system",
28
- fields: {
29
- title: { type: "string", required: true, description: "What this thread is about" },
30
- goal: { type: "string", required: true, description: "What success looks like" },
31
- status: { type: "string", required: true, default: "open", description: "open | active | blocked | done | cancelled" },
32
- owner: { type: "string", description: "Agent that claimed this thread" },
33
- priority: { type: "string", default: "medium", description: "urgent | high | medium | low" },
34
- deps: { type: "list", default: [], description: "Wiki-link refs to threads this depends on" },
35
- parent: { type: "ref", description: "Parent thread (if decomposed from a larger thread)" },
36
- context_refs: { type: "list", default: [], description: "Wiki-link refs to vault docs that inform this work" },
37
- tags: { type: "list", default: [], description: "Freeform tags" },
38
- created: { type: "date", required: true },
39
- updated: { type: "date", required: true }
40
- }
41
- },
42
- {
43
- name: "space",
44
- description: "A workspace boundary that groups related threads and sets context.",
45
- directory: "spaces",
46
- builtIn: true,
47
- createdAt: "2026-01-01T00:00:00.000Z",
48
- createdBy: "system",
49
- fields: {
50
- title: { type: "string", required: true, description: "Space name" },
51
- description: { type: "string", description: "What this space is for" },
52
- members: { type: "list", default: [], description: "Agent names that participate" },
53
- thread_refs: { type: "list", default: [], description: "Wiki-link refs to threads in this space" },
54
- tags: { type: "list", default: [], description: "Freeform tags" },
55
- created: { type: "date", required: true },
56
- updated: { type: "date", required: true }
57
- }
58
- },
59
- {
60
- name: "decision",
61
- description: "A recorded decision with reasoning and context.",
62
- directory: "decisions",
63
- builtIn: true,
64
- createdAt: "2026-01-01T00:00:00.000Z",
65
- createdBy: "system",
66
- fields: {
67
- title: { type: "string", required: true },
68
- date: { type: "date", required: true },
69
- status: { type: "string", default: "active", description: "active | superseded | reverted" },
70
- context_refs: { type: "list", default: [], description: "What informed this decision" },
71
- tags: { type: "list", default: [] }
72
- }
73
- },
74
- {
75
- name: "lesson",
76
- description: "A captured insight or pattern learned from experience.",
77
- directory: "lessons",
78
- builtIn: true,
79
- createdAt: "2026-01-01T00:00:00.000Z",
80
- createdBy: "system",
81
- fields: {
82
- title: { type: "string", required: true },
83
- date: { type: "date", required: true },
84
- confidence: { type: "string", default: "medium", description: "high | medium | low" },
85
- context_refs: { type: "list", default: [] },
86
- tags: { type: "list", default: [] }
87
- }
88
- },
89
- {
90
- name: "fact",
91
- description: "A structured piece of knowledge with optional temporal validity.",
92
- directory: "facts",
93
- builtIn: true,
94
- createdAt: "2026-01-01T00:00:00.000Z",
95
- createdBy: "system",
96
- fields: {
97
- subject: { type: "string", required: true },
98
- predicate: { type: "string", required: true },
99
- object: { type: "string", required: true },
100
- confidence: { type: "number", default: 1 },
101
- valid_from: { type: "date" },
102
- valid_until: { type: "date" },
103
- source: { type: "ref", description: "Where this fact came from" }
104
- }
105
- },
106
- {
107
- name: "agent",
108
- description: "A registered participant in the workgraph.",
109
- directory: "agents",
110
- builtIn: true,
111
- createdAt: "2026-01-01T00:00:00.000Z",
112
- createdBy: "system",
113
- fields: {
114
- name: { type: "string", required: true },
115
- role: { type: "string", description: "What this agent specializes in" },
116
- capabilities: { type: "list", default: [], description: "What this agent can do" },
117
- active_threads: { type: "list", default: [], description: "Threads currently claimed" },
118
- last_seen: { type: "date" }
119
- }
120
- }
121
- ];
122
- function registryPath(vaultPath) {
123
- return path.join(vaultPath, REGISTRY_FILE);
124
- }
125
- function loadRegistry(vaultPath) {
126
- const rPath = registryPath(vaultPath);
127
- if (fs.existsSync(rPath)) {
128
- const raw = fs.readFileSync(rPath, "utf-8");
129
- const registry = JSON.parse(raw);
130
- return ensureBuiltIns(registry);
131
- }
132
- return seedRegistry();
133
- }
134
- function saveRegistry(vaultPath, registry) {
135
- const rPath = registryPath(vaultPath);
136
- const dir = path.dirname(rPath);
137
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
138
- fs.writeFileSync(rPath, JSON.stringify(registry, null, 2) + "\n", "utf-8");
139
- }
140
- function defineType(vaultPath, name, description, fields, actor, directory) {
141
- const registry = loadRegistry(vaultPath);
142
- const safeName = name.toLowerCase().replace(/[^a-z0-9_-]/g, "-");
143
- if (registry.types[safeName]?.builtIn) {
144
- throw new Error(`Cannot redefine built-in type "${safeName}". You can extend it with new fields instead.`);
145
- }
146
- const now = (/* @__PURE__ */ new Date()).toISOString();
147
- const typeDef = {
148
- name: safeName,
149
- description,
150
- fields: {
151
- title: { type: "string", required: true },
152
- created: { type: "date", required: true },
153
- updated: { type: "date", required: true },
154
- tags: { type: "list", default: [] },
155
- ...fields
156
- },
157
- directory: directory ?? `${safeName}s`,
158
- builtIn: false,
159
- createdAt: now,
160
- createdBy: actor
161
- };
162
- registry.types[safeName] = typeDef;
163
- saveRegistry(vaultPath, registry);
164
- return typeDef;
165
- }
166
- function getType(vaultPath, name) {
167
- const registry = loadRegistry(vaultPath);
168
- return registry.types[name];
169
- }
170
- function listTypes(vaultPath) {
171
- const registry = loadRegistry(vaultPath);
172
- return Object.values(registry.types);
173
- }
174
- function extendType(vaultPath, name, newFields, actor) {
175
- const registry = loadRegistry(vaultPath);
176
- const existing = registry.types[name];
177
- if (!existing) throw new Error(`Type "${name}" not found in registry.`);
178
- existing.fields = { ...existing.fields, ...newFields };
179
- saveRegistry(vaultPath, registry);
180
- return existing;
181
- }
182
- function seedRegistry() {
183
- const types = {};
184
- for (const t of BUILT_IN_TYPES) {
185
- types[t.name] = t;
186
- }
187
- return { version: CURRENT_VERSION, types };
188
- }
189
- function ensureBuiltIns(registry) {
190
- for (const t of BUILT_IN_TYPES) {
191
- if (!registry.types[t.name]) {
192
- registry.types[t.name] = t;
193
- }
194
- }
195
- return registry;
196
- }
197
-
198
- export {
199
- registryPath,
200
- loadRegistry,
201
- saveRegistry,
202
- defineType,
203
- getType,
204
- listTypes,
205
- extendType,
206
- registry_exports
207
- };
@@ -1,154 +0,0 @@
1
- // src/lib/hybrid-search.ts
2
- import * as fs from "fs";
3
- import * as path from "path";
4
- var embeddingPipeline = null;
5
- var pipelineLoading = null;
6
- async function getEmbeddingPipeline() {
7
- if (embeddingPipeline) return embeddingPipeline;
8
- if (pipelineLoading) return pipelineLoading;
9
- pipelineLoading = (async () => {
10
- const { pipeline } = await import("@huggingface/transformers");
11
- embeddingPipeline = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2", {
12
- dtype: "fp32"
13
- });
14
- return embeddingPipeline;
15
- })();
16
- return pipelineLoading;
17
- }
18
- async function embed(text) {
19
- const pipe = await getEmbeddingPipeline();
20
- const result = await pipe(text, { pooling: "mean", normalize: true });
21
- return new Float32Array(result.data);
22
- }
23
- async function embedBatch(texts) {
24
- const pipe = await getEmbeddingPipeline();
25
- const results = [];
26
- const batchSize = 32;
27
- for (let i = 0; i < texts.length; i += batchSize) {
28
- const batch = texts.slice(i, i + batchSize);
29
- for (const text of batch) {
30
- const result = await pipe(text, { pooling: "mean", normalize: true });
31
- results.push(new Float32Array(result.data));
32
- }
33
- }
34
- return results;
35
- }
36
- function cosineSimilarity(a, b) {
37
- let dot = 0;
38
- for (let i = 0; i < a.length; i++) {
39
- dot += a[i] * b[i];
40
- }
41
- return dot;
42
- }
43
- var EmbeddingCache = class {
44
- cachePath;
45
- cache = /* @__PURE__ */ new Map();
46
- dirty = false;
47
- constructor(vaultPath) {
48
- this.cachePath = path.join(vaultPath, ".clawvault", "embeddings.bin");
49
- }
50
- /**
51
- * Load cache from disk
52
- */
53
- load() {
54
- try {
55
- if (!fs.existsSync(this.cachePath)) return;
56
- const data = JSON.parse(fs.readFileSync(this.cachePath + ".json", "utf-8"));
57
- for (const [key, arr] of Object.entries(data)) {
58
- this.cache.set(key, new Float32Array(arr));
59
- }
60
- } catch {
61
- }
62
- }
63
- /**
64
- * Save cache to disk
65
- */
66
- save() {
67
- if (!this.dirty) return;
68
- const dir = path.dirname(this.cachePath);
69
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
70
- const data = {};
71
- for (const [key, arr] of this.cache.entries()) {
72
- data[key] = Array.from(arr);
73
- }
74
- fs.writeFileSync(this.cachePath + ".json", JSON.stringify(data));
75
- this.dirty = false;
76
- }
77
- get(key) {
78
- return this.cache.get(key);
79
- }
80
- set(key, embedding) {
81
- this.cache.set(key, embedding);
82
- this.dirty = true;
83
- }
84
- has(key) {
85
- return this.cache.has(key);
86
- }
87
- entries() {
88
- return this.cache.entries();
89
- }
90
- get size() {
91
- return this.cache.size;
92
- }
93
- };
94
- function reciprocalRankFusion(list1, list2, k = 60) {
95
- const scores = /* @__PURE__ */ new Map();
96
- for (let rank = 0; rank < list1.length; rank++) {
97
- const { id } = list1[rank];
98
- scores.set(id, (scores.get(id) || 0) + 1 / (k + rank + 1));
99
- }
100
- for (let rank = 0; rank < list2.length; rank++) {
101
- const { id } = list2[rank];
102
- scores.set(id, (scores.get(id) || 0) + 1 / (k + rank + 1));
103
- }
104
- return Array.from(scores.entries()).map(([id, score]) => ({ id, score })).sort((a, b) => b.score - a.score);
105
- }
106
- async function semanticSearch(query, cache, topK = 20) {
107
- const queryEmb = await embed(query);
108
- const results = [];
109
- for (const [id, docEmb] of cache.entries()) {
110
- results.push({ id, score: cosineSimilarity(queryEmb, docEmb) });
111
- }
112
- results.sort((a, b) => b.score - a.score);
113
- return results.slice(0, topK);
114
- }
115
- async function hybridSearch(query, bm25Results, cache, options = {}) {
116
- const { topK = 20, rrfK = 60 } = options;
117
- const bm25Ranked = bm25Results.map((r) => ({ id: r.document.path || r.document.id, score: r.score }));
118
- const semanticRanked = await semanticSearch(query, cache, topK);
119
- const fused = reciprocalRankFusion(bm25Ranked, semanticRanked, rrfK);
120
- const bm25Map = new Map(bm25Results.map((r) => [r.document.path || r.document.id, r]));
121
- return fused.slice(0, topK).map(({ id, score }) => {
122
- const existing = bm25Map.get(id);
123
- if (existing) {
124
- return { ...existing, score };
125
- }
126
- const minimalDoc = {
127
- id: id.replace(/\.md$/, ""),
128
- path: id.endsWith(".md") ? id : id + ".md",
129
- title: (id.split("/").pop() || id).replace(/\.md$/, ""),
130
- content: "",
131
- category: id.split("/")[0] || "root",
132
- frontmatter: {},
133
- links: [],
134
- tags: [],
135
- modified: /* @__PURE__ */ new Date()
136
- };
137
- return {
138
- document: minimalDoc,
139
- score,
140
- snippet: "",
141
- matchedTerms: []
142
- };
143
- });
144
- }
145
-
146
- export {
147
- embed,
148
- embedBatch,
149
- cosineSimilarity,
150
- EmbeddingCache,
151
- reciprocalRankFusion,
152
- semanticSearch,
153
- hybridSearch
154
- };