mindkeeper-openclaw 0.2.23 → 0.2.25
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 +52 -21
- package/package.json +4 -2
- package/scripts/postinstall-merge-config.cjs +3 -2
package/dist/index.js
CHANGED
|
@@ -405,12 +405,12 @@ var IsomorphicGitStore = class {
|
|
|
405
405
|
* when gitdir is separated from the work directory.
|
|
406
406
|
*/
|
|
407
407
|
async getChangedFiles(filepaths) {
|
|
408
|
-
const filesToCheck = filepaths ?? await this.listWorkdirFiles();
|
|
409
408
|
let headOid = null;
|
|
410
409
|
try {
|
|
411
410
|
headOid = await import_isomorphic_git.default.resolveRef({ fs: import_node_fs.default, dir: this.workDir, gitdir: this.gitDir, ref: "HEAD" });
|
|
412
411
|
} catch {
|
|
413
412
|
}
|
|
413
|
+
const filesToCheck = filepaths ?? await this.listTrackedCandidates(headOid);
|
|
414
414
|
const entries = [];
|
|
415
415
|
for (const filepath of filesToCheck) {
|
|
416
416
|
const fullPath = import_node_path.default.join(this.workDir, filepath);
|
|
@@ -443,6 +443,14 @@ var IsomorphicGitStore = class {
|
|
|
443
443
|
}
|
|
444
444
|
return entries;
|
|
445
445
|
}
|
|
446
|
+
async listTrackedCandidates(headOid) {
|
|
447
|
+
const workdirFiles = await this.listWorkdirFiles();
|
|
448
|
+
if (!headOid) {
|
|
449
|
+
return workdirFiles;
|
|
450
|
+
}
|
|
451
|
+
const headFiles = await this.getCommitFiles(headOid);
|
|
452
|
+
return Array.from(/* @__PURE__ */ new Set([...workdirFiles, ...headFiles]));
|
|
453
|
+
}
|
|
446
454
|
async listWorkdirFiles() {
|
|
447
455
|
const files = [];
|
|
448
456
|
await this.walkDir(this.workDir, this.workDir, files);
|
|
@@ -512,7 +520,7 @@ var DEFAULT_CONFIG = {
|
|
|
512
520
|
debounceMs: 3e4
|
|
513
521
|
},
|
|
514
522
|
commitMessage: {
|
|
515
|
-
mode: "
|
|
523
|
+
mode: "llm"
|
|
516
524
|
}
|
|
517
525
|
};
|
|
518
526
|
var SensitiveFieldError = class extends Error {
|
|
@@ -684,6 +692,7 @@ var GITDIR_NAME = ".mindkeeper";
|
|
|
684
692
|
var Tracker = class {
|
|
685
693
|
store;
|
|
686
694
|
config;
|
|
695
|
+
configLoaded;
|
|
687
696
|
llmProvider;
|
|
688
697
|
workDir;
|
|
689
698
|
gitDir;
|
|
@@ -692,6 +701,7 @@ var Tracker = class {
|
|
|
692
701
|
this.workDir = import_node_path3.default.resolve(options.workDir);
|
|
693
702
|
this.gitDir = options.gitDir ? import_node_path3.default.resolve(options.gitDir) : import_node_path3.default.join(this.workDir, GITDIR_NAME);
|
|
694
703
|
this.config = options.config ?? getDefaultConfig();
|
|
704
|
+
this.configLoaded = options.config !== void 0;
|
|
695
705
|
this.configOverrides = options.configOverrides;
|
|
696
706
|
this.llmProvider = options.llmProvider;
|
|
697
707
|
this.store = new IsomorphicGitStore({
|
|
@@ -700,7 +710,7 @@ var Tracker = class {
|
|
|
700
710
|
});
|
|
701
711
|
}
|
|
702
712
|
async init() {
|
|
703
|
-
|
|
713
|
+
await this.ensureConfigLoaded();
|
|
704
714
|
await this.store.init();
|
|
705
715
|
await this.ensureGitignore();
|
|
706
716
|
const changed = await this.getTrackedChangedFiles();
|
|
@@ -712,6 +722,7 @@ var Tracker = class {
|
|
|
712
722
|
return { initialFiles: changed.map((e) => e.filepath) };
|
|
713
723
|
}
|
|
714
724
|
async snapshot(options) {
|
|
725
|
+
await this.ensureConfigLoaded();
|
|
715
726
|
const changed = await this.getTrackedChangedFiles();
|
|
716
727
|
const filesToCommit = changed.map((e) => e.filepath);
|
|
717
728
|
if (filesToCommit.length > 0) {
|
|
@@ -777,21 +788,11 @@ var Tracker = class {
|
|
|
777
788
|
};
|
|
778
789
|
}
|
|
779
790
|
async status() {
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
await this.resolveHead();
|
|
783
|
-
initialized = true;
|
|
784
|
-
} catch {
|
|
785
|
-
initialized = false;
|
|
786
|
-
}
|
|
791
|
+
await this.ensureConfigLoaded();
|
|
792
|
+
const initialized = await this.isInitialized();
|
|
787
793
|
const pendingChanges = initialized ? await this.getTrackedChangedFiles() : [];
|
|
788
794
|
const snapshots = initialized ? await this.store.listTags() : [];
|
|
789
|
-
const
|
|
790
|
-
let trackedFileCount = 0;
|
|
791
|
-
if (initialized) {
|
|
792
|
-
const allChanged = await this.store.getChangedFiles();
|
|
793
|
-
trackedFileCount = allChanged.length + pendingChanges.length;
|
|
794
|
-
}
|
|
795
|
+
const trackedFileCount = initialized ? await this.getTrackedFileCount() : 0;
|
|
795
796
|
return {
|
|
796
797
|
initialized,
|
|
797
798
|
workDir: this.workDir,
|
|
@@ -802,6 +803,7 @@ var Tracker = class {
|
|
|
802
803
|
};
|
|
803
804
|
}
|
|
804
805
|
async autoSnapshot() {
|
|
806
|
+
await this.ensureConfigLoaded();
|
|
805
807
|
const changed = await this.getTrackedChangedFiles();
|
|
806
808
|
if (changed.length === 0) return null;
|
|
807
809
|
const filesToCommit = changed.map((e) => e.filepath);
|
|
@@ -842,6 +844,16 @@ var Tracker = class {
|
|
|
842
844
|
const allChanged = await this.store.getChangedFiles();
|
|
843
845
|
return allChanged.filter((entry) => this.isTracked(entry.filepath));
|
|
844
846
|
}
|
|
847
|
+
async getTrackedFileCount() {
|
|
848
|
+
const files = new Set(await this.store.listWorkdirFiles());
|
|
849
|
+
const headOid = await this.resolveHead().catch(() => null);
|
|
850
|
+
if (headOid) {
|
|
851
|
+
for (const filepath of await this.store.getCommitFiles(headOid)) {
|
|
852
|
+
files.add(filepath);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
return Array.from(files).filter((filepath) => this.isTracked(filepath)).length;
|
|
856
|
+
}
|
|
845
857
|
isTracked(filepath) {
|
|
846
858
|
const allExcluded = [...this.config.tracking.exclude, ...ALWAYS_EXCLUDED];
|
|
847
859
|
for (const pattern of allExcluded) {
|
|
@@ -852,6 +864,21 @@ var Tracker = class {
|
|
|
852
864
|
}
|
|
853
865
|
return false;
|
|
854
866
|
}
|
|
867
|
+
async ensureConfigLoaded() {
|
|
868
|
+
if (this.configLoaded) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
this.config = await loadConfig(this.workDir, this.configOverrides);
|
|
872
|
+
this.configLoaded = true;
|
|
873
|
+
}
|
|
874
|
+
async isInitialized() {
|
|
875
|
+
try {
|
|
876
|
+
await import_promises3.default.access(import_node_path3.default.join(this.gitDir, "HEAD"));
|
|
877
|
+
return true;
|
|
878
|
+
} catch {
|
|
879
|
+
return false;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
855
882
|
async resolveHead() {
|
|
856
883
|
const git2 = await import("isomorphic-git");
|
|
857
884
|
const fs2 = await import("node:fs");
|
|
@@ -873,7 +900,11 @@ var Tracker = class {
|
|
|
873
900
|
${entry}
|
|
874
901
|
`;
|
|
875
902
|
await import_promises3.default.writeFile(gitignorePath, newContent, "utf-8");
|
|
876
|
-
} catch {
|
|
903
|
+
} catch (err) {
|
|
904
|
+
const code = err?.code;
|
|
905
|
+
if (code !== "ENOENT") {
|
|
906
|
+
throw err;
|
|
907
|
+
}
|
|
877
908
|
await import_promises3.default.writeFile(gitignorePath, `${entry}
|
|
878
909
|
`, "utf-8");
|
|
879
910
|
}
|
|
@@ -1167,11 +1198,10 @@ function createWatcherService(api, trackerRef) {
|
|
|
1167
1198
|
config: ctx.config,
|
|
1168
1199
|
log
|
|
1169
1200
|
});
|
|
1170
|
-
const configOverrides = api.pluginConfig;
|
|
1171
1201
|
const tracker = new Tracker({
|
|
1172
1202
|
workDir: workspaceDir,
|
|
1173
1203
|
llmProvider: llmProvider ?? void 0,
|
|
1174
|
-
configOverrides:
|
|
1204
|
+
configOverrides: api.pluginConfig
|
|
1175
1205
|
});
|
|
1176
1206
|
await tracker.init();
|
|
1177
1207
|
trackerRef.current = tracker;
|
|
@@ -1223,8 +1253,9 @@ function ensureToolsInConfig(api) {
|
|
|
1223
1253
|
if (!cfg || !writeConfigFile) return;
|
|
1224
1254
|
const allow = cfg.tools?.allow ?? [];
|
|
1225
1255
|
const alsoAllow = cfg.tools?.alsoAllow ?? [];
|
|
1226
|
-
const
|
|
1227
|
-
const
|
|
1256
|
+
const hasAllow = Array.isArray(cfg.tools?.allow);
|
|
1257
|
+
const target = hasAllow ? allow : alsoAllow;
|
|
1258
|
+
const key = hasAllow ? "allow" : "alsoAllow";
|
|
1228
1259
|
const existing = new Set(
|
|
1229
1260
|
target.map((e) => String(e).trim().toLowerCase()).filter(Boolean)
|
|
1230
1261
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mindkeeper-openclaw",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.25",
|
|
4
4
|
"description": "OpenClaw plugin for mindkeeper: auto-snapshot, diff, and rollback for agent context files",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openclaw",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "node build.mjs",
|
|
34
|
+
"test": "vitest run",
|
|
34
35
|
"typecheck": "tsc --noEmit",
|
|
35
36
|
"clean": "rm -rf dist",
|
|
36
37
|
"prepublishOnly": "npm run clean && npm run build",
|
|
@@ -50,7 +51,8 @@
|
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@types/node": "^22.0.0",
|
|
52
53
|
"esbuild": "^0.27.3",
|
|
53
|
-
"typescript": "^5.7.0"
|
|
54
|
+
"typescript": "^5.7.0",
|
|
55
|
+
"vitest": "^3.2.4"
|
|
54
56
|
},
|
|
55
57
|
"engines": {
|
|
56
58
|
"node": ">=22.0.0"
|
|
@@ -55,8 +55,9 @@ function run() {
|
|
|
55
55
|
|
|
56
56
|
const allow = cfg.tools?.allow ?? [];
|
|
57
57
|
const alsoAllow = cfg.tools?.alsoAllow ?? [];
|
|
58
|
-
const
|
|
59
|
-
const
|
|
58
|
+
const hasAllow = Array.isArray(cfg.tools?.allow);
|
|
59
|
+
const target = hasAllow ? allow : alsoAllow;
|
|
60
|
+
const key = hasAllow ? "allow" : "alsoAllow";
|
|
60
61
|
|
|
61
62
|
const existing = new Set(
|
|
62
63
|
target.map((e) => String(e).trim().toLowerCase()).filter(Boolean),
|