clawvault 3.1.0 → 3.2.1
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.
- package/README.md +422 -141
- package/bin/clawvault.js +10 -2
- package/bin/command-registration.test.js +3 -1
- package/bin/command-runtime.js +9 -1
- package/bin/register-core-commands.js +23 -28
- package/bin/register-maintenance-commands.js +39 -3
- package/bin/register-query-commands.js +58 -29
- package/bin/register-tailscale-commands.js +106 -0
- package/bin/register-task-commands.js +18 -1
- package/bin/register-task-commands.test.js +16 -0
- package/bin/register-vault-operations-commands.js +29 -1
- package/bin/register-workgraph-commands.js +451 -0
- package/dashboard/lib/graph-diff.js +104 -0
- package/dashboard/lib/graph-diff.test.js +75 -0
- package/dashboard/lib/vault-parser.js +556 -0
- package/dashboard/lib/vault-parser.test.js +254 -0
- package/dashboard/public/app.js +796 -0
- package/dashboard/public/index.html +52 -0
- package/dashboard/public/styles.css +221 -0
- package/dashboard/server.js +374 -0
- package/dist/{chunk-C7OK5WKP.js → chunk-2JQ3O2YL.js} +4 -4
- package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
- package/dist/{chunk-F2JEUD4J.js → chunk-4ITRXIVT.js} +5 -7
- package/dist/{chunk-GUKMRGM7.js → chunk-4OXMU5S2.js} +1 -1
- package/dist/chunk-5PJ4STIC.js +465 -0
- package/dist/{chunk-62YTUT6J.js → chunk-AZYOKJYC.js} +2 -2
- package/dist/chunk-BSJ6RIT7.js +447 -0
- package/dist/chunk-ECRZL5XR.js +50 -0
- package/dist/chunk-ERNE2FZ5.js +189 -0
- package/dist/{chunk-WAZ3NLWL.js → chunk-F55HGNU4.js} +0 -47
- package/dist/{chunk-VGLOTGAS.js → chunk-FAKNOB7Y.js} +2 -2
- package/dist/{chunk-QK3UCXWL.js → chunk-FHFUXL6G.js} +2 -2
- package/dist/chunk-GNJL4YGR.js +79 -0
- package/dist/chunk-HR4KN6S2.js +152 -0
- package/dist/{chunk-OZ7RIXTO.js → chunk-IIOU45CK.js} +1 -1
- package/dist/chunk-IJBFGPCS.js +33 -0
- package/dist/chunk-IVRIKYFE.js +520 -0
- package/dist/chunk-K7PNYS45.js +93 -0
- package/dist/chunk-MDIH26GC.js +183 -0
- package/dist/{chunk-LYHGEHXG.js → chunk-MFAWT5O5.js} +0 -1
- package/dist/{chunk-H34S76MB.js → chunk-MNPUYCHQ.js} +6 -6
- package/dist/chunk-NTOPJI7W.js +207 -0
- package/dist/{chunk-QBLMXKF2.js → chunk-OIWVQYQF.js} +1 -1
- package/dist/chunk-PG56HX5T.js +154 -0
- package/dist/{chunk-LNJA2UGL.js → chunk-PI4WMLMG.js} +7 -84
- package/dist/chunk-QMHPQYUV.js +363 -0
- package/dist/{chunk-H62BP7RI.js → chunk-QPDDIHXE.js} +209 -43
- package/dist/{chunk-N2AXRYLC.js → chunk-QWQ3TIKS.js} +1 -1
- package/dist/{chunk-3DHXQHYG.js → chunk-R2MIW5G7.js} +1 -1
- package/dist/{chunk-SJSFRIYS.js → chunk-S5OJEGFG.js} +2 -2
- package/dist/chunk-SS4B7P7V.js +99 -0
- package/dist/chunk-TIGW564L.js +628 -0
- package/dist/chunk-U67V476Y.js +35 -0
- package/dist/{chunk-JY6FYXIT.js → chunk-UCQAOZHW.js} +6 -11
- package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
- package/dist/chunk-WIOLLGAD.js +190 -0
- package/dist/{chunk-3WRJEKN4.js → chunk-WJVWINEM.js} +72 -8
- package/dist/chunk-WMGIIABP.js +15 -0
- package/dist/{chunk-33UGEQRT.js → chunk-X3SPPUFG.js} +151 -64
- package/dist/{chunk-3NSBOUT3.js → chunk-Y3TIJEBP.js} +314 -79
- package/dist/chunk-Y6VJKXGL.js +373 -0
- package/dist/{chunk-LI4O6NVK.js → chunk-YDWHS4LJ.js} +49 -9
- package/dist/{chunk-U55BGUAU.js → chunk-YNIPYN4F.js} +5 -5
- package/dist/chunk-YXQCA6B7.js +226 -0
- package/dist/cli/index.js +26 -22
- package/dist/commands/archive.js +3 -3
- package/dist/commands/backlog.js +3 -3
- package/dist/commands/blocked.js +3 -3
- package/dist/commands/canvas.d.ts +15 -0
- package/dist/commands/canvas.js +200 -0
- package/dist/commands/checkpoint.js +2 -2
- package/dist/commands/compat.js +2 -2
- package/dist/commands/context.js +7 -5
- package/dist/commands/doctor.d.ts +11 -7
- package/dist/commands/doctor.js +16 -14
- package/dist/commands/embed.js +5 -6
- package/dist/commands/entities.js +2 -2
- package/dist/commands/graph.js +3 -3
- package/dist/commands/inject.d.ts +1 -1
- package/dist/commands/inject.js +4 -5
- package/dist/commands/kanban.js +4 -4
- package/dist/commands/link.js +2 -2
- package/dist/commands/migrate-observations.js +4 -4
- package/dist/commands/observe.d.ts +0 -1
- package/dist/commands/observe.js +13 -12
- package/dist/commands/project.js +5 -5
- package/dist/commands/rebuild-embeddings.d.ts +21 -0
- package/dist/commands/rebuild-embeddings.js +91 -0
- package/dist/commands/rebuild.js +12 -11
- package/dist/commands/recover.js +3 -3
- package/dist/commands/reflect.js +6 -7
- package/dist/commands/repair-session.js +1 -1
- package/dist/commands/replay.js +14 -14
- package/dist/commands/session-recap.js +1 -1
- package/dist/commands/setup.d.ts +2 -89
- package/dist/commands/setup.js +3 -21
- package/dist/commands/shell-init.js +1 -1
- package/dist/commands/sleep.d.ts +1 -1
- package/dist/commands/sleep.js +18 -17
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +40 -30
- package/dist/commands/sync-bd.d.ts +10 -0
- package/dist/commands/sync-bd.js +10 -0
- package/dist/commands/tailscale.d.ts +52 -0
- package/dist/commands/tailscale.js +26 -0
- package/dist/commands/task.js +4 -4
- package/dist/commands/template.js +2 -2
- package/dist/commands/wake.d.ts +1 -1
- package/dist/commands/wake.js +11 -10
- package/dist/index.d.ts +334 -191
- package/dist/index.js +432 -108
- package/dist/{inject-Bzi5E-By.d.ts → inject-DYUrDqQO.d.ts} +3 -3
- package/dist/ledger-B7g7jhqG.d.ts +44 -0
- package/dist/lib/auto-linker.js +1 -1
- package/dist/lib/canvas-layout.d.ts +115 -0
- package/dist/lib/canvas-layout.js +35 -0
- package/dist/lib/config.d.ts +27 -3
- package/dist/lib/config.js +4 -2
- package/dist/lib/entity-index.js +1 -1
- package/dist/lib/project-utils.js +4 -4
- package/dist/lib/session-repair.js +1 -1
- package/dist/lib/session-utils.js +1 -1
- package/dist/lib/tailscale.d.ts +225 -0
- package/dist/lib/tailscale.js +50 -0
- package/dist/lib/task-utils.js +3 -3
- package/dist/lib/template-engine.js +1 -1
- package/dist/lib/webdav.d.ts +109 -0
- package/dist/lib/webdav.js +35 -0
- package/dist/plugin/index.d.ts +344 -28
- package/dist/plugin/index.js +3919 -227
- package/dist/registry-BR4326o0.d.ts +30 -0
- package/dist/store-CA-6sKCJ.d.ts +34 -0
- package/dist/thread-B9LhXNU0.d.ts +41 -0
- package/dist/{types-Y2_Um2Ls.d.ts → types-BbWJoC1c.d.ts} +1 -44
- package/dist/workgraph/index.d.ts +5 -0
- package/dist/workgraph/index.js +23 -0
- package/dist/workgraph/ledger.d.ts +2 -0
- package/dist/workgraph/ledger.js +25 -0
- package/dist/workgraph/registry.d.ts +2 -0
- package/dist/workgraph/registry.js +19 -0
- package/dist/workgraph/store.d.ts +2 -0
- package/dist/workgraph/store.js +25 -0
- package/dist/workgraph/thread.d.ts +2 -0
- package/dist/workgraph/thread.js +25 -0
- package/dist/workgraph/types.d.ts +54 -0
- package/dist/workgraph/types.js +7 -0
- package/hooks/clawvault/HOOK.md +113 -0
- package/hooks/clawvault/handler.js +1559 -0
- package/hooks/clawvault/handler.test.js +510 -0
- package/hooks/clawvault/openclaw.plugin.json +72 -0
- package/openclaw.plugin.json +235 -30
- package/package.json +20 -20
- package/dist/chunk-3RG5ZIWI.js +0 -10
- package/dist/chunk-3ZIH425O.js +0 -871
- package/dist/chunk-6U6MK36V.js +0 -205
- package/dist/chunk-CMB7UL7C.js +0 -327
- package/dist/chunk-D2H45LON.js +0 -1074
- package/dist/chunk-E7MFQB6D.js +0 -163
- package/dist/chunk-GQSLDZTS.js +0 -560
- package/dist/chunk-MFM6K7PU.js +0 -374
- package/dist/chunk-MXSSG3QU.js +0 -42
- package/dist/chunk-OCGVIN3L.js +0 -88
- package/dist/chunk-PAH27GSN.js +0 -108
- package/dist/chunk-YCUNCH2I.js +0 -78
- package/dist/cli/index.cjs +0 -8584
- package/dist/cli/index.d.cts +0 -5
- package/dist/commands/archive.cjs +0 -287
- package/dist/commands/archive.d.cts +0 -11
- package/dist/commands/backlog.cjs +0 -721
- package/dist/commands/backlog.d.cts +0 -53
- package/dist/commands/blocked.cjs +0 -204
- package/dist/commands/blocked.d.cts +0 -26
- package/dist/commands/checkpoint.cjs +0 -244
- package/dist/commands/checkpoint.d.cts +0 -41
- package/dist/commands/compat.cjs +0 -294
- package/dist/commands/compat.d.cts +0 -28
- package/dist/commands/context.cjs +0 -2990
- package/dist/commands/context.d.cts +0 -2
- package/dist/commands/doctor.cjs +0 -2986
- package/dist/commands/doctor.d.cts +0 -21
- package/dist/commands/embed.cjs +0 -232
- package/dist/commands/embed.d.cts +0 -17
- package/dist/commands/entities.cjs +0 -141
- package/dist/commands/entities.d.cts +0 -7
- package/dist/commands/graph.cjs +0 -501
- package/dist/commands/graph.d.cts +0 -21
- package/dist/commands/inject.cjs +0 -1636
- package/dist/commands/inject.d.cts +0 -2
- package/dist/commands/kanban.cjs +0 -884
- package/dist/commands/kanban.d.cts +0 -63
- package/dist/commands/link.cjs +0 -965
- package/dist/commands/link.d.cts +0 -11
- package/dist/commands/migrate-observations.cjs +0 -362
- package/dist/commands/migrate-observations.d.cts +0 -19
- package/dist/commands/observe.cjs +0 -4099
- package/dist/commands/observe.d.cts +0 -23
- package/dist/commands/project.cjs +0 -1341
- package/dist/commands/project.d.cts +0 -85
- package/dist/commands/rebuild.cjs +0 -3136
- package/dist/commands/rebuild.d.cts +0 -11
- package/dist/commands/recover.cjs +0 -361
- package/dist/commands/recover.d.cts +0 -38
- package/dist/commands/reflect.cjs +0 -1008
- package/dist/commands/reflect.d.cts +0 -11
- package/dist/commands/repair-session.cjs +0 -457
- package/dist/commands/repair-session.d.cts +0 -38
- package/dist/commands/replay.cjs +0 -4103
- package/dist/commands/replay.d.cts +0 -16
- package/dist/commands/session-recap.cjs +0 -353
- package/dist/commands/session-recap.d.cts +0 -27
- package/dist/commands/setup.cjs +0 -1278
- package/dist/commands/setup.d.cts +0 -99
- package/dist/commands/shell-init.cjs +0 -75
- package/dist/commands/shell-init.d.cts +0 -7
- package/dist/commands/sleep.cjs +0 -6029
- package/dist/commands/sleep.d.cts +0 -36
- package/dist/commands/status.cjs +0 -2737
- package/dist/commands/status.d.cts +0 -52
- package/dist/commands/task.cjs +0 -1236
- package/dist/commands/task.d.cts +0 -97
- package/dist/commands/template.cjs +0 -457
- package/dist/commands/template.d.cts +0 -36
- package/dist/commands/wake.cjs +0 -2627
- package/dist/commands/wake.d.cts +0 -22
- package/dist/context-BUGaWpyL.d.cts +0 -46
- package/dist/index.cjs +0 -12373
- package/dist/index.d.cts +0 -854
- package/dist/inject-Bzi5E-By.d.cts +0 -137
- package/dist/lib/auto-linker.cjs +0 -176
- package/dist/lib/auto-linker.d.cts +0 -26
- package/dist/lib/config.cjs +0 -78
- package/dist/lib/config.d.cts +0 -11
- package/dist/lib/entity-index.cjs +0 -84
- package/dist/lib/entity-index.d.cts +0 -26
- package/dist/lib/project-utils.cjs +0 -864
- package/dist/lib/project-utils.d.cts +0 -97
- package/dist/lib/session-repair.cjs +0 -239
- package/dist/lib/session-repair.d.cts +0 -110
- package/dist/lib/session-utils.cjs +0 -209
- package/dist/lib/session-utils.d.cts +0 -63
- package/dist/lib/task-utils.cjs +0 -1137
- package/dist/lib/task-utils.d.cts +0 -208
- package/dist/lib/template-engine.cjs +0 -47
- package/dist/lib/template-engine.d.cts +0 -11
- package/dist/plugin/index.cjs +0 -1907
- package/dist/plugin/index.d.cts +0 -36
- package/dist/plugin/inject.cjs +0 -356
- package/dist/plugin/inject.d.cts +0 -54
- package/dist/plugin/inject.d.ts +0 -54
- package/dist/plugin/inject.js +0 -17
- package/dist/plugin/observe.cjs +0 -631
- package/dist/plugin/observe.d.cts +0 -39
- package/dist/plugin/observe.d.ts +0 -39
- package/dist/plugin/observe.js +0 -18
- package/dist/plugin/templates.cjs +0 -593
- package/dist/plugin/templates.d.cts +0 -52
- package/dist/plugin/templates.d.ts +0 -52
- package/dist/plugin/templates.js +0 -25
- package/dist/plugin/types.cjs +0 -18
- package/dist/plugin/types.d.cts +0 -209
- package/dist/plugin/types.d.ts +0 -209
- package/dist/plugin/types.js +0 -0
- package/dist/plugin/vault.cjs +0 -927
- package/dist/plugin/vault.d.cts +0 -68
- package/dist/plugin/vault.d.ts +0 -68
- package/dist/plugin/vault.js +0 -22
- package/dist/types-Y2_Um2Ls.d.cts +0 -205
- package/templates/memory-event.md +0 -67
- package/templates/party.md +0 -63
- package/templates/primitive-registry.yaml +0 -551
- package/templates/run.md +0 -68
- package/templates/trigger.md +0 -68
- package/templates/workspace.md +0 -50
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Observer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-Y3TIJEBP.js";
|
|
4
4
|
import {
|
|
5
5
|
getSessionsDir
|
|
6
6
|
} from "./chunk-HRLWZGMA.js";
|
|
@@ -18,11 +18,6 @@ var AGENT_ID_RE = /^[a-zA-Z0-9_-]{1,100}$/;
|
|
|
18
18
|
var SESSION_ID_RE = /^[a-zA-Z0-9._-]{1,200}$/;
|
|
19
19
|
var CURSOR_FILE_NAME = "observe-cursors.json";
|
|
20
20
|
var STALE_CURSOR_THRESHOLD_MS = 12 * 60 * 60 * 1e3;
|
|
21
|
-
function formatBytes(bytes) {
|
|
22
|
-
if (bytes >= ONE_MIB) return `${(bytes / ONE_MIB).toFixed(1)}MB`;
|
|
23
|
-
if (bytes >= ONE_KIB) return `${Math.round(bytes / ONE_KIB)}KB`;
|
|
24
|
-
return `${bytes}B`;
|
|
25
|
-
}
|
|
26
21
|
function isFiniteNonNegative(value) {
|
|
27
22
|
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
28
23
|
}
|
|
@@ -158,12 +153,7 @@ function getObserverStaleness(vaultPath, options = {}) {
|
|
|
158
153
|
if (!sessionStat.isFile()) {
|
|
159
154
|
continue;
|
|
160
155
|
}
|
|
161
|
-
|
|
162
|
-
if (newBytes <= 0) {
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
const processThreshold = getScaledObservationThresholdBytes(sessionStat.size);
|
|
166
|
-
if (newBytes < processThreshold) {
|
|
156
|
+
if (cursor.lastFileSize >= sessionStat.size) {
|
|
167
157
|
continue;
|
|
168
158
|
}
|
|
169
159
|
staleCount += 1;
|
|
@@ -191,32 +181,8 @@ function loadSessionIndex(sessionsDir) {
|
|
|
191
181
|
return {};
|
|
192
182
|
}
|
|
193
183
|
}
|
|
194
|
-
function findMostRecentResetFile(sessionsDir, sessionId) {
|
|
195
|
-
const prefix = `${sessionId}.jsonl.reset.`;
|
|
196
|
-
try {
|
|
197
|
-
const files = fs.readdirSync(sessionsDir).filter((f) => f.startsWith(prefix)).sort().reverse();
|
|
198
|
-
return files.length > 0 ? path.join(sessionsDir, files[0]) : null;
|
|
199
|
-
} catch {
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
184
|
function resolveTranscriptPath(sessionsDir, sessionId) {
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
const stat = fs.statSync(mainPath);
|
|
207
|
-
if (stat.size < 100) {
|
|
208
|
-
const resetFile = findMostRecentResetFile(sessionsDir, sessionId);
|
|
209
|
-
if (resetFile) {
|
|
210
|
-
return resetFile;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
} catch {
|
|
214
|
-
const resetFile = findMostRecentResetFile(sessionsDir, sessionId);
|
|
215
|
-
if (resetFile) {
|
|
216
|
-
return resetFile;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return mainPath;
|
|
185
|
+
return path.join(sessionsDir, `${sessionId}.jsonl`);
|
|
220
186
|
}
|
|
221
187
|
function discoverSessionDescriptors(sessionsDir, fallbackAgentId) {
|
|
222
188
|
const descriptors = [];
|
|
@@ -293,21 +259,6 @@ function normalizeRole(role) {
|
|
|
293
259
|
}
|
|
294
260
|
return role.trim().toLowerCase();
|
|
295
261
|
}
|
|
296
|
-
function summarizeContentArray(content) {
|
|
297
|
-
const parts = [];
|
|
298
|
-
for (const block of content) {
|
|
299
|
-
if (!block || typeof block !== "object") continue;
|
|
300
|
-
const b = block;
|
|
301
|
-
if (b.type === "text" && typeof b.text === "string") {
|
|
302
|
-
const text = normalizeWhitespace(b.text);
|
|
303
|
-
if (text) parts.push(text);
|
|
304
|
-
} else if (b.type === "toolCall") {
|
|
305
|
-
const toolName = typeof b.name === "string" ? b.name : "tool";
|
|
306
|
-
parts.push(`[tool: ${toolName}]`);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return parts.join(" ");
|
|
310
|
-
}
|
|
311
262
|
function parseOpenClawJsonLine(line) {
|
|
312
263
|
if (!line.trim()) {
|
|
313
264
|
return "";
|
|
@@ -324,38 +275,14 @@ function parseOpenClawJsonLine(line) {
|
|
|
324
275
|
const entry = parsed;
|
|
325
276
|
if ("role" in entry && "content" in entry) {
|
|
326
277
|
const role = normalizeRole(entry.role);
|
|
327
|
-
|
|
328
|
-
if (role === "toolresult") {
|
|
329
|
-
const output = extractContentText(entry.content);
|
|
330
|
-
const preview = output.slice(0, 80) || "ok";
|
|
331
|
-
return `[tool_result \u2192 ${preview}]`;
|
|
332
|
-
}
|
|
333
|
-
const raw = entry.content;
|
|
334
|
-
let content;
|
|
335
|
-
if (Array.isArray(raw)) {
|
|
336
|
-
content = summarizeContentArray(raw);
|
|
337
|
-
} else {
|
|
338
|
-
content = extractContentText(raw);
|
|
339
|
-
}
|
|
278
|
+
const content = extractContentText(entry.content);
|
|
340
279
|
if (!content) return "";
|
|
341
280
|
return role ? `${role}: ${content}` : content;
|
|
342
281
|
}
|
|
343
282
|
if (entry.type === "message" && entry.message && typeof entry.message === "object") {
|
|
344
283
|
const message = entry.message;
|
|
345
284
|
const role = normalizeRole(message.role);
|
|
346
|
-
|
|
347
|
-
if (role === "toolresult") {
|
|
348
|
-
const output = extractContentText(message.content);
|
|
349
|
-
const preview = output.slice(0, 80) || "ok";
|
|
350
|
-
return `[tool_result \u2192 ${preview}]`;
|
|
351
|
-
}
|
|
352
|
-
const raw = message.content;
|
|
353
|
-
let content;
|
|
354
|
-
if (Array.isArray(raw)) {
|
|
355
|
-
content = summarizeContentArray(raw);
|
|
356
|
-
} else {
|
|
357
|
-
content = extractContentText(raw);
|
|
358
|
-
}
|
|
285
|
+
const content = extractContentText(message.content);
|
|
359
286
|
if (!content) return "";
|
|
360
287
|
return role ? `${role}: ${content}` : content;
|
|
361
288
|
}
|
|
@@ -518,9 +445,7 @@ async function observeActiveSessions(options, dependencies = {}) {
|
|
|
518
445
|
const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
|
|
519
446
|
const cursors = loadObserveCursorStore(vaultPath);
|
|
520
447
|
const descriptors = discoverSessionDescriptors(sessionsDir, agentId);
|
|
521
|
-
const
|
|
522
|
-
allCandidates.sort((a, b) => b.newBytes - a.newBytes);
|
|
523
|
-
const candidates = options.maxSessions != null && options.maxSessions > 0 ? allCandidates.slice(0, options.maxSessions) : allCandidates;
|
|
448
|
+
const candidates = selectCandidates(descriptors, cursors, options.minNewBytes);
|
|
524
449
|
if (dryRun || candidates.length === 0) {
|
|
525
450
|
return {
|
|
526
451
|
agentId,
|
|
@@ -550,9 +475,7 @@ async function observeActiveSessions(options, dependencies = {}) {
|
|
|
550
475
|
let observedNewBytes = 0;
|
|
551
476
|
const routedCounts = {};
|
|
552
477
|
const failedSessions = [];
|
|
553
|
-
for (
|
|
554
|
-
const candidate = candidates[i];
|
|
555
|
-
console.log(`[observer] processing session ${i + 1}/${candidates.length}: ${candidate.sessionKey} (${formatBytes(candidate.newBytes)} new)`);
|
|
478
|
+
for (const candidate of candidates) {
|
|
556
479
|
try {
|
|
557
480
|
const observer = observerFactory(vaultPath, observerOptions);
|
|
558
481
|
const { messages, nextOffset } = await readIncrementalMessages(candidate.filePath, candidate.startOffset);
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasQmd,
|
|
3
|
+
withQmdIndexArgs
|
|
4
|
+
} from "./chunk-5PJ4STIC.js";
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_CATEGORIES
|
|
7
|
+
} from "./chunk-2CDEETQN.js";
|
|
8
|
+
|
|
9
|
+
// src/commands/setup.ts
|
|
10
|
+
import * as fs from "fs";
|
|
11
|
+
import * as os from "os";
|
|
12
|
+
import * as path from "path";
|
|
13
|
+
import { execFileSync } from "child_process";
|
|
14
|
+
var CONFIG_FILE = ".clawvault.json";
|
|
15
|
+
function resolveVaultTarget(vaultOverride) {
|
|
16
|
+
if (vaultOverride) {
|
|
17
|
+
const vaultPath = path.resolve(vaultOverride);
|
|
18
|
+
return { vaultPath, source: "--vault flag", existed: fs.existsSync(vaultPath) };
|
|
19
|
+
}
|
|
20
|
+
const envPath = process.env.CLAWVAULT_PATH?.trim();
|
|
21
|
+
const home = os.homedir();
|
|
22
|
+
if (envPath) {
|
|
23
|
+
const vaultPath = path.resolve(envPath);
|
|
24
|
+
return { vaultPath, source: "CLAWVAULT_PATH", existed: fs.existsSync(vaultPath) };
|
|
25
|
+
}
|
|
26
|
+
const candidates = [
|
|
27
|
+
{ vaultPath: path.join(home, ".openclaw", "workspace", "memory"), source: "OpenClaw default" },
|
|
28
|
+
{ vaultPath: path.resolve(process.cwd(), "memory"), source: "./memory" },
|
|
29
|
+
{ vaultPath: path.join(home, "memory"), source: "~/memory" }
|
|
30
|
+
];
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
if (fs.existsSync(candidate.vaultPath)) {
|
|
33
|
+
return { ...candidate, existed: true };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const fallback = candidates[0];
|
|
37
|
+
return { ...fallback, existed: false };
|
|
38
|
+
}
|
|
39
|
+
function ensureVaultStructure(vaultPath) {
|
|
40
|
+
fs.mkdirSync(vaultPath, { recursive: true });
|
|
41
|
+
for (const category of DEFAULT_CATEGORIES) {
|
|
42
|
+
fs.mkdirSync(path.join(vaultPath, category), { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
const configPath = path.join(vaultPath, CONFIG_FILE);
|
|
45
|
+
if (fs.existsSync(configPath)) return false;
|
|
46
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
47
|
+
const name = path.basename(vaultPath);
|
|
48
|
+
const meta = {
|
|
49
|
+
name,
|
|
50
|
+
version: "1.0.0",
|
|
51
|
+
created: now,
|
|
52
|
+
lastUpdated: now,
|
|
53
|
+
categories: DEFAULT_CATEGORIES,
|
|
54
|
+
documentCount: 0,
|
|
55
|
+
qmdCollection: name,
|
|
56
|
+
qmdRoot: vaultPath
|
|
57
|
+
};
|
|
58
|
+
fs.writeFileSync(configPath, JSON.stringify(meta, null, 2));
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
function writeBases(vaultPath, force) {
|
|
62
|
+
const basesFiles = {
|
|
63
|
+
"all-tasks.base": `filters:
|
|
64
|
+
and:
|
|
65
|
+
- file.inFolder("tasks")
|
|
66
|
+
- status != "done"
|
|
67
|
+
formulas:
|
|
68
|
+
age: (now() - file.ctime).days
|
|
69
|
+
status_icon: if(status == "blocked", "\u{1F534}", if(status == "in-progress", "\u{1F528}", if(status == "open", "\u26AA", "\u2705")))
|
|
70
|
+
views:
|
|
71
|
+
- type: table
|
|
72
|
+
name: All Active Tasks
|
|
73
|
+
groupBy:
|
|
74
|
+
property: status
|
|
75
|
+
direction: ASC
|
|
76
|
+
order:
|
|
77
|
+
- formula.status_icon
|
|
78
|
+
- file.name
|
|
79
|
+
- status
|
|
80
|
+
- owner
|
|
81
|
+
- project
|
|
82
|
+
- priority
|
|
83
|
+
- blocked_by
|
|
84
|
+
- formula.age
|
|
85
|
+
- type: cards
|
|
86
|
+
name: Task Board
|
|
87
|
+
groupBy:
|
|
88
|
+
property: status
|
|
89
|
+
direction: ASC
|
|
90
|
+
order:
|
|
91
|
+
- file.name
|
|
92
|
+
- owner
|
|
93
|
+
- project
|
|
94
|
+
- priority`,
|
|
95
|
+
"blocked.base": `filters:
|
|
96
|
+
and:
|
|
97
|
+
- file.inFolder("tasks")
|
|
98
|
+
- status == "blocked"
|
|
99
|
+
formulas:
|
|
100
|
+
days_blocked: (now() - file.ctime).days
|
|
101
|
+
views:
|
|
102
|
+
- type: table
|
|
103
|
+
name: Blocked Tasks
|
|
104
|
+
order:
|
|
105
|
+
- file.name
|
|
106
|
+
- owner
|
|
107
|
+
- project
|
|
108
|
+
- blocked_by
|
|
109
|
+
- formula.days_blocked
|
|
110
|
+
- priority`,
|
|
111
|
+
"by-project.base": `filters:
|
|
112
|
+
and:
|
|
113
|
+
- file.inFolder("tasks")
|
|
114
|
+
- status != "done"
|
|
115
|
+
formulas:
|
|
116
|
+
status_icon: if(status == "blocked", "\u{1F534}", if(status == "in-progress", "\u{1F528}", "\u26AA"))
|
|
117
|
+
views:
|
|
118
|
+
- type: table
|
|
119
|
+
name: By Project
|
|
120
|
+
groupBy:
|
|
121
|
+
property: project
|
|
122
|
+
direction: ASC
|
|
123
|
+
order:
|
|
124
|
+
- formula.status_icon
|
|
125
|
+
- file.name
|
|
126
|
+
- status
|
|
127
|
+
- owner
|
|
128
|
+
- priority
|
|
129
|
+
- type: cards
|
|
130
|
+
name: Project Cards
|
|
131
|
+
groupBy:
|
|
132
|
+
property: project
|
|
133
|
+
direction: ASC
|
|
134
|
+
order:
|
|
135
|
+
- file.name
|
|
136
|
+
- owner
|
|
137
|
+
- status`,
|
|
138
|
+
"by-owner.base": `filters:
|
|
139
|
+
and:
|
|
140
|
+
- file.inFolder("tasks")
|
|
141
|
+
- status != "done"
|
|
142
|
+
views:
|
|
143
|
+
- type: table
|
|
144
|
+
name: By Owner
|
|
145
|
+
groupBy:
|
|
146
|
+
property: owner
|
|
147
|
+
direction: ASC
|
|
148
|
+
order:
|
|
149
|
+
- file.name
|
|
150
|
+
- status
|
|
151
|
+
- project
|
|
152
|
+
- priority`,
|
|
153
|
+
"backlog.base": `filters:
|
|
154
|
+
and:
|
|
155
|
+
- file.inFolder("backlog")
|
|
156
|
+
views:
|
|
157
|
+
- type: table
|
|
158
|
+
name: Backlog
|
|
159
|
+
order:
|
|
160
|
+
- file.name
|
|
161
|
+
- source
|
|
162
|
+
- project
|
|
163
|
+
- file.ctime`
|
|
164
|
+
};
|
|
165
|
+
let written = 0;
|
|
166
|
+
for (const [filename, content] of Object.entries(basesFiles)) {
|
|
167
|
+
const filePath = path.join(vaultPath, filename);
|
|
168
|
+
if (force || !fs.existsSync(filePath)) {
|
|
169
|
+
fs.writeFileSync(filePath, content);
|
|
170
|
+
written++;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return written;
|
|
174
|
+
}
|
|
175
|
+
var NEURAL_GRAPH_CSS = `/* ClawVault Graph Colors \u2014 Neural Neural Style */
|
|
176
|
+
/* Auto-generated by \`clawvault setup --theme neural\` */
|
|
177
|
+
|
|
178
|
+
body.theme-dark .graph-view .graph-view-container { background-color: #0a0a0a; }
|
|
179
|
+
|
|
180
|
+
body.theme-dark .graph-view .node.tag-person circle { fill: #00b4d8 !important; }
|
|
181
|
+
body.theme-dark .graph-view .node.tag-project circle { fill: #2d6a4f !important; }
|
|
182
|
+
body.theme-dark .graph-view .node.tag-decision circle { fill: #e8590c !important; }
|
|
183
|
+
body.theme-dark .graph-view .node.tag-lesson circle { fill: #fcc419 !important; }
|
|
184
|
+
body.theme-dark .graph-view .node.tag-commitment circle { fill: #e03131 !important; }
|
|
185
|
+
body.theme-dark .graph-view .node.tag-task circle { fill: #22b8cf !important; }
|
|
186
|
+
body.theme-dark .graph-view .node.tag-observation circle { fill: #7950f2 !important; }
|
|
187
|
+
body.theme-dark .graph-view .node.tag-handoff circle { fill: #845ef7 !important; }
|
|
188
|
+
body.theme-dark .graph-view .node.tag-daily circle { fill: #495057 !important; }
|
|
189
|
+
|
|
190
|
+
body.theme-dark .graph-view .node.is-focused circle {
|
|
191
|
+
fill: #e8a430 !important; stroke: #e8a430 !important;
|
|
192
|
+
stroke-width: 3px; filter: drop-shadow(0 0 6px #e8a430);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
body.theme-dark .graph-view .link { stroke: rgba(45, 200, 120, 0.15) !important; }
|
|
196
|
+
body.theme-dark .graph-view .link.is-focused { stroke: rgba(45, 200, 120, 0.6) !important; }
|
|
197
|
+
body.theme-dark .graph-view .node text { fill: #c1c2c5 !important; font-size: 0.8em; }
|
|
198
|
+
`;
|
|
199
|
+
var MINIMAL_GRAPH_CSS = `/* ClawVault Graph Colors \u2014 Minimal */
|
|
200
|
+
/* Auto-generated by \`clawvault setup --theme minimal\` */
|
|
201
|
+
|
|
202
|
+
body.theme-dark .graph-view .node.tag-person circle { fill: #4a90e8 !important; }
|
|
203
|
+
body.theme-dark .graph-view .node.tag-project circle { fill: #4ae85d !important; }
|
|
204
|
+
body.theme-dark .graph-view .node.tag-decision circle { fill: #e85d4a !important; }
|
|
205
|
+
body.theme-dark .graph-view .node.tag-lesson circle { fill: #9b59b6 !important; }
|
|
206
|
+
body.theme-dark .graph-view .node.tag-task circle { fill: #e8a430 !important; }
|
|
207
|
+
`;
|
|
208
|
+
var NEURAL_COLOR_GROUPS = [
|
|
209
|
+
{ query: "path:people", color: { a: 1, rgb: 47316 } },
|
|
210
|
+
{ query: "path:projects", color: { a: 1, rgb: 2976335 } },
|
|
211
|
+
{ query: "path:decisions", color: { a: 1, rgb: 15227916 } },
|
|
212
|
+
{ query: "path:lessons", color: { a: 1, rgb: 16565273 } },
|
|
213
|
+
{ query: "path:tasks", color: { a: 1, rgb: 2275535 } },
|
|
214
|
+
{ query: "path:commitments", color: { a: 1, rgb: 14680369 } },
|
|
215
|
+
{ query: "path:backlog", color: { a: 1, rgb: 9806262 } },
|
|
216
|
+
{ query: "path:inbox", color: { a: 1, rgb: 15964178 } },
|
|
217
|
+
{ query: "path:handoffs", color: { a: 1, rgb: 8675063 } },
|
|
218
|
+
{ query: "path:ledger", color: { a: 1, rgb: 7950066 } }
|
|
219
|
+
];
|
|
220
|
+
var MINIMAL_COLOR_GROUPS = [
|
|
221
|
+
{ query: "path:people", color: { a: 1, rgb: 4886760 } },
|
|
222
|
+
{ query: "path:projects", color: { a: 1, rgb: 4909149 } },
|
|
223
|
+
{ query: "path:decisions", color: { a: 1, rgb: 15228234 } },
|
|
224
|
+
{ query: "path:lessons", color: { a: 1, rgb: 10181046 } },
|
|
225
|
+
{ query: "path:tasks", color: { a: 1, rgb: 15246384 } }
|
|
226
|
+
];
|
|
227
|
+
function writeGraphColors(vaultPath, theme, force) {
|
|
228
|
+
const obsidianDir = path.join(vaultPath, ".obsidian");
|
|
229
|
+
if (!fs.existsSync(obsidianDir)) {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
const snippetsDir = path.join(obsidianDir, "snippets");
|
|
233
|
+
fs.mkdirSync(snippetsDir, { recursive: true });
|
|
234
|
+
const snippetName = "clawvault-graph";
|
|
235
|
+
const snippetPath = path.join(snippetsDir, `${snippetName}.css`);
|
|
236
|
+
if (!force && fs.existsSync(snippetPath)) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
const css = theme === "neural" ? NEURAL_GRAPH_CSS : MINIMAL_GRAPH_CSS;
|
|
240
|
+
fs.writeFileSync(snippetPath, css);
|
|
241
|
+
const appearancePath = path.join(obsidianDir, "appearance.json");
|
|
242
|
+
let appearance = {};
|
|
243
|
+
if (fs.existsSync(appearancePath)) {
|
|
244
|
+
try {
|
|
245
|
+
appearance = JSON.parse(fs.readFileSync(appearancePath, "utf-8"));
|
|
246
|
+
} catch {
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
const snippets = appearance.enabledCssSnippets || [];
|
|
250
|
+
if (!snippets.includes(snippetName)) {
|
|
251
|
+
snippets.push(snippetName);
|
|
252
|
+
appearance.enabledCssSnippets = snippets;
|
|
253
|
+
fs.writeFileSync(appearancePath, JSON.stringify(appearance, null, 2));
|
|
254
|
+
}
|
|
255
|
+
const graphPath = path.join(obsidianDir, "graph.json");
|
|
256
|
+
let graphConfig = {};
|
|
257
|
+
if (fs.existsSync(graphPath)) {
|
|
258
|
+
try {
|
|
259
|
+
graphConfig = JSON.parse(fs.readFileSync(graphPath, "utf-8"));
|
|
260
|
+
} catch {
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
graphConfig.colorGroups = theme === "neural" ? NEURAL_COLOR_GROUPS : MINIMAL_COLOR_GROUPS;
|
|
264
|
+
if (theme === "neural") {
|
|
265
|
+
graphConfig.showTags = false;
|
|
266
|
+
graphConfig.showAttachments = false;
|
|
267
|
+
graphConfig.nodeSizeMultiplier = 1.2;
|
|
268
|
+
graphConfig.lineSizeMultiplier = 0.8;
|
|
269
|
+
graphConfig.textFadeMultiplier = 0;
|
|
270
|
+
graphConfig.repelStrength = 10;
|
|
271
|
+
graphConfig.linkDistance = 250;
|
|
272
|
+
graphConfig.centerStrength = 0.5;
|
|
273
|
+
}
|
|
274
|
+
fs.writeFileSync(graphPath, JSON.stringify(graphConfig, null, 2));
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
function getQmdConfig(vaultPath) {
|
|
278
|
+
const configPath = path.join(vaultPath, CONFIG_FILE);
|
|
279
|
+
if (fs.existsSync(configPath)) {
|
|
280
|
+
try {
|
|
281
|
+
const meta = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
282
|
+
return {
|
|
283
|
+
collection: meta.qmdCollection || meta.name || path.basename(vaultPath),
|
|
284
|
+
root: meta.qmdRoot || vaultPath
|
|
285
|
+
};
|
|
286
|
+
} catch {
|
|
287
|
+
return { collection: path.basename(vaultPath), root: vaultPath };
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return { collection: path.basename(vaultPath), root: vaultPath };
|
|
291
|
+
}
|
|
292
|
+
async function setupCommand(options = {}) {
|
|
293
|
+
const target = resolveVaultTarget(options.vault);
|
|
294
|
+
if (target.existed && !fs.statSync(target.vaultPath).isDirectory()) {
|
|
295
|
+
throw new Error(`Vault path is not a directory: ${target.vaultPath}`);
|
|
296
|
+
}
|
|
297
|
+
if (!target.existed) fs.mkdirSync(target.vaultPath, { recursive: true });
|
|
298
|
+
console.log(`${target.existed ? "Found" : "Created"} vault path (${target.source}): ${target.vaultPath}`);
|
|
299
|
+
const initialized = ensureVaultStructure(target.vaultPath);
|
|
300
|
+
console.log(initialized ? "\u2713 Initialized vault structure." : "\u2713 Vault structure already present.");
|
|
301
|
+
const force = options.force ?? false;
|
|
302
|
+
const theme = options.theme ?? "neural";
|
|
303
|
+
const explicitFlags = options.graphColors !== void 0 || options.bases !== void 0 || options.canvas !== void 0;
|
|
304
|
+
const doGraphColors = explicitFlags ? options.graphColors !== false : true;
|
|
305
|
+
const doBases = explicitFlags ? options.bases !== false : true;
|
|
306
|
+
const doCanvas = explicitFlags ? options.canvas !== void 0 && options.canvas !== false : false;
|
|
307
|
+
if (doGraphColors && theme !== "none") {
|
|
308
|
+
const wrote = writeGraphColors(target.vaultPath, theme, force);
|
|
309
|
+
if (wrote) {
|
|
310
|
+
console.log(`\u2713 Graph colors configured (${theme} theme)`);
|
|
311
|
+
} else {
|
|
312
|
+
const obsidianDir = path.join(target.vaultPath, ".obsidian");
|
|
313
|
+
if (!fs.existsSync(obsidianDir)) {
|
|
314
|
+
console.log("\u2298 No .obsidian directory \u2014 skipping graph colors (not an Obsidian vault)");
|
|
315
|
+
} else {
|
|
316
|
+
console.log("\u2298 Graph colors already exist (use --force to overwrite)");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
} else if (doGraphColors && theme === "none") {
|
|
320
|
+
console.log("\u2298 Graph colors skipped (--theme none)");
|
|
321
|
+
}
|
|
322
|
+
if (doBases) {
|
|
323
|
+
const count = writeBases(target.vaultPath, force);
|
|
324
|
+
if (count > 0) {
|
|
325
|
+
console.log(`\u2713 Created ${count} Obsidian Bases view${count > 1 ? "s" : ""}`);
|
|
326
|
+
} else {
|
|
327
|
+
console.log("\u2298 Bases views already exist (use --force to overwrite)");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
if (doCanvas) {
|
|
331
|
+
try {
|
|
332
|
+
const { canvasCommand } = await import("./commands/canvas.js");
|
|
333
|
+
await canvasCommand(target.vaultPath);
|
|
334
|
+
} catch (err) {
|
|
335
|
+
console.log(`\u26A0 Canvas generation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (hasQmd()) {
|
|
339
|
+
const { collection, root } = getQmdConfig(target.vaultPath);
|
|
340
|
+
try {
|
|
341
|
+
execFileSync("qmd", withQmdIndexArgs(["collection", "add", root, "--name", collection, "--mask", "**/*.md"], options.qmdIndexName), {
|
|
342
|
+
stdio: "ignore"
|
|
343
|
+
});
|
|
344
|
+
console.log(`\u2713 qmd collection ready: ${collection}`);
|
|
345
|
+
} catch {
|
|
346
|
+
console.log("\u2298 qmd collection already exists.");
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
console.log("\u2298 qmd not found \u2014 skipping semantic search setup.");
|
|
350
|
+
}
|
|
351
|
+
console.log("\nTip: add this to your shell config:");
|
|
352
|
+
console.log(` export CLAWVAULT_PATH="${target.vaultPath}"`);
|
|
353
|
+
console.log("\nCustomize further:");
|
|
354
|
+
console.log(" clawvault setup --theme neural # Neural neural graph colors");
|
|
355
|
+
console.log(" clawvault setup --theme minimal # Subtle category colors");
|
|
356
|
+
console.log(" clawvault setup --canvas # Generate vault status canvas");
|
|
357
|
+
console.log(" clawvault setup --no-bases --no-graph-colors # Structure only");
|
|
358
|
+
console.log(" clawvault setup --force # Overwrite existing configs");
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export {
|
|
362
|
+
setupCommand
|
|
363
|
+
};
|