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.
- package/README.md +56 -16
- package/bin/clawvault.js +0 -2
- package/bin/command-registration.test.js +15 -2
- package/bin/help-contract.test.js +16 -0
- package/bin/register-core-commands.js +88 -0
- package/bin/register-core-commands.test.js +80 -0
- package/bin/register-maintenance-commands.js +84 -7
- package/bin/register-query-commands.js +45 -28
- package/bin/register-query-commands.test.js +15 -0
- package/bin/test-helpers/cli-command-fixtures.js +1 -0
- package/dist/chunk-2PKBIKDH.js +130 -0
- package/dist/{chunk-U67V476Y.js → chunk-2ZDO52B4.js} +18 -1
- package/dist/{chunk-ZZA73MFY.js → chunk-33DOSHTA.js} +176 -36
- package/dist/chunk-35JCYSRR.js +158 -0
- package/dist/{chunk-AZYOKJYC.js → chunk-4PY655YM.js} +13 -1
- package/dist/{chunk-2JQ3O2YL.js → chunk-5EFSWZO6.js} +3 -3
- package/dist/{chunk-Y3TIJEBP.js → chunk-7SWP5FKU.js} +34 -613
- package/dist/{chunk-4VQTUVH7.js → chunk-7YZWHM36.js} +52 -26
- package/dist/{chunk-URXDAUVH.js → chunk-AXSJIFOJ.js} +174 -1
- package/dist/{chunk-4ITRXIVT.js → chunk-BLQXXX7Q.js} +6 -6
- package/dist/chunk-CSHO3PJB.js +684 -0
- package/dist/chunk-D5U3Q4N5.js +872 -0
- package/dist/chunk-DCF4KMFD.js +158 -0
- package/dist/{chunk-S5OJEGFG.js → chunk-DOIUYIXV.js} +2 -2
- package/dist/{chunk-YXQCA6B7.js → chunk-DVOUSOR3.js} +112 -7
- package/dist/{chunk-YDWHS4LJ.js → chunk-ECGJYWNA.js} +205 -33
- package/dist/{chunk-QMHPQYUV.js → chunk-EL6UBSX5.js} +7 -6
- package/dist/chunk-FZ5I2NF7.js +352 -0
- package/dist/{chunk-WJVWINEM.js → chunk-GFCHWMGD.js} +55 -6
- package/dist/{chunk-GNJL4YGR.js → chunk-GJO3CFUN.js} +30 -6
- package/dist/chunk-H3JZIB5O.js +322 -0
- package/dist/chunk-HEHO7SMV.js +51 -0
- package/dist/{chunk-UCQAOZHW.js → chunk-HGDDW24U.js} +3 -3
- package/dist/chunk-J3YUXVID.js +907 -0
- package/dist/{chunk-Y6VJKXGL.js → chunk-KCYWJDDW.js} +1 -1
- package/dist/{chunk-P5EPF6MB.js → chunk-MW5C6ZQA.js} +110 -13
- package/dist/chunk-NSXYM6EZ.js +255 -0
- package/dist/{chunk-YNIPYN4F.js → chunk-OFOCU2V4.js} +6 -5
- package/dist/{chunk-42MXU7A6.js → chunk-P62WHA27.js} +58 -47
- package/dist/chunk-PTWPPVC7.js +972 -0
- package/dist/{chunk-FAKNOB7Y.js → chunk-QFWERBDP.js} +2 -2
- package/dist/chunk-QYQAGBTM.js +2097 -0
- package/dist/chunk-RL2L6I6K.js +223 -0
- package/dist/{chunk-IIOU45CK.js → chunk-S7N7HI5E.js} +2 -2
- package/dist/{chunk-ECRZL5XR.js → chunk-T7E764W3.js} +23 -7
- package/dist/{chunk-MNPUYCHQ.js → chunk-TWMI3SNN.js} +6 -5
- package/dist/{chunk-2RAZ4ZFE.js → chunk-VBILES4B.js} +1 -1
- package/dist/{chunk-PI4WMLMG.js → chunk-VXAGOLDP.js} +1 -1
- package/dist/{chunk-SS4B7P7V.js → chunk-YIDV4VV2.js} +1 -1
- package/dist/chunk-YTRZNA64.js +37 -0
- package/dist/chunk-ZKWPCBYT.js +600 -0
- package/dist/cli/index.js +28 -21
- package/dist/commands/archive.js +3 -3
- package/dist/commands/backlog.js +1 -1
- package/dist/commands/benchmark.d.ts +12 -0
- package/dist/commands/benchmark.js +12 -0
- package/dist/commands/blocked.js +1 -1
- package/dist/commands/canvas.js +2 -2
- package/dist/commands/checkpoint.js +1 -1
- package/dist/commands/compat.js +1 -1
- package/dist/commands/context.js +8 -7
- package/dist/commands/doctor.d.ts +8 -3
- package/dist/commands/doctor.js +8 -22
- package/dist/commands/embed.js +6 -5
- package/dist/commands/entities.d.ts +8 -1
- package/dist/commands/entities.js +46 -3
- package/dist/commands/graph.js +4 -4
- package/dist/commands/inbox.d.ts +23 -0
- package/dist/commands/inbox.js +11 -0
- package/dist/commands/inject.d.ts +1 -1
- package/dist/commands/inject.js +5 -5
- package/dist/commands/kanban.js +1 -1
- package/dist/commands/link.js +5 -5
- package/dist/commands/maintain.d.ts +32 -0
- package/dist/commands/maintain.js +13 -0
- package/dist/commands/migrate-observations.js +3 -3
- package/dist/commands/observe.js +11 -10
- package/dist/commands/project.js +2 -2
- package/dist/commands/rebuild-embeddings.js +48 -17
- package/dist/commands/rebuild.js +9 -8
- package/dist/commands/recall.d.ts +14 -0
- package/dist/commands/recall.js +15 -0
- package/dist/commands/recover.js +1 -1
- package/dist/commands/reflect.js +6 -6
- package/dist/commands/repair-session.js +1 -1
- package/dist/commands/replay.js +10 -9
- package/dist/commands/session-recap.js +1 -1
- package/dist/commands/setup.js +4 -3
- package/dist/commands/shell-init.js +1 -1
- package/dist/commands/sleep.d.ts +1 -1
- package/dist/commands/sleep.js +20 -18
- package/dist/commands/status.js +40 -26
- package/dist/commands/sync-bd.js +3 -3
- package/dist/commands/tailscale.js +3 -3
- package/dist/commands/task.js +1 -1
- package/dist/commands/template.js +1 -1
- package/dist/commands/wake.d.ts +1 -1
- package/dist/commands/wake.js +10 -9
- package/dist/index.d.ts +233 -16
- package/dist/index.js +325 -111
- package/dist/{inject-DYUrDqQO.d.ts → inject-DEb_jpLi.d.ts} +3 -1
- package/dist/lib/auto-linker.js +2 -2
- package/dist/lib/canvas-layout.js +1 -1
- package/dist/lib/config.js +2 -2
- package/dist/lib/entity-index.js +1 -1
- package/dist/lib/project-utils.js +2 -2
- package/dist/lib/session-repair.js +1 -1
- package/dist/lib/session-utils.js +1 -1
- package/dist/lib/tailscale.js +1 -1
- package/dist/lib/task-utils.js +1 -1
- package/dist/lib/template-engine.js +1 -1
- package/dist/lib/webdav.js +1 -1
- package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
- package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
- package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
- package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
- package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
- package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
- package/dist/openclaw-plugin--gqA2BZw.d.ts +267 -0
- package/dist/openclaw-plugin.d.ts +4 -0
- package/dist/openclaw-plugin.js +20 -0
- package/dist/transformers.node-A2ZRORSQ.js +46775 -0
- package/dist/types-CbL-wIKi.d.ts +36 -0
- package/dist/{types-BbWJoC1c.d.ts → types-DslKvCaj.d.ts} +51 -1
- package/hooks/clawvault/HOOK.md +25 -8
- package/hooks/clawvault/handler.js +215 -78
- package/hooks/clawvault/handler.test.js +109 -43
- package/hooks/clawvault/integrity.js +112 -0
- package/hooks/clawvault/integrity.test.js +32 -0
- package/hooks/clawvault/openclaw.plugin.json +133 -15
- package/openclaw.plugin.json +161 -194
- package/package.json +8 -5
- package/bin/register-workgraph-commands.js +0 -451
- package/dist/chunk-5PJ4STIC.js +0 -465
- package/dist/chunk-ERNE2FZ5.js +0 -189
- package/dist/chunk-HR4KN6S2.js +0 -152
- package/dist/chunk-IJBFGPCS.js +0 -33
- package/dist/chunk-K7PNYS45.js +0 -93
- package/dist/chunk-NTOPJI7W.js +0 -207
- package/dist/chunk-PG56HX5T.js +0 -154
- package/dist/chunk-QPDDIHXE.js +0 -501
- package/dist/chunk-WIOLLGAD.js +0 -190
- package/dist/chunk-WMGIIABP.js +0 -15
- package/dist/ledger-B7g7jhqG.d.ts +0 -44
- package/dist/plugin/index.d.ts +0 -352
- package/dist/plugin/index.js +0 -4264
- package/dist/registry-BR4326o0.d.ts +0 -30
- package/dist/store-CA-6sKCJ.d.ts +0 -34
- package/dist/thread-B9LhXNU0.d.ts +0 -41
- package/dist/workgraph/index.d.ts +0 -5
- package/dist/workgraph/index.js +0 -23
- package/dist/workgraph/ledger.d.ts +0 -2
- package/dist/workgraph/ledger.js +0 -25
- package/dist/workgraph/registry.d.ts +0 -2
- package/dist/workgraph/registry.js +0 -19
- package/dist/workgraph/store.d.ts +0 -2
- package/dist/workgraph/store.js +0 -25
- package/dist/workgraph/thread.d.ts +0 -2
- package/dist/workgraph/thread.js +0 -25
- package/dist/workgraph/types.d.ts +0 -54
- package/dist/workgraph/types.js +0 -7
package/dist/chunk-QPDDIHXE.js
DELETED
|
@@ -1,501 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
formatAge
|
|
3
|
-
} from "./chunk-7ZRP733D.js";
|
|
4
|
-
import {
|
|
5
|
-
scanVaultLinks
|
|
6
|
-
} from "./chunk-4VQTUVH7.js";
|
|
7
|
-
import {
|
|
8
|
-
getObserverStaleness
|
|
9
|
-
} from "./chunk-PI4WMLMG.js";
|
|
10
|
-
import {
|
|
11
|
-
ClawVault,
|
|
12
|
-
findVault
|
|
13
|
-
} from "./chunk-YDWHS4LJ.js";
|
|
14
|
-
import {
|
|
15
|
-
listQmdCollections,
|
|
16
|
-
loadVaultQmdConfig
|
|
17
|
-
} from "./chunk-WIOLLGAD.js";
|
|
18
|
-
import {
|
|
19
|
-
QMD_INSTALL_COMMAND,
|
|
20
|
-
QMD_INSTALL_URL,
|
|
21
|
-
hasQmd
|
|
22
|
-
} from "./chunk-5PJ4STIC.js";
|
|
23
|
-
import {
|
|
24
|
-
loadMemoryGraphIndex
|
|
25
|
-
} from "./chunk-ZZA73MFY.js";
|
|
26
|
-
import {
|
|
27
|
-
checkOpenClawCompatibility
|
|
28
|
-
} from "./chunk-X3SPPUFG.js";
|
|
29
|
-
|
|
30
|
-
// src/commands/doctor.ts
|
|
31
|
-
import * as fs from "fs";
|
|
32
|
-
import * as os from "os";
|
|
33
|
-
import * as path from "path";
|
|
34
|
-
var CLAWVAULT_DIR = ".clawvault";
|
|
35
|
-
var CHECKPOINT_FILE = "last-checkpoint.json";
|
|
36
|
-
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
37
|
-
var ACTIVE_USE_DAYS = 7;
|
|
38
|
-
var V2_COLLECTION_PATTERNS = [
|
|
39
|
-
/^clawvault$/i,
|
|
40
|
-
/^vault$/i,
|
|
41
|
-
/^memory$/i,
|
|
42
|
-
/^notes$/i
|
|
43
|
-
];
|
|
44
|
-
function daysSince(date, now = Date.now()) {
|
|
45
|
-
return Math.max(0, Math.floor((now - date.getTime()) / DAY_MS));
|
|
46
|
-
}
|
|
47
|
-
function describeAge(date, now = Date.now()) {
|
|
48
|
-
return formatAge(now - date.getTime());
|
|
49
|
-
}
|
|
50
|
-
function loadCheckpointTimestamp(vaultPath) {
|
|
51
|
-
const checkpointPath = path.join(vaultPath, CLAWVAULT_DIR, CHECKPOINT_FILE);
|
|
52
|
-
if (!fs.existsSync(checkpointPath)) {
|
|
53
|
-
return {};
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const data = JSON.parse(fs.readFileSync(checkpointPath, "utf-8"));
|
|
57
|
-
return { timestamp: data.timestamp };
|
|
58
|
-
} catch (err) {
|
|
59
|
-
return { error: err?.message || "Failed to parse checkpoint" };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function getShellConfigPaths(shellPath) {
|
|
63
|
-
const home = os.homedir();
|
|
64
|
-
const shellName = shellPath ? path.basename(shellPath) : "bash";
|
|
65
|
-
if (shellName === "zsh") {
|
|
66
|
-
return [path.join(home, ".zshrc"), path.join(home, ".zprofile")];
|
|
67
|
-
}
|
|
68
|
-
if (shellName === "fish") {
|
|
69
|
-
return [path.join(home, ".config", "fish", "config.fish")];
|
|
70
|
-
}
|
|
71
|
-
return [path.join(home, ".bashrc"), path.join(home, ".bash_profile"), path.join(home, ".profile")];
|
|
72
|
-
}
|
|
73
|
-
function hasClawvaultPathConfig(paths) {
|
|
74
|
-
for (const filePath of paths) {
|
|
75
|
-
if (!fs.existsSync(filePath)) continue;
|
|
76
|
-
try {
|
|
77
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
78
|
-
if (/CLAWVAULT_PATH\s*=/.test(content)) {
|
|
79
|
-
return true;
|
|
80
|
-
}
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
function isLikelyV2CollectionName(name) {
|
|
87
|
-
return V2_COLLECTION_PATTERNS.some((pattern) => pattern.test(name));
|
|
88
|
-
}
|
|
89
|
-
function checkQmdCollectionExists(collections, expectedName) {
|
|
90
|
-
const found = collections.find((c) => c.name === expectedName);
|
|
91
|
-
return { exists: !!found, collection: found };
|
|
92
|
-
}
|
|
93
|
-
function checkCollectionPathMatches(collection, expectedRoot) {
|
|
94
|
-
if (!collection.root) return false;
|
|
95
|
-
const normalizedCollectionRoot = path.resolve(collection.root);
|
|
96
|
-
const normalizedExpectedRoot = path.resolve(expectedRoot);
|
|
97
|
-
return normalizedCollectionRoot === normalizedExpectedRoot;
|
|
98
|
-
}
|
|
99
|
-
function detectMigrationIssues(vaultPath, configuredCollection, configuredRoot) {
|
|
100
|
-
const issues = [];
|
|
101
|
-
if (!hasQmd()) {
|
|
102
|
-
return issues;
|
|
103
|
-
}
|
|
104
|
-
let collections;
|
|
105
|
-
try {
|
|
106
|
-
collections = listQmdCollections();
|
|
107
|
-
} catch {
|
|
108
|
-
return issues;
|
|
109
|
-
}
|
|
110
|
-
const vaultConfig = loadVaultQmdConfig(vaultPath);
|
|
111
|
-
const expectedCollection = configuredCollection || vaultConfig.qmdCollection;
|
|
112
|
-
const expectedRoot = configuredRoot || vaultConfig.qmdRoot;
|
|
113
|
-
const { exists, collection } = checkQmdCollectionExists(collections, expectedCollection);
|
|
114
|
-
if (!exists) {
|
|
115
|
-
const potentialV2Collections = collections.filter(
|
|
116
|
-
(c) => isLikelyV2CollectionName(c.name) && c.root && path.resolve(c.root) === path.resolve(expectedRoot)
|
|
117
|
-
);
|
|
118
|
-
if (potentialV2Collections.length > 0) {
|
|
119
|
-
issues.push({
|
|
120
|
-
type: "stale_collection_name",
|
|
121
|
-
description: `Found v2-style collection "${potentialV2Collections[0].name}" that should be renamed to "${expectedCollection}"`,
|
|
122
|
-
autoFixable: true,
|
|
123
|
-
details: {
|
|
124
|
-
oldName: potentialV2Collections[0].name,
|
|
125
|
-
newName: expectedCollection,
|
|
126
|
-
root: potentialV2Collections[0].root
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
} else {
|
|
130
|
-
issues.push({
|
|
131
|
-
type: "missing_qmd_collection",
|
|
132
|
-
description: `qmd collection "${expectedCollection}" does not exist`,
|
|
133
|
-
autoFixable: true,
|
|
134
|
-
details: {
|
|
135
|
-
collectionName: expectedCollection,
|
|
136
|
-
expectedRoot
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
} else if (collection && !checkCollectionPathMatches(collection, expectedRoot)) {
|
|
141
|
-
issues.push({
|
|
142
|
-
type: "wrong_vault_path",
|
|
143
|
-
description: `Collection "${expectedCollection}" points to "${collection.root}" but vault is at "${expectedRoot}"`,
|
|
144
|
-
autoFixable: true,
|
|
145
|
-
details: {
|
|
146
|
-
collectionName: expectedCollection,
|
|
147
|
-
currentRoot: collection.root,
|
|
148
|
-
expectedRoot
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
const orphanedCollections = collections.filter((c) => {
|
|
153
|
-
if (c.name === expectedCollection) return false;
|
|
154
|
-
if (!c.root) return false;
|
|
155
|
-
const collectionRoot = path.resolve(c.root);
|
|
156
|
-
const vaultRoot = path.resolve(expectedRoot);
|
|
157
|
-
return collectionRoot === vaultRoot || collectionRoot.startsWith(vaultRoot + path.sep);
|
|
158
|
-
});
|
|
159
|
-
for (const orphan of orphanedCollections) {
|
|
160
|
-
issues.push({
|
|
161
|
-
type: "orphaned_collection",
|
|
162
|
-
description: `Orphaned collection "${orphan.name}" points to vault path but is not the configured collection`,
|
|
163
|
-
autoFixable: true,
|
|
164
|
-
details: {
|
|
165
|
-
collectionName: orphan.name,
|
|
166
|
-
root: orphan.root
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
const configPath = path.join(vaultPath, ".clawvault.json");
|
|
171
|
-
if (fs.existsSync(configPath)) {
|
|
172
|
-
try {
|
|
173
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
174
|
-
if (!config.qmdCollection || !config.qmdRoot) {
|
|
175
|
-
issues.push({
|
|
176
|
-
type: "missing_qmd_config",
|
|
177
|
-
description: "Vault config is missing qmdCollection or qmdRoot settings",
|
|
178
|
-
autoFixable: true,
|
|
179
|
-
details: {
|
|
180
|
-
hasQmdCollection: !!config.qmdCollection,
|
|
181
|
-
hasQmdRoot: !!config.qmdRoot
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
} catch {
|
|
186
|
-
issues.push({
|
|
187
|
-
type: "legacy_config_format",
|
|
188
|
-
description: "Unable to parse .clawvault.json - may need migration",
|
|
189
|
-
autoFixable: false
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return issues;
|
|
194
|
-
}
|
|
195
|
-
function migrationIssuesToChecks(issues) {
|
|
196
|
-
return issues.map((issue) => ({
|
|
197
|
-
label: `migration: ${issue.type.replace(/_/g, " ")}`,
|
|
198
|
-
status: "warn",
|
|
199
|
-
detail: issue.description,
|
|
200
|
-
hint: issue.autoFixable ? "Run `clawvault migrate` to auto-fix this issue." : "Manual intervention required.",
|
|
201
|
-
category: "migration"
|
|
202
|
-
}));
|
|
203
|
-
}
|
|
204
|
-
async function resolveVault(vaultPath) {
|
|
205
|
-
if (vaultPath) {
|
|
206
|
-
const vault = new ClawVault(path.resolve(vaultPath));
|
|
207
|
-
await vault.load();
|
|
208
|
-
return vault;
|
|
209
|
-
}
|
|
210
|
-
const envPath = process.env.CLAWVAULT_PATH;
|
|
211
|
-
if (envPath) {
|
|
212
|
-
const vault = new ClawVault(path.resolve(envPath));
|
|
213
|
-
await vault.load();
|
|
214
|
-
return vault;
|
|
215
|
-
}
|
|
216
|
-
const found = await findVault();
|
|
217
|
-
if (!found) {
|
|
218
|
-
throw new Error("No ClawVault found. Run `clawvault init` first.");
|
|
219
|
-
}
|
|
220
|
-
return found;
|
|
221
|
-
}
|
|
222
|
-
async function doctor(vaultPath) {
|
|
223
|
-
const checks = [];
|
|
224
|
-
let warnings = 0;
|
|
225
|
-
let errors = 0;
|
|
226
|
-
const migrationIssues = [];
|
|
227
|
-
const compatReport = checkOpenClawCompatibility();
|
|
228
|
-
if (compatReport.errors > 0) {
|
|
229
|
-
checks.push({
|
|
230
|
-
label: "OpenClaw compatibility",
|
|
231
|
-
status: "error",
|
|
232
|
-
detail: `${compatReport.errors} error(s), ${compatReport.warnings} warning(s)`,
|
|
233
|
-
hint: "Run `clawvault compat` for full compatibility diagnostics.",
|
|
234
|
-
category: "system"
|
|
235
|
-
});
|
|
236
|
-
errors++;
|
|
237
|
-
} else if (compatReport.warnings > 0) {
|
|
238
|
-
checks.push({
|
|
239
|
-
label: "OpenClaw compatibility",
|
|
240
|
-
status: "warn",
|
|
241
|
-
detail: `${compatReport.warnings} warning(s)`,
|
|
242
|
-
hint: "Run `clawvault compat` for full compatibility diagnostics.",
|
|
243
|
-
category: "system"
|
|
244
|
-
});
|
|
245
|
-
warnings++;
|
|
246
|
-
} else {
|
|
247
|
-
checks.push({
|
|
248
|
-
label: "OpenClaw compatibility",
|
|
249
|
-
status: "ok",
|
|
250
|
-
category: "system"
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
if (hasQmd()) {
|
|
254
|
-
checks.push({ label: "qmd installed", status: "ok", category: "system" });
|
|
255
|
-
} else {
|
|
256
|
-
checks.push({
|
|
257
|
-
label: "qmd installed",
|
|
258
|
-
status: "error",
|
|
259
|
-
detail: "qmd binary not found in PATH",
|
|
260
|
-
hint: `Install qmd to enable ClawVault search and indexing:
|
|
261
|
-
${QMD_INSTALL_COMMAND}
|
|
262
|
-
|
|
263
|
-
For more information: ${QMD_INSTALL_URL}`,
|
|
264
|
-
category: "system"
|
|
265
|
-
});
|
|
266
|
-
errors++;
|
|
267
|
-
}
|
|
268
|
-
const shellConfigs = getShellConfigPaths(process.env.SHELL).filter(fs.existsSync);
|
|
269
|
-
if (hasClawvaultPathConfig(shellConfigs)) {
|
|
270
|
-
checks.push({
|
|
271
|
-
label: "CLAWVAULT_PATH in shell config",
|
|
272
|
-
status: "ok",
|
|
273
|
-
detail: shellConfigs.map((p) => path.basename(p)).join(", "),
|
|
274
|
-
category: "system"
|
|
275
|
-
});
|
|
276
|
-
} else {
|
|
277
|
-
checks.push({
|
|
278
|
-
label: "CLAWVAULT_PATH in shell config",
|
|
279
|
-
status: "warn",
|
|
280
|
-
hint: "Run `clawvault shell-init` and add it to your shell rc.",
|
|
281
|
-
category: "system"
|
|
282
|
-
});
|
|
283
|
-
warnings++;
|
|
284
|
-
}
|
|
285
|
-
if (!hasQmd()) {
|
|
286
|
-
return { vaultPath, checks, warnings, errors, migrationIssues };
|
|
287
|
-
}
|
|
288
|
-
let vault;
|
|
289
|
-
try {
|
|
290
|
-
vault = await resolveVault(vaultPath);
|
|
291
|
-
checks.push({ label: "vault found", status: "ok", detail: vault.getPath(), category: "system" });
|
|
292
|
-
} catch (err) {
|
|
293
|
-
checks.push({
|
|
294
|
-
label: "vault found",
|
|
295
|
-
status: "error",
|
|
296
|
-
detail: err?.message || "Unable to locate vault",
|
|
297
|
-
category: "system"
|
|
298
|
-
});
|
|
299
|
-
errors++;
|
|
300
|
-
return { vaultPath, checks, warnings, errors, migrationIssues };
|
|
301
|
-
}
|
|
302
|
-
const detectedMigrationIssues = detectMigrationIssues(
|
|
303
|
-
vault.getPath(),
|
|
304
|
-
vault.getQmdCollection(),
|
|
305
|
-
vault.getQmdRoot()
|
|
306
|
-
);
|
|
307
|
-
migrationIssues.push(...detectedMigrationIssues);
|
|
308
|
-
const migrationChecks = migrationIssuesToChecks(detectedMigrationIssues);
|
|
309
|
-
checks.push(...migrationChecks);
|
|
310
|
-
warnings += migrationChecks.length;
|
|
311
|
-
const stats = await vault.stats();
|
|
312
|
-
const documents = await vault.list();
|
|
313
|
-
const handoffs = await vault.list("handoffs");
|
|
314
|
-
const inbox = await vault.list("inbox");
|
|
315
|
-
const qmdCollection = vault.getQmdCollection();
|
|
316
|
-
if (qmdCollection) {
|
|
317
|
-
checks.push({ label: "qmd collection configured", status: "ok", detail: qmdCollection, category: "system" });
|
|
318
|
-
} else {
|
|
319
|
-
checks.push({
|
|
320
|
-
label: "qmd collection configured",
|
|
321
|
-
status: "warn",
|
|
322
|
-
hint: "Set qmd collection in .clawvault.json or run `clawvault migrate`.",
|
|
323
|
-
category: "system"
|
|
324
|
-
});
|
|
325
|
-
warnings++;
|
|
326
|
-
}
|
|
327
|
-
const latestDoc = documents.slice().sort((a, b) => b.modified.getTime() - a.modified.getTime())[0];
|
|
328
|
-
const latestDocAge = latestDoc ? daysSince(latestDoc.modified) : null;
|
|
329
|
-
const graphIndex = loadMemoryGraphIndex(vault.getPath());
|
|
330
|
-
if (!graphIndex) {
|
|
331
|
-
checks.push({
|
|
332
|
-
label: "memory graph index",
|
|
333
|
-
status: "warn",
|
|
334
|
-
detail: "No graph index found",
|
|
335
|
-
hint: "Run `clawvault graph --refresh` to build .clawvault/graph-index.json.",
|
|
336
|
-
category: "health"
|
|
337
|
-
});
|
|
338
|
-
warnings++;
|
|
339
|
-
} else {
|
|
340
|
-
const generatedAt = new Date(graphIndex.generatedAt);
|
|
341
|
-
const generatedAge = describeAge(generatedAt);
|
|
342
|
-
const latestDocIsNewer = latestDoc ? latestDoc.modified.getTime() > generatedAt.getTime() + 1e3 : false;
|
|
343
|
-
if (latestDocIsNewer) {
|
|
344
|
-
checks.push({
|
|
345
|
-
label: "memory graph index",
|
|
346
|
-
status: "warn",
|
|
347
|
-
detail: `Stale graph index (generated ${generatedAge} ago)`,
|
|
348
|
-
hint: "Run `clawvault graph --refresh` to resync index.",
|
|
349
|
-
category: "health"
|
|
350
|
-
});
|
|
351
|
-
warnings++;
|
|
352
|
-
} else {
|
|
353
|
-
checks.push({
|
|
354
|
-
label: "memory graph index",
|
|
355
|
-
status: "ok",
|
|
356
|
-
detail: `${graphIndex.graph.stats.nodeCount} nodes, ${graphIndex.graph.stats.edgeCount} edges`,
|
|
357
|
-
category: "health"
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
let lastHandoffAge = null;
|
|
362
|
-
if (handoffs.length === 0) {
|
|
363
|
-
checks.push({
|
|
364
|
-
label: "recent handoff",
|
|
365
|
-
status: "warn",
|
|
366
|
-
hint: "Run `clawvault sleep` at the end of sessions.",
|
|
367
|
-
category: "health"
|
|
368
|
-
});
|
|
369
|
-
warnings++;
|
|
370
|
-
} else {
|
|
371
|
-
const latestHandoff = handoffs.slice().sort((a, b) => b.modified.getTime() - a.modified.getTime())[0];
|
|
372
|
-
lastHandoffAge = daysSince(latestHandoff.modified);
|
|
373
|
-
const ageLabel = describeAge(latestHandoff.modified);
|
|
374
|
-
if (lastHandoffAge > 1) {
|
|
375
|
-
checks.push({
|
|
376
|
-
label: "recent handoff",
|
|
377
|
-
status: "warn",
|
|
378
|
-
detail: `Last handoff ${ageLabel} ago`,
|
|
379
|
-
hint: "Run `clawvault sleep` before long pauses.",
|
|
380
|
-
category: "health"
|
|
381
|
-
});
|
|
382
|
-
warnings++;
|
|
383
|
-
} else {
|
|
384
|
-
checks.push({
|
|
385
|
-
label: "recent handoff",
|
|
386
|
-
status: "ok",
|
|
387
|
-
detail: `Last handoff ${ageLabel} ago`,
|
|
388
|
-
category: "health"
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
const checkpointInfo = loadCheckpointTimestamp(vault.getPath());
|
|
393
|
-
const activeUse = latestDocAge !== null && latestDocAge <= ACTIVE_USE_DAYS || lastHandoffAge !== null && lastHandoffAge <= ACTIVE_USE_DAYS;
|
|
394
|
-
if (checkpointInfo.error) {
|
|
395
|
-
checks.push({
|
|
396
|
-
label: "checkpoint freshness",
|
|
397
|
-
status: "warn",
|
|
398
|
-
detail: checkpointInfo.error,
|
|
399
|
-
category: "health"
|
|
400
|
-
});
|
|
401
|
-
warnings++;
|
|
402
|
-
} else if (!checkpointInfo.timestamp) {
|
|
403
|
-
const status = activeUse ? "warn" : "ok";
|
|
404
|
-
if (status === "warn") warnings++;
|
|
405
|
-
checks.push({
|
|
406
|
-
label: "checkpoint freshness",
|
|
407
|
-
status,
|
|
408
|
-
detail: activeUse ? "No checkpoint found" : "No checkpoint found (vault appears inactive)",
|
|
409
|
-
hint: activeUse ? "Run `clawvault checkpoint` during heavy work." : void 0,
|
|
410
|
-
category: "health"
|
|
411
|
-
});
|
|
412
|
-
} else {
|
|
413
|
-
const checkpointDate = new Date(checkpointInfo.timestamp);
|
|
414
|
-
const checkpointAge = daysSince(checkpointDate);
|
|
415
|
-
const ageLabel = describeAge(checkpointDate);
|
|
416
|
-
if (activeUse && checkpointAge > 1) {
|
|
417
|
-
checks.push({
|
|
418
|
-
label: "checkpoint freshness",
|
|
419
|
-
status: "warn",
|
|
420
|
-
detail: `Last checkpoint ${ageLabel} ago`,
|
|
421
|
-
hint: "Checkpoint at least once per active day.",
|
|
422
|
-
category: "health"
|
|
423
|
-
});
|
|
424
|
-
warnings++;
|
|
425
|
-
} else {
|
|
426
|
-
checks.push({
|
|
427
|
-
label: "checkpoint freshness",
|
|
428
|
-
status: "ok",
|
|
429
|
-
detail: `Last checkpoint ${ageLabel} ago`,
|
|
430
|
-
category: "health"
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
const observerStaleness = getObserverStaleness(vault.getPath());
|
|
435
|
-
if (observerStaleness.staleCount > 0) {
|
|
436
|
-
checks.push({
|
|
437
|
-
label: "observer freshness",
|
|
438
|
-
status: "warn",
|
|
439
|
-
detail: `${observerStaleness.staleCount} stale session cursor(s); oldest ${formatAge(observerStaleness.oldestMs)} ago`,
|
|
440
|
-
hint: "Run `clawvault observe --cron` and verify cron/hook scheduling.",
|
|
441
|
-
category: "health"
|
|
442
|
-
});
|
|
443
|
-
warnings++;
|
|
444
|
-
} else {
|
|
445
|
-
checks.push({
|
|
446
|
-
label: "observer freshness",
|
|
447
|
-
status: "ok",
|
|
448
|
-
category: "health"
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
const linkScan = scanVaultLinks(vault.getPath());
|
|
452
|
-
if (linkScan.orphans.length > 20) {
|
|
453
|
-
checks.push({
|
|
454
|
-
label: "orphan links",
|
|
455
|
-
status: "warn",
|
|
456
|
-
detail: `${linkScan.orphans.length} orphan link(s)`,
|
|
457
|
-
hint: "Run `clawvault link --orphans` to review.",
|
|
458
|
-
category: "health"
|
|
459
|
-
});
|
|
460
|
-
warnings++;
|
|
461
|
-
} else {
|
|
462
|
-
checks.push({
|
|
463
|
-
label: "orphan links",
|
|
464
|
-
status: "ok",
|
|
465
|
-
detail: `${linkScan.orphans.length} orphan link(s)`,
|
|
466
|
-
category: "health"
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
if (inbox.length > 5) {
|
|
470
|
-
checks.push({
|
|
471
|
-
label: "inbox backlog",
|
|
472
|
-
status: "warn",
|
|
473
|
-
detail: `${inbox.length} inbox item(s) pending`,
|
|
474
|
-
hint: "Process inbox items to keep memory tidy.",
|
|
475
|
-
category: "health"
|
|
476
|
-
});
|
|
477
|
-
warnings++;
|
|
478
|
-
} else {
|
|
479
|
-
checks.push({
|
|
480
|
-
label: "inbox backlog",
|
|
481
|
-
status: "ok",
|
|
482
|
-
detail: `${inbox.length} inbox item(s) pending`,
|
|
483
|
-
category: "health"
|
|
484
|
-
});
|
|
485
|
-
}
|
|
486
|
-
if (stats.documents < 5) {
|
|
487
|
-
checks.push({
|
|
488
|
-
label: "vault activity",
|
|
489
|
-
status: "warn",
|
|
490
|
-
detail: `${stats.documents} total documents`,
|
|
491
|
-
hint: "Start capturing decisions, lessons, and projects.",
|
|
492
|
-
category: "health"
|
|
493
|
-
});
|
|
494
|
-
warnings++;
|
|
495
|
-
}
|
|
496
|
-
return { vaultPath: vault.getPath(), checks, warnings, errors, migrationIssues };
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
export {
|
|
500
|
-
doctor
|
|
501
|
-
};
|
package/dist/chunk-WIOLLGAD.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
// src/lib/qmd-collections.ts
|
|
2
|
-
import { execFileSync } from "child_process";
|
|
3
|
-
var COLLECTION_HEADER_RE = /^(\S+)\s+\(qmd:\/\/([^)]+)\)\s*$/;
|
|
4
|
-
var DETAIL_LINE_RE = /^\s+([A-Za-z][A-Za-z0-9 _-]*):\s*(.+)\s*$/;
|
|
5
|
-
function normalizeDetailKey(value) {
|
|
6
|
-
return value.trim().toLowerCase().replace(/[ -]+/g, "_");
|
|
7
|
-
}
|
|
8
|
-
function parseCount(raw) {
|
|
9
|
-
if (!raw) return void 0;
|
|
10
|
-
const match = raw.match(/-?\d[\d,]*/);
|
|
11
|
-
if (!match) return void 0;
|
|
12
|
-
const parsed = Number.parseInt(match[0].replace(/,/g, ""), 10);
|
|
13
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
14
|
-
}
|
|
15
|
-
function pickDetail(details, keys) {
|
|
16
|
-
for (const key of keys) {
|
|
17
|
-
const value = details[key];
|
|
18
|
-
if (typeof value === "string" && value.trim()) {
|
|
19
|
-
return value.trim();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return void 0;
|
|
23
|
-
}
|
|
24
|
-
function pickCount(details, keys) {
|
|
25
|
-
for (const key of keys) {
|
|
26
|
-
const parsed = parseCount(details[key]);
|
|
27
|
-
if (parsed !== void 0) {
|
|
28
|
-
return parsed;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
return void 0;
|
|
32
|
-
}
|
|
33
|
-
function parseQmdCollectionList(raw) {
|
|
34
|
-
const collections = [];
|
|
35
|
-
let current = null;
|
|
36
|
-
for (const line of raw.split(/\r?\n/)) {
|
|
37
|
-
const headerMatch = line.match(COLLECTION_HEADER_RE);
|
|
38
|
-
if (headerMatch) {
|
|
39
|
-
current = {
|
|
40
|
-
name: headerMatch[1],
|
|
41
|
-
uri: headerMatch[2],
|
|
42
|
-
details: {}
|
|
43
|
-
};
|
|
44
|
-
collections.push(current);
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (!current) continue;
|
|
48
|
-
const detailMatch = line.match(DETAIL_LINE_RE);
|
|
49
|
-
if (!detailMatch) continue;
|
|
50
|
-
const key = normalizeDetailKey(detailMatch[1]);
|
|
51
|
-
current.details[key] = detailMatch[2].trim();
|
|
52
|
-
}
|
|
53
|
-
for (const collection of collections) {
|
|
54
|
-
const root = pickDetail(collection.details, ["root", "path", "directory"]);
|
|
55
|
-
if (root) {
|
|
56
|
-
collection.root = root;
|
|
57
|
-
}
|
|
58
|
-
collection.files = pickCount(collection.details, ["files", "documents", "docs"]);
|
|
59
|
-
collection.vectors = pickCount(collection.details, ["vectors", "embeddings", "vector_embeddings"]);
|
|
60
|
-
collection.pendingEmbeddings = pickCount(collection.details, [
|
|
61
|
-
"pending",
|
|
62
|
-
"pending_vectors",
|
|
63
|
-
"pending_embeddings",
|
|
64
|
-
"unembedded",
|
|
65
|
-
"without_embeddings"
|
|
66
|
-
]);
|
|
67
|
-
if (collection.pendingEmbeddings === void 0 && collection.files !== void 0 && collection.vectors !== void 0) {
|
|
68
|
-
collection.pendingEmbeddings = Math.max(collection.files - collection.vectors, 0);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return collections;
|
|
72
|
-
}
|
|
73
|
-
function listQmdCollections() {
|
|
74
|
-
const output = execFileSync("qmd", ["collection", "list"], {
|
|
75
|
-
encoding: "utf-8"
|
|
76
|
-
});
|
|
77
|
-
return parseQmdCollectionList(output);
|
|
78
|
-
}
|
|
79
|
-
function removeQmdCollection(name) {
|
|
80
|
-
try {
|
|
81
|
-
execFileSync("qmd", ["collection", "remove", name], { stdio: "ignore" });
|
|
82
|
-
return;
|
|
83
|
-
} catch {
|
|
84
|
-
execFileSync("qmd", ["collection", "rm", name], { stdio: "ignore" });
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function collectionExists(name) {
|
|
88
|
-
try {
|
|
89
|
-
const collections = listQmdCollections();
|
|
90
|
-
return collections.some((c) => c.name === name);
|
|
91
|
-
} catch {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
function findCollectionByRoot(rootPath) {
|
|
96
|
-
try {
|
|
97
|
-
const collections = listQmdCollections();
|
|
98
|
-
const normalizedRoot = rootPath.replace(/\/$/, "");
|
|
99
|
-
return collections.find((c) => {
|
|
100
|
-
if (!c.root) return false;
|
|
101
|
-
const normalizedCollectionRoot = c.root.replace(/\/$/, "");
|
|
102
|
-
return normalizedCollectionRoot === normalizedRoot;
|
|
103
|
-
});
|
|
104
|
-
} catch {
|
|
105
|
-
return void 0;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
function getFirstCollection() {
|
|
109
|
-
try {
|
|
110
|
-
const collections = listQmdCollections();
|
|
111
|
-
return collections[0];
|
|
112
|
-
} catch {
|
|
113
|
-
return void 0;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// src/lib/vault-qmd-config.ts
|
|
118
|
-
import * as fs from "fs";
|
|
119
|
-
import * as path from "path";
|
|
120
|
-
var CONFIG_FILE = ".clawvault.json";
|
|
121
|
-
function readTrimmedString(value) {
|
|
122
|
-
if (typeof value !== "string") return void 0;
|
|
123
|
-
const trimmed = value.trim();
|
|
124
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
125
|
-
}
|
|
126
|
-
function autoDetectCollection(vaultPath, fallbackName) {
|
|
127
|
-
const byRoot = findCollectionByRoot(vaultPath);
|
|
128
|
-
if (byRoot) {
|
|
129
|
-
return { collection: byRoot.name, autoDetected: true };
|
|
130
|
-
}
|
|
131
|
-
if (collectionExists(fallbackName)) {
|
|
132
|
-
return { collection: fallbackName, autoDetected: false };
|
|
133
|
-
}
|
|
134
|
-
const first = getFirstCollection();
|
|
135
|
-
if (first) {
|
|
136
|
-
return { collection: first.name, autoDetected: true };
|
|
137
|
-
}
|
|
138
|
-
return { collection: fallbackName, autoDetected: false };
|
|
139
|
-
}
|
|
140
|
-
function loadVaultQmdConfig(vaultPath) {
|
|
141
|
-
const resolvedVaultPath = path.resolve(vaultPath);
|
|
142
|
-
const fallbackName = path.basename(resolvedVaultPath);
|
|
143
|
-
const fallbackRoot = resolvedVaultPath;
|
|
144
|
-
const configPath = path.join(resolvedVaultPath, CONFIG_FILE);
|
|
145
|
-
if (!fs.existsSync(configPath)) {
|
|
146
|
-
const { collection, autoDetected } = autoDetectCollection(resolvedVaultPath, fallbackName);
|
|
147
|
-
return {
|
|
148
|
-
vaultPath: resolvedVaultPath,
|
|
149
|
-
qmdCollection: collection,
|
|
150
|
-
qmdRoot: fallbackRoot,
|
|
151
|
-
autoDetected
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
try {
|
|
155
|
-
const raw = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
156
|
-
const configuredName = readTrimmedString(raw.name) ?? fallbackName;
|
|
157
|
-
const configuredCollection = readTrimmedString(raw.qmdCollection);
|
|
158
|
-
const rawRoot = readTrimmedString(raw.qmdRoot) ?? fallbackRoot;
|
|
159
|
-
const qmdRoot = path.isAbsolute(rawRoot) ? path.resolve(rawRoot) : path.resolve(resolvedVaultPath, rawRoot);
|
|
160
|
-
if (configuredCollection && collectionExists(configuredCollection)) {
|
|
161
|
-
return {
|
|
162
|
-
vaultPath: resolvedVaultPath,
|
|
163
|
-
qmdCollection: configuredCollection,
|
|
164
|
-
qmdRoot
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
const { collection, autoDetected } = autoDetectCollection(qmdRoot, configuredCollection ?? configuredName);
|
|
168
|
-
return {
|
|
169
|
-
vaultPath: resolvedVaultPath,
|
|
170
|
-
qmdCollection: collection,
|
|
171
|
-
qmdRoot,
|
|
172
|
-
autoDetected
|
|
173
|
-
};
|
|
174
|
-
} catch {
|
|
175
|
-
const { collection, autoDetected } = autoDetectCollection(resolvedVaultPath, fallbackName);
|
|
176
|
-
return {
|
|
177
|
-
vaultPath: resolvedVaultPath,
|
|
178
|
-
qmdCollection: collection,
|
|
179
|
-
qmdRoot: fallbackRoot,
|
|
180
|
-
autoDetected
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export {
|
|
186
|
-
parseQmdCollectionList,
|
|
187
|
-
listQmdCollections,
|
|
188
|
-
removeQmdCollection,
|
|
189
|
-
loadVaultQmdConfig
|
|
190
|
-
};
|
package/dist/chunk-WMGIIABP.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// src/workgraph/types.ts
|
|
2
|
-
var THREAD_STATUS_TRANSITIONS = {
|
|
3
|
-
open: ["active", "cancelled"],
|
|
4
|
-
active: ["blocked", "done", "cancelled", "open"],
|
|
5
|
-
// open = release
|
|
6
|
-
blocked: ["active", "cancelled"],
|
|
7
|
-
done: [],
|
|
8
|
-
// terminal
|
|
9
|
-
cancelled: ["open"]
|
|
10
|
-
// can be reopened
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
THREAD_STATUS_TRANSITIONS
|
|
15
|
-
};
|