@wipcomputer/wip-ldm-os 0.2.4 → 0.2.6
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/README.md +4 -0
- package/SKILL.md +1 -1
- package/bin/ldm.mjs +22 -17
- package/catalog.json +21 -3
- package/lib/state.mjs +21 -58
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -89,6 +89,10 @@ The OS connects your AIs. Add-ons are what they actually use. Each one is a full
|
|
|
89
89
|
- Memory consolidation protocol for AI agents with bounded context windows. A practical guide for remembering memories.
|
|
90
90
|
- [Read more about Dream Weaver Protocol](https://github.com/wipcomputer/dream-weaver-protocol)
|
|
91
91
|
|
|
92
|
+
**OpenClaw**
|
|
93
|
+
- Open-source agent runtime. Run AI agents 24/7 with identity, memory, and tool access. The existence proof for LDM OS.
|
|
94
|
+
- [Read more about OpenClaw](https://github.com/openclaw/openclaw)
|
|
95
|
+
|
|
92
96
|
**Bridge**
|
|
93
97
|
- Cross-platform agent bridge. Enables Claude Code CLI to talk to OpenClaw CLI without a human in the middle.
|
|
94
98
|
- [Read more about Bridge](https://github.com/wipcomputer/wip-bridge)
|
package/SKILL.md
CHANGED
package/bin/ldm.mjs
CHANGED
|
@@ -411,15 +411,26 @@ async function cmdInstallCatalog() {
|
|
|
411
411
|
// Show the real system state
|
|
412
412
|
console.log(formatReconciliation(reconciled));
|
|
413
413
|
|
|
414
|
-
//
|
|
414
|
+
// Check catalog: use registryMatches + cliMatches to detect what's really installed
|
|
415
415
|
const registry = readJSON(REGISTRY_PATH);
|
|
416
416
|
const registeredNames = Object.keys(registry?.extensions || {});
|
|
417
|
+
const reconciledNames = Object.keys(reconciled);
|
|
417
418
|
const components = loadCatalog();
|
|
419
|
+
|
|
420
|
+
function isCatalogItemInstalled(c) {
|
|
421
|
+
// Direct ID match
|
|
422
|
+
if (registeredNames.includes(c.id) || reconciled[c.id]) return true;
|
|
423
|
+
// Check registryMatches (aliases)
|
|
424
|
+
const matches = c.registryMatches || [];
|
|
425
|
+
if (matches.some(m => registeredNames.includes(m) || reconciled[m])) return true;
|
|
426
|
+
// Check CLI binaries
|
|
427
|
+
const cliMatches = c.cliMatches || [];
|
|
428
|
+
if (cliMatches.some(b => state.cliBinaries[b])) return true;
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
|
|
418
432
|
const available = components.filter(c =>
|
|
419
|
-
c.status !== 'coming-soon'
|
|
420
|
-
&& !registeredNames.includes(c.id)
|
|
421
|
-
// Also check if it's in reconciled as external (already installed outside LDM)
|
|
422
|
-
&& !reconciled[c.id]
|
|
433
|
+
c.status !== 'coming-soon' && !isCatalogItemInstalled(c)
|
|
423
434
|
);
|
|
424
435
|
|
|
425
436
|
if (available.length > 0) {
|
|
@@ -428,29 +439,23 @@ async function cmdInstallCatalog() {
|
|
|
428
439
|
console.log(` [ ] ${c.name} ... ${c.description}`);
|
|
429
440
|
}
|
|
430
441
|
console.log('');
|
|
442
|
+
} else {
|
|
443
|
+
console.log(' All catalog components are installed.');
|
|
444
|
+
console.log('');
|
|
431
445
|
}
|
|
432
446
|
|
|
433
447
|
if (DRY_RUN) {
|
|
434
448
|
// Show what an update would do
|
|
435
449
|
const updatable = Object.values(reconciled).filter(e =>
|
|
436
|
-
e.
|
|
437
|
-
);
|
|
438
|
-
const unlinked = Object.values(reconciled).filter(e =>
|
|
439
|
-
e.status === 'installed-unlinked'
|
|
450
|
+
e.registryHasSource
|
|
440
451
|
);
|
|
441
452
|
|
|
442
453
|
if (updatable.length > 0) {
|
|
443
454
|
console.log(` Would update ${updatable.length} extension(s) from source repos.`);
|
|
444
|
-
console.log(' No data (crystal.db,
|
|
455
|
+
console.log(' No data (crystal.db, agent files) would be touched.');
|
|
445
456
|
console.log(' Old versions would be moved to ~/.ldm/_trash/ (never deleted).');
|
|
446
457
|
} else {
|
|
447
|
-
console.log('
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
if (unlinked.length > 0) {
|
|
451
|
-
console.log('');
|
|
452
|
-
console.log(` ${unlinked.length} extension(s) are installed but have no source repo linked.`);
|
|
453
|
-
console.log(' These are safe. Link them with: ldm install <org/repo>');
|
|
458
|
+
console.log(' Everything is up to date. No changes needed.');
|
|
454
459
|
}
|
|
455
460
|
|
|
456
461
|
console.log('');
|
package/catalog.json
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.
|
|
2
|
+
"version": "0.2.0",
|
|
3
3
|
"components": [
|
|
4
4
|
{
|
|
5
5
|
"id": "memory-crystal",
|
|
6
6
|
"name": "Memory Crystal",
|
|
7
7
|
"description": "Persistent memory for your AI. Search, capture, consolidation.",
|
|
8
|
-
"npm": "memory-crystal",
|
|
8
|
+
"npm": "@wipcomputer/memory-crystal",
|
|
9
9
|
"repo": "wipcomputer/memory-crystal",
|
|
10
|
+
"registryMatches": ["memory-crystal"],
|
|
11
|
+
"cliMatches": ["crystal"],
|
|
10
12
|
"recommended": true,
|
|
11
13
|
"status": "stable",
|
|
12
14
|
"postInstall": "crystal doctor"
|
|
@@ -17,6 +19,8 @@
|
|
|
17
19
|
"description": "Release pipeline, license compliance, repo management, identity file protection.",
|
|
18
20
|
"npm": "@wipcomputer/universal-installer",
|
|
19
21
|
"repo": "wipcomputer/wip-ai-devops-toolbox",
|
|
22
|
+
"registryMatches": ["wip-repos", "wip-release", "wip-file-guard", "wip-license-hook", "wip-repo-permissions-hook", "universal-installer", "deploy-public", "post-merge-rename", "wip-license-guard", "wip-repo-init", "wip-readme-format"],
|
|
23
|
+
"cliMatches": ["wip-release", "wip-repos", "wip-file-guard", "wip-install"],
|
|
20
24
|
"recommended": false,
|
|
21
25
|
"status": "stable",
|
|
22
26
|
"postInstall": null
|
|
@@ -27,6 +31,8 @@
|
|
|
27
31
|
"description": "1Password secrets for AI agents.",
|
|
28
32
|
"npm": null,
|
|
29
33
|
"repo": "wipcomputer/wip-1password",
|
|
34
|
+
"registryMatches": ["wip-1password", "op-secrets"],
|
|
35
|
+
"cliMatches": [],
|
|
30
36
|
"recommended": false,
|
|
31
37
|
"status": "stable",
|
|
32
38
|
"postInstall": null
|
|
@@ -37,6 +43,8 @@
|
|
|
37
43
|
"description": "Live markdown viewer for AI pair-editing. Updates render instantly in any browser.",
|
|
38
44
|
"npm": "@wipcomputer/markdown-viewer",
|
|
39
45
|
"repo": "wipcomputer/wip-markdown-viewer",
|
|
46
|
+
"registryMatches": ["wip-markdown-viewer", "markdown-viewer"],
|
|
47
|
+
"cliMatches": ["mdview"],
|
|
40
48
|
"recommended": false,
|
|
41
49
|
"status": "stable",
|
|
42
50
|
"postInstall": null
|
|
@@ -47,6 +55,8 @@
|
|
|
47
55
|
"description": "xAI Grok API. Search the web, search X, generate images, generate video.",
|
|
48
56
|
"npm": null,
|
|
49
57
|
"repo": "wipcomputer/wip-xai-grok",
|
|
58
|
+
"registryMatches": ["wip-xai-grok", "grok-search"],
|
|
59
|
+
"cliMatches": [],
|
|
50
60
|
"recommended": false,
|
|
51
61
|
"status": "stable",
|
|
52
62
|
"postInstall": null
|
|
@@ -57,6 +67,8 @@
|
|
|
57
67
|
"description": "X Platform API. Read posts, search tweets, post, upload media.",
|
|
58
68
|
"npm": null,
|
|
59
69
|
"repo": "wipcomputer/wip-xai-x",
|
|
70
|
+
"registryMatches": ["wip-xai-x"],
|
|
71
|
+
"cliMatches": [],
|
|
60
72
|
"recommended": false,
|
|
61
73
|
"status": "stable",
|
|
62
74
|
"postInstall": null
|
|
@@ -67,6 +79,8 @@
|
|
|
67
79
|
"description": "AI agent platform. Run AI agents 24/7 with identity, memory, and tool access.",
|
|
68
80
|
"npm": null,
|
|
69
81
|
"repo": "openclaw/openclaw",
|
|
82
|
+
"registryMatches": ["openclaw"],
|
|
83
|
+
"cliMatches": ["openclaw"],
|
|
70
84
|
"recommended": false,
|
|
71
85
|
"status": "stable",
|
|
72
86
|
"postInstall": null
|
|
@@ -74,9 +88,11 @@
|
|
|
74
88
|
{
|
|
75
89
|
"id": "dream-weaver-protocol",
|
|
76
90
|
"name": "Dream Weaver Protocol",
|
|
77
|
-
"description": "Memory consolidation protocol for AI agents with bounded context windows.
|
|
91
|
+
"description": "Memory consolidation protocol for AI agents with bounded context windows.",
|
|
78
92
|
"npm": null,
|
|
79
93
|
"repo": "wipcomputer/dream-weaver-protocol",
|
|
94
|
+
"registryMatches": ["dream-weaver-protocol", "dream-weaver"],
|
|
95
|
+
"cliMatches": [],
|
|
80
96
|
"recommended": false,
|
|
81
97
|
"status": "stable",
|
|
82
98
|
"postInstall": null
|
|
@@ -87,6 +103,8 @@
|
|
|
87
103
|
"description": "Cross-platform agent bridge. Enables Claude Code CLI to talk to OpenClaw CLI without a human in the middle.",
|
|
88
104
|
"npm": null,
|
|
89
105
|
"repo": "wipcomputer/wip-bridge",
|
|
106
|
+
"registryMatches": ["wip-bridge", "lesa-bridge"],
|
|
107
|
+
"cliMatches": [],
|
|
90
108
|
"recommended": false,
|
|
91
109
|
"status": "stable",
|
|
92
110
|
"postInstall": null
|
package/lib/state.mjs
CHANGED
|
@@ -83,7 +83,7 @@ function scanExtensionDir(dir) {
|
|
|
83
83
|
function detectCLIBinaries() {
|
|
84
84
|
const knownBins = [
|
|
85
85
|
'crystal', 'mdview', 'wip-release', 'wip-repos', 'wip-file-guard',
|
|
86
|
-
'ldm', 'ldm-scaffold', 'wip-install', 'wip-license',
|
|
86
|
+
'ldm', 'ldm-scaffold', 'wip-install', 'wip-license', 'openclaw',
|
|
87
87
|
];
|
|
88
88
|
|
|
89
89
|
const binaries = {};
|
|
@@ -223,25 +223,19 @@ export function reconcileState(systemState) {
|
|
|
223
223
|
// ── Display ──
|
|
224
224
|
|
|
225
225
|
export function formatReconciliation(reconciled, { verbose = false } = {}) {
|
|
226
|
-
const
|
|
227
|
-
const
|
|
228
|
-
const needsAttention = [];
|
|
229
|
-
const external = [];
|
|
226
|
+
const installed = [];
|
|
227
|
+
const broken = [];
|
|
230
228
|
|
|
231
229
|
for (const entry of Object.values(reconciled)) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
external.push(entry);
|
|
242
|
-
break;
|
|
243
|
-
default:
|
|
244
|
-
needsAttention.push(entry);
|
|
230
|
+
// Hide internal registry issues from normal output
|
|
231
|
+
if (entry.status === 'registered-missing') {
|
|
232
|
+
if (verbose) broken.push(entry);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Everything that's actually deployed, registered, or has an MCP server = installed
|
|
237
|
+
if (entry.deployedLdm || entry.deployedOc || entry.mcpRegistered || entry.inRegistry) {
|
|
238
|
+
installed.push(entry);
|
|
245
239
|
}
|
|
246
240
|
}
|
|
247
241
|
|
|
@@ -252,52 +246,21 @@ export function formatReconciliation(reconciled, { verbose = false } = {}) {
|
|
|
252
246
|
lines.push(' System State');
|
|
253
247
|
lines.push(' ────────────────────────────────────');
|
|
254
248
|
|
|
255
|
-
if (
|
|
249
|
+
if (installed.length > 0) {
|
|
256
250
|
lines.push('');
|
|
257
|
-
lines.push(`
|
|
258
|
-
for (const e of
|
|
259
|
-
const ver = e.ldmVersion || e.registryVersion || '?';
|
|
260
|
-
const ifaces = e.registryInterfaces.length > 0 ? ` (${e.registryInterfaces.join(', ')})` : '';
|
|
261
|
-
const mcp = e.mcpRegistered ? ' [MCP]' : '';
|
|
262
|
-
lines.push(` [x] ${e.name} v${ver}${ifaces}${mcp}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (unlinked.length > 0) {
|
|
267
|
-
lines.push('');
|
|
268
|
-
lines.push(` Installed, no source repo linked (${unlinked.length}):`);
|
|
269
|
-
lines.push(` (These work fine. Link them to enable updates via ldm install.)`);
|
|
270
|
-
for (const e of unlinked.sort(sort)) {
|
|
251
|
+
lines.push(` Installed (${installed.length}):`);
|
|
252
|
+
for (const e of installed.sort(sort)) {
|
|
271
253
|
const ver = e.ldmVersion || e.ocVersion || e.registryVersion || '?';
|
|
272
|
-
const mcp = e.mcpRegistered ? ' [MCP]' : '';
|
|
273
|
-
lines.push(` [
|
|
274
|
-
if (verbose) {
|
|
275
|
-
for (const issue of e.issues) {
|
|
276
|
-
lines.push(` ${issue}`);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
254
|
+
const mcp = e.mcpRegistered ? ' [MCP connected]' : '';
|
|
255
|
+
lines.push(` [x] ${e.name} v${ver}${mcp}`);
|
|
279
256
|
}
|
|
280
257
|
}
|
|
281
258
|
|
|
282
|
-
if (
|
|
259
|
+
if (broken.length > 0) {
|
|
283
260
|
lines.push('');
|
|
284
|
-
lines.push(`
|
|
285
|
-
for (const e of
|
|
286
|
-
|
|
287
|
-
const detail = e.mcpRegistered ? 'MCP registered' : 'extension deployed';
|
|
288
|
-
lines.push(` [ ] ${e.name} v${ver} ... ${detail}`);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (needsAttention.length > 0) {
|
|
293
|
-
lines.push('');
|
|
294
|
-
lines.push(` Needs attention (${needsAttention.length}):`);
|
|
295
|
-
for (const e of needsAttention.sort(sort)) {
|
|
296
|
-
const ver = e.ldmVersion || e.ocVersion || e.registryVersion || '?';
|
|
297
|
-
lines.push(` [!] ${e.name} v${ver} ... ${e.status}`);
|
|
298
|
-
for (const issue of e.issues) {
|
|
299
|
-
lines.push(` ${issue}`);
|
|
300
|
-
}
|
|
261
|
+
lines.push(` Needs cleanup (${broken.length}):`);
|
|
262
|
+
for (const e of broken.sort(sort)) {
|
|
263
|
+
lines.push(` [!] ${e.name} ... ${e.status}`);
|
|
301
264
|
}
|
|
302
265
|
}
|
|
303
266
|
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wipcomputer/wip-ldm-os",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "LDM OS: identity, memory, and sovereignty infrastructure for AI agents",
|
|
6
6
|
"main": "src/boot/boot-hook.mjs",
|
|
7
7
|
"bin": {
|
|
8
|
-
"ldm": "
|
|
9
|
-
"wip-ldm-os": "
|
|
10
|
-
"ldm-scaffold": "
|
|
11
|
-
"ldm-boot-install": "
|
|
8
|
+
"ldm": "bin/ldm.mjs",
|
|
9
|
+
"wip-ldm-os": "bin/ldm.mjs",
|
|
10
|
+
"ldm-scaffold": "bin/scaffold.sh",
|
|
11
|
+
"ldm-boot-install": "src/boot/install-cli.mjs"
|
|
12
12
|
},
|
|
13
13
|
"claudeCode": {
|
|
14
14
|
"hook": {
|