@sdotwinter/openclaw-deterministic 0.1.4 → 0.2.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/bin/install.js +21 -38
- package/bin/revert.js +21 -11
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -23,43 +23,42 @@ function timestamp() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function addHeader(content) {
|
|
26
|
-
|
|
27
|
-
`# Installed by openclaw-deterministic v${pkg.version}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return header + content;
|
|
26
|
+
return (
|
|
27
|
+
`# Installed by openclaw-deterministic v${pkg.version}\n` +
|
|
28
|
+
`# Installed at: ${new Date().toISOString()}\n\n` +
|
|
29
|
+
content
|
|
30
|
+
);
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
function
|
|
35
|
-
if (fs.existsSync(filePath))
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
function backupRelative(filePath, backupDir) {
|
|
34
|
+
if (!fs.existsSync(filePath)) return;
|
|
35
|
+
|
|
36
|
+
const relativePath = path.relative(WORKSPACE_DIR, filePath);
|
|
37
|
+
const backupTarget = path.join(backupDir, relativePath);
|
|
38
|
+
|
|
39
|
+
ensureDir(path.dirname(backupTarget));
|
|
40
|
+
fs.copyFileSync(filePath, backupTarget);
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
function installFile(templateName,
|
|
43
|
+
function installFile(templateName, relativeTargetPath, backupDir) {
|
|
42
44
|
const templatePath = path.join(TEMPLATES_DIR, templateName);
|
|
45
|
+
const targetPath = path.join(WORKSPACE_DIR, relativeTargetPath);
|
|
43
46
|
|
|
44
|
-
|
|
45
|
-
console.error(`Template not found: ${templateName}`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
47
|
+
ensureDir(path.dirname(targetPath));
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
backupRelative(targetPath, backupDir);
|
|
50
50
|
|
|
51
51
|
const templateContent = fs.readFileSync(templatePath, "utf8");
|
|
52
52
|
const stampedContent = addHeader(templateContent);
|
|
53
53
|
|
|
54
54
|
fs.writeFileSync(targetPath, stampedContent, "utf8");
|
|
55
55
|
|
|
56
|
-
console.log(`Installed: ${
|
|
56
|
+
console.log(`Installed: ${relativeTargetPath}`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function runInstall() {
|
|
60
60
|
if (!fs.existsSync(OPENCLAW_DIR)) {
|
|
61
61
|
console.error("OpenClaw directory not found.");
|
|
62
|
-
console.error("Install OpenClaw first: npm i -g openclaw && openclaw onboard");
|
|
63
62
|
process.exit(1);
|
|
64
63
|
}
|
|
65
64
|
|
|
@@ -72,27 +71,11 @@ function runInstall() {
|
|
|
72
71
|
console.log("Creating deterministic backup snapshot...");
|
|
73
72
|
console.log(`Backup location: ${backupDir}`);
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
installFile(
|
|
77
|
-
"OPERATING_RULES.md",
|
|
78
|
-
path.join(WORKSPACE_DIR, "OPERATING_RULES.md"),
|
|
79
|
-
backupDir
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
// Install deterministic SOUL overlay
|
|
83
|
-
installFile(
|
|
84
|
-
"SOUL.deterministic.md",
|
|
85
|
-
path.join(WORKSPACE_DIR, "SOUL.deterministic.md"),
|
|
86
|
-
backupDir
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
// Install memory-compactor skill
|
|
90
|
-
const skillsDir = path.join(WORKSPACE_DIR, "skills", "memory-compactor");
|
|
91
|
-
ensureDir(skillsDir);
|
|
92
|
-
|
|
74
|
+
installFile("OPERATING_RULES.md", "OPERATING_RULES.md", backupDir);
|
|
75
|
+
installFile("SOUL.deterministic.md", "SOUL.deterministic.md", backupDir);
|
|
93
76
|
installFile(
|
|
94
77
|
"memory-compactor.SKILL.md",
|
|
95
|
-
path.join(
|
|
78
|
+
path.join("skills", "memory-compactor", "SKILL.md"),
|
|
96
79
|
backupDir
|
|
97
80
|
);
|
|
98
81
|
|
package/bin/revert.js
CHANGED
|
@@ -8,7 +8,6 @@ const OPENCLAW_DIR = path.join(os.homedir(), ".openclaw");
|
|
|
8
8
|
const WORKSPACE_DIR = path.join(OPENCLAW_DIR, "workspace");
|
|
9
9
|
const BACKUP_ROOT = path.join(OPENCLAW_DIR, "backups", "deterministic");
|
|
10
10
|
|
|
11
|
-
// Remove the first argument ("revert")
|
|
12
11
|
const args = process.argv.slice(3);
|
|
13
12
|
|
|
14
13
|
function listBackups() {
|
|
@@ -18,7 +17,7 @@ function listBackups() {
|
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
const dirs = fs.readdirSync(BACKUP_ROOT);
|
|
21
|
-
if (dirs.length
|
|
20
|
+
if (!dirs.length) {
|
|
22
21
|
console.log("No backups found.");
|
|
23
22
|
return;
|
|
24
23
|
}
|
|
@@ -27,6 +26,25 @@ function listBackups() {
|
|
|
27
26
|
dirs.forEach(d => console.log(`- ${d}`));
|
|
28
27
|
}
|
|
29
28
|
|
|
29
|
+
function restoreDirectoryRecursive(srcDir, destDir) {
|
|
30
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
31
|
+
|
|
32
|
+
entries.forEach(entry => {
|
|
33
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
34
|
+
const destPath = path.join(destDir, entry.name);
|
|
35
|
+
|
|
36
|
+
if (entry.isDirectory()) {
|
|
37
|
+
if (!fs.existsSync(destPath)) {
|
|
38
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
restoreDirectoryRecursive(srcPath, destPath);
|
|
41
|
+
} else {
|
|
42
|
+
fs.copyFileSync(srcPath, destPath);
|
|
43
|
+
console.log(`Restored: ${path.relative(WORKSPACE_DIR, destPath)}`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
30
48
|
function restoreBackup(timestamp) {
|
|
31
49
|
const backupDir = path.join(BACKUP_ROOT, timestamp);
|
|
32
50
|
|
|
@@ -35,15 +53,7 @@ function restoreBackup(timestamp) {
|
|
|
35
53
|
process.exit(1);
|
|
36
54
|
}
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
files.forEach(file => {
|
|
41
|
-
const src = path.join(backupDir, file);
|
|
42
|
-
const dest = path.join(WORKSPACE_DIR, file);
|
|
43
|
-
|
|
44
|
-
fs.copyFileSync(src, dest);
|
|
45
|
-
console.log(`Restored: ${file}`);
|
|
46
|
-
});
|
|
56
|
+
restoreDirectoryRecursive(backupDir, WORKSPACE_DIR);
|
|
47
57
|
|
|
48
58
|
console.log("Revert complete.");
|
|
49
59
|
}
|