@wipcomputer/wip-ldm-os 0.4.64 → 0.4.65
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 +73 -21
- package/dist/bridge/{chunk-QZ4DNVJM.js → chunk-XVIE3HLZ.js} +2 -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/src/bridge/core.ts +1 -0
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.65"
|
|
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
|
@@ -397,10 +397,16 @@ async function installCatalogComponent(c) {
|
|
|
397
397
|
// never get copied to ~/.ldm/extensions/lesa-bridge/dist/. This function fixes that.
|
|
398
398
|
|
|
399
399
|
function deployBridge() {
|
|
400
|
-
const
|
|
400
|
+
const ldmBridgeDir = join(LDM_EXTENSIONS, 'lesa-bridge');
|
|
401
|
+
const ocBridgeDir = join(HOME, '.openclaw', 'extensions', 'lesa-bridge');
|
|
401
402
|
|
|
402
|
-
//
|
|
403
|
-
|
|
403
|
+
// Deploy targets: LDM path (canonical) and OpenClaw path (where the plugin loads)
|
|
404
|
+
const targets = [
|
|
405
|
+
{ dir: ldmBridgeDir, label: '~/.ldm/extensions/lesa-bridge/dist/' },
|
|
406
|
+
{ dir: ocBridgeDir, label: '~/.openclaw/extensions/lesa-bridge/dist/' },
|
|
407
|
+
].filter(t => existsSync(t.dir)); // Only deploy if the extension dir exists
|
|
408
|
+
|
|
409
|
+
if (targets.length === 0) return 0;
|
|
404
410
|
|
|
405
411
|
// Find the npm package bridge files. Try require.resolve first, fall back to known path.
|
|
406
412
|
let bridgeSrc = '';
|
|
@@ -427,13 +433,14 @@ function deployBridge() {
|
|
|
427
433
|
|
|
428
434
|
if (!bridgeSrc || !existsSync(bridgeSrc)) return 0;
|
|
429
435
|
|
|
430
|
-
// Check if files differ
|
|
436
|
+
// Check if files differ (compare against the LDM target, or first available)
|
|
437
|
+
const checkDest = join(targets[0].dir, 'dist');
|
|
431
438
|
let changed = false;
|
|
432
439
|
try {
|
|
433
440
|
const srcFiles = readdirSync(bridgeSrc).filter(f => f.endsWith('.js') || f.endsWith('.d.ts'));
|
|
434
441
|
for (const file of srcFiles) {
|
|
435
442
|
const srcPath = join(bridgeSrc, file);
|
|
436
|
-
const destPath = join(
|
|
443
|
+
const destPath = join(checkDest, file);
|
|
437
444
|
if (!existsSync(destPath)) {
|
|
438
445
|
changed = true;
|
|
439
446
|
break;
|
|
@@ -445,6 +452,17 @@ function deployBridge() {
|
|
|
445
452
|
break;
|
|
446
453
|
}
|
|
447
454
|
}
|
|
455
|
+
// Also check if there are stale files in the target that aren't in the source
|
|
456
|
+
if (!changed) {
|
|
457
|
+
const destFiles = readdirSync(checkDest).filter(f => f.endsWith('.js'));
|
|
458
|
+
const srcFileSet = new Set(srcFiles);
|
|
459
|
+
for (const file of destFiles) {
|
|
460
|
+
if (!srcFileSet.has(file)) {
|
|
461
|
+
changed = true; // stale chunk file found
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
448
466
|
} catch {
|
|
449
467
|
changed = true; // if comparison fails, copy anyway
|
|
450
468
|
}
|
|
@@ -452,23 +470,57 @@ function deployBridge() {
|
|
|
452
470
|
if (!changed) return 0;
|
|
453
471
|
|
|
454
472
|
if (DRY_RUN) {
|
|
455
|
-
console.log(` + would deploy bridge files to
|
|
473
|
+
console.log(` + would deploy bridge files to ${targets.map(t => t.label).join(' + ')}`);
|
|
456
474
|
return 0;
|
|
457
475
|
}
|
|
458
476
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
477
|
+
const srcFiles = readdirSync(bridgeSrc).filter(f => f.endsWith('.js') || f.endsWith('.d.ts'));
|
|
478
|
+
let totalDeployed = 0;
|
|
479
|
+
|
|
480
|
+
for (const target of targets) {
|
|
481
|
+
const dest = join(target.dir, 'dist');
|
|
482
|
+
try {
|
|
483
|
+
mkdirSync(dest, { recursive: true });
|
|
484
|
+
|
|
485
|
+
// Clean stale .js files before copying (chunk hashes change between builds)
|
|
486
|
+
try {
|
|
487
|
+
const existing = readdirSync(dest).filter(f => f.endsWith('.js'));
|
|
488
|
+
const srcFileSet = new Set(srcFiles.filter(f => f.endsWith('.js')));
|
|
489
|
+
for (const file of existing) {
|
|
490
|
+
if (!srcFileSet.has(file)) {
|
|
491
|
+
unlinkSync(join(dest, file));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
} catch {}
|
|
495
|
+
|
|
496
|
+
for (const file of srcFiles) {
|
|
497
|
+
cpSync(join(bridgeSrc, file), join(dest, file));
|
|
498
|
+
}
|
|
499
|
+
console.log(` + bridge deployed to ${target.label} (${srcFiles.length} files)`);
|
|
500
|
+
installLog(`Bridge deployed: ${srcFiles.length} files to ${target.label}`);
|
|
501
|
+
totalDeployed += srcFiles.length;
|
|
502
|
+
} catch (e) {
|
|
503
|
+
console.log(` ! bridge deploy to ${target.label} failed: ${e.message}`);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Re-register MCP server to point to the canonical LDM path
|
|
508
|
+
if (totalDeployed > 0 && existsSync(join(ldmBridgeDir, 'dist', 'mcp-server.js'))) {
|
|
509
|
+
try {
|
|
510
|
+
const mcpPath = join(ldmBridgeDir, 'dist', 'mcp-server.js');
|
|
511
|
+
execSync(`claude mcp add lesa-bridge --scope user -- node ${mcpPath}`, {
|
|
512
|
+
stdio: 'pipe',
|
|
513
|
+
timeout: 10000,
|
|
514
|
+
});
|
|
515
|
+
console.log(` + MCP registration updated: lesa-bridge -> ~/.ldm/extensions/lesa-bridge/dist/mcp-server.js`);
|
|
516
|
+
installLog('MCP registration updated: lesa-bridge -> ~/.ldm/extensions/lesa-bridge/dist/mcp-server.js');
|
|
517
|
+
} catch (e) {
|
|
518
|
+
// Non-fatal: MCP registration is a convenience, not a requirement
|
|
519
|
+
console.log(` ! MCP registration update failed: ${e.message}`);
|
|
520
|
+
}
|
|
471
521
|
}
|
|
522
|
+
|
|
523
|
+
return totalDeployed;
|
|
472
524
|
}
|
|
473
525
|
|
|
474
526
|
// ── ldm init ──
|
|
@@ -892,7 +944,7 @@ async function cmdInit() {
|
|
|
892
944
|
}
|
|
893
945
|
}
|
|
894
946
|
|
|
895
|
-
// Deploy bridge files to
|
|
947
|
+
// Deploy bridge files to all targets and re-register MCP (#245, #251)
|
|
896
948
|
deployBridge();
|
|
897
949
|
|
|
898
950
|
// Clean up dead backup triggers (#207)
|
|
@@ -1266,9 +1318,9 @@ async function cmdInstallCatalog() {
|
|
|
1266
1318
|
|
|
1267
1319
|
autoDetectExtensions();
|
|
1268
1320
|
|
|
1269
|
-
// Deploy bridge files after self-update or on every catalog install (#245)
|
|
1321
|
+
// Deploy bridge files after self-update or on every catalog install (#245, #251)
|
|
1270
1322
|
// After npm install -g, the new bridge files are in the npm package but not
|
|
1271
|
-
// in
|
|
1323
|
+
// in the extension directories. This copies them to both LDM and OpenClaw targets.
|
|
1272
1324
|
deployBridge();
|
|
1273
1325
|
|
|
1274
1326
|
const { detectSystemState, reconcileState, formatReconciliation } = await import('../lib/state.mjs');
|
|
@@ -103,7 +103,8 @@ async function sendMessage(openclawDir, message, options) {
|
|
|
103
103
|
method: "POST",
|
|
104
104
|
headers: {
|
|
105
105
|
Authorization: `Bearer ${token}`,
|
|
106
|
-
"Content-Type": "application/json"
|
|
106
|
+
"Content-Type": "application/json",
|
|
107
|
+
"x-openclaw-scopes": "operator.read,operator.write"
|
|
107
108
|
},
|
|
108
109
|
body: JSON.stringify({
|
|
109
110
|
model: `openclaw/${agentId}`,
|
package/dist/bridge/cli.js
CHANGED
package/dist/bridge/core.js
CHANGED
package/package.json
CHANGED
package/src/bridge/core.ts
CHANGED