@wipcomputer/wip-ldm-os 0.4.62 → 0.4.63
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/SKILL.md +1 -1
- package/bin/ldm.js +48 -4
- package/catalog.json +2 -0
- package/dist/bridge/{chunk-I5FNBIR2.js → chunk-QZ4DNVJM.js} +1 -1
- package/dist/bridge/cli.js +1 -1
- package/dist/bridge/core.js +1 -1
- package/dist/bridge/mcp-server.js +1 -1
- package/package.json +1 -1
- package/scripts/ldm-backup.sh +18 -9
- package/src/bridge/core.ts +1 -1
package/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ license: MIT
|
|
|
9
9
|
compatibility: Requires git, npm, node. Node.js 18+.
|
|
10
10
|
metadata:
|
|
11
11
|
display-name: "LDM OS"
|
|
12
|
-
version: "0.4.
|
|
12
|
+
version: "0.4.63"
|
|
13
13
|
homepage: "https://github.com/wipcomputer/wip-ldm-os"
|
|
14
14
|
author: "Parker Todd Brooks"
|
|
15
15
|
category: infrastructure
|
package/bin/ldm.js
CHANGED
|
@@ -226,6 +226,22 @@ function cleanDeadBackupTriggers() {
|
|
|
226
226
|
cleaned++;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
// 3. Unload and disable com.wipcomputer.cc-watcher LaunchAgent
|
|
230
|
+
// Broken since Mar 24 migration (old iCloud path, wrong node path).
|
|
231
|
+
// The agent communication channel needs redesign, not screen automation.
|
|
232
|
+
const ccWatcherPlist = join(HOME, 'Library', 'LaunchAgents', 'com.wipcomputer.cc-watcher.plist');
|
|
233
|
+
const ccWatcherDisabled = ccWatcherPlist + '.disabled';
|
|
234
|
+
if (existsSync(ccWatcherPlist)) {
|
|
235
|
+
try { execSync(`launchctl unload "${ccWatcherPlist}" 2>/dev/null`, { stdio: 'pipe' }); } catch {}
|
|
236
|
+
try {
|
|
237
|
+
renameSync(ccWatcherPlist, ccWatcherDisabled);
|
|
238
|
+
} catch {
|
|
239
|
+
try { unlinkSync(ccWatcherPlist); } catch {}
|
|
240
|
+
}
|
|
241
|
+
console.log(' + Disabled dead LaunchAgent: com.wipcomputer.cc-watcher');
|
|
242
|
+
cleaned++;
|
|
243
|
+
}
|
|
244
|
+
|
|
229
245
|
return cleaned;
|
|
230
246
|
}
|
|
231
247
|
|
|
@@ -396,6 +412,32 @@ async function cmdInit() {
|
|
|
396
412
|
join(LDM_ROOT, 'hooks'),
|
|
397
413
|
];
|
|
398
414
|
|
|
415
|
+
// Migrate config-from-home.json into config.json (one-time merge)
|
|
416
|
+
// config-from-home.json held org identity (coAuthors, paths, agents, backup, etc.)
|
|
417
|
+
// config.json held runtime/harness info. Now they are one file.
|
|
418
|
+
const configFromHomePath = join(LDM_ROOT, 'config-from-home.json');
|
|
419
|
+
if (existsSync(configFromHomePath) && existsSync(join(LDM_ROOT, 'config.json'))) {
|
|
420
|
+
try {
|
|
421
|
+
const existing = JSON.parse(readFileSync(join(LDM_ROOT, 'config.json'), 'utf8'));
|
|
422
|
+
const fromHome = JSON.parse(readFileSync(configFromHomePath, 'utf8'));
|
|
423
|
+
// Merge: config-from-home.json wins where keys overlap (richer data)
|
|
424
|
+
const merged = { ...existing, ...fromHome };
|
|
425
|
+
// Preserve harnesses from existing config (not in config-from-home.json)
|
|
426
|
+
if (existing.harnesses) merged.harnesses = existing.harnesses;
|
|
427
|
+
// Preserve version and created from existing config
|
|
428
|
+
if (existing.version) merged.version = existing.version;
|
|
429
|
+
if (existing.created) merged.created = existing.created;
|
|
430
|
+
// Update timestamp
|
|
431
|
+
merged.updatedAt = new Date().toISOString();
|
|
432
|
+
writeFileSync(join(LDM_ROOT, 'config.json'), JSON.stringify(merged, null, 2) + '\n');
|
|
433
|
+
renameSync(configFromHomePath, configFromHomePath + '.migrated');
|
|
434
|
+
console.log(` + config-from-home.json merged into config.json`);
|
|
435
|
+
console.log(` + config-from-home.json renamed to config-from-home.json.migrated`);
|
|
436
|
+
} catch (e) {
|
|
437
|
+
console.log(` ! config-from-home.json migration failed: ${e.message}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
|
|
399
441
|
// Scaffold per-agent memory dirs
|
|
400
442
|
try {
|
|
401
443
|
const config = JSON.parse(readFileSync(join(LDM_ROOT, 'config.json'), 'utf8'));
|
|
@@ -674,10 +716,9 @@ async function cmdInit() {
|
|
|
674
716
|
mkdirSync(docsDest, { recursive: true });
|
|
675
717
|
let docsCount = 0;
|
|
676
718
|
|
|
677
|
-
// Build template values from
|
|
678
|
-
//
|
|
679
|
-
const
|
|
680
|
-
const sc = settingsConfig;
|
|
719
|
+
// Build template values from ~/.ldm/config.json (unified config)
|
|
720
|
+
// Legacy: settings/config.json was a separate file, now merged into config.json
|
|
721
|
+
const sc = ldmConfig;
|
|
681
722
|
const lc = ldmConfig;
|
|
682
723
|
|
|
683
724
|
// Agents from settings config (rich objects with harness/machine/prefix)
|
|
@@ -1384,6 +1425,9 @@ async function cmdInstallCatalog() {
|
|
|
1384
1425
|
return matches.includes(name) || c.id === name;
|
|
1385
1426
|
});
|
|
1386
1427
|
|
|
1428
|
+
// Skip pinned components (e.g. OpenClaw). Upgrades must be explicit.
|
|
1429
|
+
if (catalogEntry?.pinned) continue;
|
|
1430
|
+
|
|
1387
1431
|
// Fallback: use repository.url from extension's package.json (#82)
|
|
1388
1432
|
let repoUrl = catalogEntry?.repo || null;
|
|
1389
1433
|
if (!repoUrl && extPkg?.repository) {
|
package/catalog.json
CHANGED
|
@@ -255,6 +255,8 @@
|
|
|
255
255
|
],
|
|
256
256
|
"recommended": false,
|
|
257
257
|
"status": "stable",
|
|
258
|
+
"pinned": true,
|
|
259
|
+
"pinnedReason": "OpenClaw is the runtime. Upgrades overwrite dist patches and can change API behavior. Use: ldm upgrade openclaw",
|
|
258
260
|
"postInstall": null,
|
|
259
261
|
"installs": {
|
|
260
262
|
"cli": [
|
package/dist/bridge/cli.js
CHANGED
package/dist/bridge/core.js
CHANGED
package/package.json
CHANGED
package/scripts/ldm-backup.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# ldm-backup.sh — Unified backup for LDM OS
|
|
3
|
-
# Backs up: ~/.ldm/, ~/.openclaw/, ~/.claude/,
|
|
3
|
+
# Backs up: ~/.ldm/, ~/.openclaw/, ~/.claude/, $WORKSPACE/
|
|
4
4
|
# Handles SQLite safely (sqlite3 .backup). Tars to iCloud for offsite.
|
|
5
5
|
#
|
|
6
6
|
# Source of truth: wip-ldm-os-private/scripts/ldm-backup.sh
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# ldm-backup.sh --keep 14 # keep last 14 backups (default: 7)
|
|
13
13
|
# ldm-backup.sh --include-secrets # include ~/.ldm/secrets/
|
|
14
14
|
#
|
|
15
|
-
# Config: ~/.ldm/config.json (workspace path
|
|
15
|
+
# Config: ~/.ldm/config.json (workspace path, backup settings, iCloud path)
|
|
16
16
|
|
|
17
17
|
set -euo pipefail
|
|
18
18
|
|
|
@@ -45,20 +45,29 @@ if [ -z "$WORKSPACE" ]; then
|
|
|
45
45
|
echo "WARNING: No workspace in ~/.ldm/config.json. Skipping workspace backup."
|
|
46
46
|
fi
|
|
47
47
|
|
|
48
|
-
# Read
|
|
48
|
+
# Read org name from config (used for tar filename)
|
|
49
|
+
ORG=""
|
|
50
|
+
if [ -f "$LDM_HOME/config.json" ]; then
|
|
51
|
+
ORG=$(python3 -c "import json; print(json.load(open('$LDM_HOME/config.json')).get('org',''))" 2>/dev/null || true)
|
|
52
|
+
fi
|
|
53
|
+
if [ -z "$ORG" ]; then
|
|
54
|
+
ORG="workspace"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Read iCloud backup path from ~/.ldm/config.json
|
|
49
58
|
ICLOUD_BACKUP=""
|
|
50
|
-
if [ -
|
|
59
|
+
if [ -f "$LDM_HOME/config.json" ]; then
|
|
51
60
|
ICLOUD_BACKUP=$(python3 -c "
|
|
52
61
|
import json, os
|
|
53
|
-
c = json.load(open('$
|
|
62
|
+
c = json.load(open('$LDM_HOME/config.json'))
|
|
54
63
|
p = c.get('paths',{}).get('icloudBackup','')
|
|
55
64
|
print(os.path.expanduser(p))
|
|
56
65
|
" 2>/dev/null || true)
|
|
57
66
|
fi
|
|
58
67
|
|
|
59
|
-
# Read keep from
|
|
60
|
-
if [ -
|
|
61
|
-
CONFIG_KEEP=$(python3 -c "import json; print(json.load(open('$
|
|
68
|
+
# Read keep from ~/.ldm/config.json (override if set there)
|
|
69
|
+
if [ -f "$LDM_HOME/config.json" ]; then
|
|
70
|
+
CONFIG_KEEP=$(python3 -c "import json; print(json.load(open('$LDM_HOME/config.json')).get('backup',{}).get('keep',0))" 2>/dev/null || true)
|
|
62
71
|
if [ -n "$CONFIG_KEEP" ] && [ "$CONFIG_KEEP" -gt 0 ] 2>/dev/null; then
|
|
63
72
|
KEEP="$CONFIG_KEEP"
|
|
64
73
|
fi
|
|
@@ -211,7 +220,7 @@ if [ -n "$WORKSPACE" ] && [ -d "$WORKSPACE" ]; then
|
|
|
211
220
|
echo " ERROR: Workspace estimated at ${ESTIMATED_KB}KB (>10GB). Aborting tar to prevent disk fill."
|
|
212
221
|
echo " Check for large directories: du -sh $WORKSPACE/*/"
|
|
213
222
|
else
|
|
214
|
-
tar -cf "$DEST
|
|
223
|
+
tar -cf "$DEST/$ORG.tar" \
|
|
215
224
|
--exclude "node_modules" \
|
|
216
225
|
--exclude ".git/objects" \
|
|
217
226
|
--exclude ".DS_Store" \
|