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.
Files changed (3) hide show
  1. package/dist/index.js +115 -31
  2. package/package.json +10 -9
  3. 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
- await this.store.addFiles(changed.map((e) => e.filepath));
724
- const msg = generateTemplateMessage(changed.map((e) => e.filepath));
725
- await this.store.commit(msg);
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 = "LLM provider not configured (no default model or API key in OpenClaw)";
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 = "first commit or no diff (no previous version to compare, diffs.length=0)";
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: commitMessage.mode is 'template'";
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 (this.log) {
873
- if (usedLlm) {
874
- this.log.info?.(
875
- `[mindkeeper] Commit message: LLM-generated \u2014 "${message.slice(0, 50)}${message.length > 50 ? "\u2026" : ""}"`
876
- );
877
- } else {
878
- this.log.warn?.(
879
- `[mindkeeper] Commit message: template \u2014 reason: ${templateReason}`
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
- return callLlm({
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("/")) return null;
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.log?.info?.(msg),
1305
- warn: (msg) => api.log?.warn?.(msg),
1306
- error: (msg) => api.log?.error?.(msg)
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.log });
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.log });
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.log?.info?.("[mindkeeper] Plugin loaded.");
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.log?.warn?.(`[mindkeeper] Failed to auto-update tools.${key}:`, String(err)));
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.31",
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.