@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 CHANGED
@@ -23,43 +23,42 @@ function timestamp() {
23
23
  }
24
24
 
25
25
  function addHeader(content) {
26
- const header =
27
- `# Installed by openclaw-deterministic v${pkg.version}
28
- # Installed at: ${new Date().toISOString()}
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 backupFile(filePath, backupDir) {
35
- if (fs.existsSync(filePath)) {
36
- const fileName = path.basename(filePath);
37
- fs.copyFileSync(filePath, path.join(backupDir, fileName));
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, targetPath, backupDir) {
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
- if (!fs.existsSync(templatePath)) {
45
- console.error(`Template not found: ${templateName}`);
46
- process.exit(1);
47
- }
47
+ ensureDir(path.dirname(targetPath));
48
48
 
49
- backupFile(targetPath, backupDir);
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: ${targetPath}`);
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
- // Install OPERATING_RULES.md
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(skillsDir, "SKILL.md"),
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 === 0) {
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
- const files = fs.readdirSync(backupDir);
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdotwinter/openclaw-deterministic",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Deterministic governance and memory compaction layer for OpenClaw",
5
5
  "keywords": [
6
6
  "openclaw",