mindkeeper-openclaw 0.2.31 → 0.2.33
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/dist/index.js +115 -31
- package/package.json +10 -9
- package/LICENSE +0 -21
package/dist/index.js
CHANGED
|
@@ -718,11 +718,66 @@ var Tracker = class {
|
|
|
718
718
|
await this.ensureConfigLoaded();
|
|
719
719
|
await this.store.init();
|
|
720
720
|
await this.ensureGitignore();
|
|
721
|
+
this.log?.info?.(
|
|
722
|
+
`[mindkeeper] init: commitMessage.mode=${this.config.commitMessage.mode}, llmProvider=${this.llmProvider ? "yes" : "no"}`
|
|
723
|
+
);
|
|
721
724
|
const changed = await this.getTrackedChangedFiles();
|
|
722
725
|
if (changed.length > 0) {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
+
const filesToCommit = changed.map((e) => e.filepath);
|
|
727
|
+
await this.store.addFiles(filesToCommit);
|
|
728
|
+
let message = null;
|
|
729
|
+
if (this.config.commitMessage.mode === "llm" && this.llmProvider) {
|
|
730
|
+
let headOid = null;
|
|
731
|
+
try {
|
|
732
|
+
headOid = await this.resolveHead();
|
|
733
|
+
} catch {
|
|
734
|
+
}
|
|
735
|
+
if (headOid) {
|
|
736
|
+
const diffs = [];
|
|
737
|
+
for (const file of filesToCommit) {
|
|
738
|
+
try {
|
|
739
|
+
const oldContent = await this.store.readFile(file, headOid) ?? "";
|
|
740
|
+
let newContent;
|
|
741
|
+
try {
|
|
742
|
+
newContent = await import_promises3.default.readFile(
|
|
743
|
+
import_node_path3.default.join(this.workDir, file),
|
|
744
|
+
"utf-8"
|
|
745
|
+
);
|
|
746
|
+
} catch {
|
|
747
|
+
newContent = "";
|
|
748
|
+
}
|
|
749
|
+
const d = computeDiff({
|
|
750
|
+
file,
|
|
751
|
+
fromVersion: headOid.slice(0, 8),
|
|
752
|
+
toVersion: "(staged)",
|
|
753
|
+
oldContent,
|
|
754
|
+
newContent
|
|
755
|
+
});
|
|
756
|
+
if (d.additions > 0 || d.deletions > 0) diffs.push(d);
|
|
757
|
+
} catch {
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
if (diffs.length > 0) {
|
|
761
|
+
message = await generateLlmMessage(diffs, this.llmProvider, this.log);
|
|
762
|
+
if (message) {
|
|
763
|
+
this.log?.info?.(
|
|
764
|
+
`[mindkeeper] init: LLM-generated commit \u2014 "${message.slice(0, 50)}${message.length > 50 ? "\u2026" : ""}"`
|
|
765
|
+
);
|
|
766
|
+
}
|
|
767
|
+
} else {
|
|
768
|
+
this.log?.info?.("[mindkeeper] init: diffs empty (all files unchanged vs HEAD)");
|
|
769
|
+
}
|
|
770
|
+
} else {
|
|
771
|
+
this.log?.info?.("[mindkeeper] init: no HEAD yet (first commit), LLM skipped");
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (!message) {
|
|
775
|
+
message = generateTemplateMessage(filesToCommit);
|
|
776
|
+
this.log?.info?.(`[mindkeeper] init: using template \u2014 "${message}"`);
|
|
777
|
+
}
|
|
778
|
+
await this.store.commit(message);
|
|
779
|
+
} else {
|
|
780
|
+
this.log?.info?.("[mindkeeper] init: no changed files");
|
|
726
781
|
}
|
|
727
782
|
return { initialFiles: changed.map((e) => e.filepath) };
|
|
728
783
|
}
|
|
@@ -823,6 +878,9 @@ var Tracker = class {
|
|
|
823
878
|
headOid = await this.resolveHead();
|
|
824
879
|
} catch {
|
|
825
880
|
}
|
|
881
|
+
this.log?.info?.(
|
|
882
|
+
`[mindkeeper] autoSnapshot: files=${filesToCommit.length}, headOid=${headOid ? headOid.slice(0, 8) : "none"}, mode=${this.config.commitMessage.mode}, llmProvider=${this.llmProvider ? "yes" : "no"}`
|
|
883
|
+
);
|
|
826
884
|
if (headOid) {
|
|
827
885
|
for (const file of filesToCommit) {
|
|
828
886
|
try {
|
|
@@ -846,10 +904,14 @@ var Tracker = class {
|
|
|
846
904
|
if (d.additions > 0 || d.deletions > 0) {
|
|
847
905
|
diffs.push(d);
|
|
848
906
|
}
|
|
849
|
-
} catch {
|
|
907
|
+
} catch (err) {
|
|
908
|
+
this.log?.warn?.(
|
|
909
|
+
`[mindkeeper] autoSnapshot: diff failed for ${file}: ${err instanceof Error ? err.message : String(err)}`
|
|
910
|
+
);
|
|
850
911
|
}
|
|
851
912
|
}
|
|
852
913
|
}
|
|
914
|
+
this.log?.info?.(`[mindkeeper] autoSnapshot: computed ${diffs.length} non-empty diff(s)`);
|
|
853
915
|
let message = null;
|
|
854
916
|
let usedLlm = false;
|
|
855
917
|
let templateReason = null;
|
|
@@ -857,28 +919,26 @@ var Tracker = class {
|
|
|
857
919
|
if (this.llmProvider) {
|
|
858
920
|
message = await generateLlmMessage(diffs, this.llmProvider, this.log);
|
|
859
921
|
if (message) usedLlm = true;
|
|
860
|
-
else templateReason = "LLM API call failed (check logs above for error)";
|
|
922
|
+
else templateReason = "LLM API call failed (check logs above for error details)";
|
|
861
923
|
} else {
|
|
862
|
-
templateReason = "
|
|
924
|
+
templateReason = "llmProvider is null (createOpenClawLlmProvider returned null \u2014 check startup logs)";
|
|
863
925
|
}
|
|
864
926
|
} else if (this.config.commitMessage.mode === "llm" && diffs.length === 0) {
|
|
865
|
-
templateReason =
|
|
927
|
+
templateReason = headOid ? `diffs empty (${filesToCommit.length} file(s) changed but no textual diff vs HEAD)` : "no HEAD commit yet (first commit), cannot compute diff";
|
|
866
928
|
} else {
|
|
867
|
-
templateReason = "config
|
|
929
|
+
templateReason = `commitMessage.mode="${this.config.commitMessage.mode}" (not "llm")`;
|
|
868
930
|
}
|
|
869
931
|
if (!message) {
|
|
870
932
|
message = generateTemplateMessage(filesToCommit);
|
|
871
933
|
}
|
|
872
|
-
if (
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
);
|
|
881
|
-
}
|
|
934
|
+
if (usedLlm) {
|
|
935
|
+
this.log?.info?.(
|
|
936
|
+
`[mindkeeper] Commit message: LLM \u2713 \u2014 "${message.slice(0, 60)}${message.length > 60 ? "\u2026" : ""}"`
|
|
937
|
+
);
|
|
938
|
+
} else {
|
|
939
|
+
this.log?.warn?.(
|
|
940
|
+
`[mindkeeper] Commit message: TEMPLATE \u2014 reason: ${templateReason}`
|
|
941
|
+
);
|
|
882
942
|
}
|
|
883
943
|
const oid = await this.store.commit(message);
|
|
884
944
|
return {
|
|
@@ -1191,7 +1251,7 @@ function readEnvApiKey(provider) {
|
|
|
1191
1251
|
// src/llm-provider.ts
|
|
1192
1252
|
var MAX_DIFF_CHARS = 4e3;
|
|
1193
1253
|
async function createOpenClawLlmProvider(api) {
|
|
1194
|
-
const modelSpec = resolveModelFromConfig(api.config);
|
|
1254
|
+
const modelSpec = resolveModelFromConfig(api.config, api.log);
|
|
1195
1255
|
if (!modelSpec) {
|
|
1196
1256
|
api.log?.warn?.(
|
|
1197
1257
|
"[mindkeeper] No default model configured in OpenClaw \u2014 LLM commit messages disabled."
|
|
@@ -1207,25 +1267,32 @@ async function createOpenClawLlmProvider(api) {
|
|
|
1207
1267
|
const apiKey = await resolveApiKey(modelSpec.provider);
|
|
1208
1268
|
if (!apiKey) {
|
|
1209
1269
|
api.log?.warn?.(
|
|
1210
|
-
`[mindkeeper] No API key found for provider "${modelSpec.provider}" \u2014 LLM commit messages disabled.`
|
|
1270
|
+
`[mindkeeper] No API key found for provider "${modelSpec.provider}" \u2014 LLM commit messages disabled. Checked: auth-profiles.json + env vars.`
|
|
1211
1271
|
);
|
|
1212
1272
|
return null;
|
|
1213
1273
|
}
|
|
1214
1274
|
api.log?.info?.(
|
|
1215
|
-
`[mindkeeper] LLM commit messages enabled (${modelSpec.provider}/${modelSpec.model}).`
|
|
1275
|
+
`[mindkeeper] LLM commit messages enabled (${modelSpec.provider}/${modelSpec.model}${modelSpec.baseUrl ? `, baseUrl=${modelSpec.baseUrl}` : ""}).`
|
|
1216
1276
|
);
|
|
1217
1277
|
return {
|
|
1218
1278
|
async generateCommitMessage(diffs) {
|
|
1219
1279
|
const diffText = diffs.map((d) => `--- ${d.file} ---
|
|
1220
1280
|
${d.unified}`).join("\n").slice(0, MAX_DIFF_CHARS);
|
|
1281
|
+
api.log?.info?.(
|
|
1282
|
+
`[mindkeeper] Calling LLM for commit message (${diffs.length} diff(s), ${diffText.length} chars)\u2026`
|
|
1283
|
+
);
|
|
1221
1284
|
const { callLlm } = await import("./llm-client.cjs");
|
|
1222
|
-
|
|
1285
|
+
const result = await callLlm({
|
|
1223
1286
|
provider: modelSpec.provider,
|
|
1224
1287
|
model: modelSpec.model,
|
|
1225
1288
|
apiKey,
|
|
1226
1289
|
userPrompt: diffText,
|
|
1227
1290
|
baseUrl: modelSpec.baseUrl
|
|
1228
1291
|
});
|
|
1292
|
+
api.log?.info?.(
|
|
1293
|
+
`[mindkeeper] LLM returned: "${(result ?? "").slice(0, 60)}${(result ?? "").length > 60 ? "\u2026" : ""}"`
|
|
1294
|
+
);
|
|
1295
|
+
return result;
|
|
1229
1296
|
}
|
|
1230
1297
|
};
|
|
1231
1298
|
}
|
|
@@ -1233,10 +1300,13 @@ function isOAuthProvider(provider) {
|
|
|
1233
1300
|
const normalized = normalizeProvider(provider);
|
|
1234
1301
|
return normalized.includes("portal") || normalized.includes("oauth");
|
|
1235
1302
|
}
|
|
1236
|
-
function resolveModelFromConfig(config) {
|
|
1303
|
+
function resolveModelFromConfig(config, log) {
|
|
1237
1304
|
const agents = config?.agents;
|
|
1238
1305
|
const defaults = agents?.defaults;
|
|
1239
1306
|
const raw = defaults?.model;
|
|
1307
|
+
log?.info?.(
|
|
1308
|
+
`[mindkeeper] resolveModel: config.agents=${agents ? "present" : "missing"}, config.agents.defaults=${defaults ? "present" : "missing"}, config.agents.defaults.model=${raw === void 0 ? "undefined" : typeof raw === "string" ? `"${raw}"` : JSON.stringify(raw)}`
|
|
1309
|
+
);
|
|
1240
1310
|
let spec;
|
|
1241
1311
|
if (typeof raw === "string") {
|
|
1242
1312
|
spec = raw.trim();
|
|
@@ -1244,7 +1314,12 @@ function resolveModelFromConfig(config) {
|
|
|
1244
1314
|
const primary = raw.primary;
|
|
1245
1315
|
if (typeof primary === "string") spec = primary.trim();
|
|
1246
1316
|
}
|
|
1247
|
-
if (!spec?.includes("/"))
|
|
1317
|
+
if (!spec?.includes("/")) {
|
|
1318
|
+
log?.warn?.(
|
|
1319
|
+
`[mindkeeper] resolveModel: no valid "provider/model" spec found (got: ${spec === void 0 ? "undefined" : `"${spec}"`})`
|
|
1320
|
+
);
|
|
1321
|
+
return null;
|
|
1322
|
+
}
|
|
1248
1323
|
const slashIdx = spec.indexOf("/");
|
|
1249
1324
|
const provider = spec.slice(0, slashIdx);
|
|
1250
1325
|
const model = spec.slice(slashIdx + 1);
|
|
@@ -1301,9 +1376,9 @@ function resolveBundledSkillDir() {
|
|
|
1301
1376
|
function createWatcherService(api, trackerRef) {
|
|
1302
1377
|
let watcher = null;
|
|
1303
1378
|
const log = {
|
|
1304
|
-
info: (msg) => api.
|
|
1305
|
-
warn: (msg) => api.
|
|
1306
|
-
error: (msg) => api.
|
|
1379
|
+
info: (msg) => api.logger?.info?.(msg),
|
|
1380
|
+
warn: (msg) => api.logger?.warn?.(msg),
|
|
1381
|
+
error: (msg) => api.logger?.error?.(msg)
|
|
1307
1382
|
};
|
|
1308
1383
|
return {
|
|
1309
1384
|
id: "mindkeeper-watcher",
|
|
@@ -1313,11 +1388,17 @@ function createWatcherService(api, trackerRef) {
|
|
|
1313
1388
|
log.warn("[mindkeeper] No workspace directory in service context. Watcher disabled.");
|
|
1314
1389
|
return;
|
|
1315
1390
|
}
|
|
1316
|
-
ensureWorkspaceSkillMirror(workspaceDir, { log: api.
|
|
1391
|
+
ensureWorkspaceSkillMirror(workspaceDir, { log: api.logger });
|
|
1392
|
+
log.info(
|
|
1393
|
+
`[mindkeeper] Service starting: ctx.config=${ctx.config ? "present" : "missing"}, pluginConfig=${api.pluginConfig ? JSON.stringify(api.pluginConfig) : "none"}`
|
|
1394
|
+
);
|
|
1317
1395
|
const llmProvider = await createOpenClawLlmProvider({
|
|
1318
1396
|
config: ctx.config,
|
|
1319
1397
|
log
|
|
1320
1398
|
});
|
|
1399
|
+
log.info(
|
|
1400
|
+
`[mindkeeper] LLM provider: ${llmProvider ? "created successfully" : "null (will use template)"}`
|
|
1401
|
+
);
|
|
1321
1402
|
const tracker = new Tracker({
|
|
1322
1403
|
workDir: workspaceDir,
|
|
1323
1404
|
llmProvider: llmProvider ?? void 0,
|
|
@@ -1326,6 +1407,9 @@ function createWatcherService(api, trackerRef) {
|
|
|
1326
1407
|
});
|
|
1327
1408
|
await tracker.init();
|
|
1328
1409
|
trackerRef.current = tracker;
|
|
1410
|
+
log.info(
|
|
1411
|
+
`[mindkeeper] Tracker config: commitMessage.mode=${tracker.getConfig().commitMessage.mode}`
|
|
1412
|
+
);
|
|
1329
1413
|
watcher = new Watcher({
|
|
1330
1414
|
tracker,
|
|
1331
1415
|
onSnapshot: (commit) => {
|
|
@@ -1363,11 +1447,11 @@ function mindkeeperPlugin(api) {
|
|
|
1363
1447
|
const trackerRef = { current: null };
|
|
1364
1448
|
registerTrackerTools(api, trackerRef);
|
|
1365
1449
|
registerTrackerCli(api, trackerRef);
|
|
1366
|
-
ensureWorkspaceSkillMirror(api.getWorkspaceDir?.(), { log: api.
|
|
1450
|
+
ensureWorkspaceSkillMirror(api.getWorkspaceDir?.(), { log: api.logger });
|
|
1367
1451
|
const watcherService = createWatcherService(api, trackerRef);
|
|
1368
1452
|
api.registerService?.(watcherService);
|
|
1369
1453
|
ensureToolsInConfig(api);
|
|
1370
|
-
api.
|
|
1454
|
+
api.logger?.info?.("[mindkeeper] Plugin loaded.");
|
|
1371
1455
|
}
|
|
1372
1456
|
function ensureToolsInConfig(api) {
|
|
1373
1457
|
const cfg = api.config;
|
|
@@ -1388,5 +1472,5 @@ function ensureToolsInConfig(api) {
|
|
|
1388
1472
|
void writeConfigFile({
|
|
1389
1473
|
...cfg,
|
|
1390
1474
|
tools: { ...cfg.tools, [key]: merged }
|
|
1391
|
-
}).catch((err) => api.
|
|
1475
|
+
}).catch((err) => api.logger?.warn?.(`[mindkeeper] Failed to auto-update tools.${key}:`, String(err)));
|
|
1392
1476
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindkeeper-openclaw",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.33",
|
|
4
4
|
"description": "OpenClaw plugin for mindkeeper: auto-snapshot, diff, and rollback for agent context files",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
"scripts/postinstall-merge-config.cjs",
|
|
30
30
|
"README.md"
|
|
31
31
|
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "node build.mjs",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"clean": "rm -rf dist",
|
|
37
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
38
|
+
"postinstall": "node scripts/postinstall-merge-config.cjs"
|
|
39
|
+
},
|
|
32
40
|
"openclaw": {
|
|
33
41
|
"extensions": [
|
|
34
42
|
"./dist/index.js"
|
|
@@ -51,12 +59,5 @@
|
|
|
51
59
|
},
|
|
52
60
|
"publishConfig": {
|
|
53
61
|
"access": "public"
|
|
54
|
-
},
|
|
55
|
-
"scripts": {
|
|
56
|
-
"build": "node build.mjs",
|
|
57
|
-
"test": "vitest run",
|
|
58
|
-
"typecheck": "tsc --noEmit",
|
|
59
|
-
"clean": "rm -rf dist",
|
|
60
|
-
"postinstall": "node scripts/postinstall-merge-config.cjs"
|
|
61
62
|
}
|
|
62
|
-
}
|
|
63
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 context-vault contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|