@wipcomputer/wip-ldm-os 0.4.85-alpha.11 → 0.4.85-alpha.13
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/ldm.js
CHANGED
|
@@ -229,6 +229,58 @@ function checkCliVersion() {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
function selectedLdmNpmTrack() {
|
|
233
|
+
return ALPHA_FLAG ? 'alpha' : BETA_FLAG ? 'beta' : 'latest';
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function selectedLdmTrackLabel(npmTag) {
|
|
237
|
+
return npmTag === 'latest' ? '' : ` (${npmTag} track)`;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function latestLdmCliForSelectedTrack() {
|
|
241
|
+
const npmTag = selectedLdmNpmTrack();
|
|
242
|
+
const npmViewCmd = npmTag === 'latest'
|
|
243
|
+
? 'npm view @wipcomputer/wip-ldm-os version 2>/dev/null'
|
|
244
|
+
: `npm view @wipcomputer/wip-ldm-os dist-tags.${npmTag} 2>/dev/null`;
|
|
245
|
+
const latest = execSync(npmViewCmd, {
|
|
246
|
+
encoding: 'utf8',
|
|
247
|
+
timeout: 15000,
|
|
248
|
+
}).trim();
|
|
249
|
+
return { latest, npmTag };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function maybeSelfUpdateLdmCliBeforeInstall() {
|
|
253
|
+
// This shared preflight covers both bare `ldm install` and targeted
|
|
254
|
+
// `ldm install <app>`. Dry runs never update, but still disclose skew.
|
|
255
|
+
if (process.env.LDM_SELF_UPDATED) return;
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
const { latest, npmTag } = latestLdmCliForSelectedTrack();
|
|
259
|
+
if (!latest || !semverNewer(latest, PKG_VERSION)) return;
|
|
260
|
+
|
|
261
|
+
const trackLabel = selectedLdmTrackLabel(npmTag);
|
|
262
|
+
|
|
263
|
+
if (DRY_RUN) {
|
|
264
|
+
console.log(` LDM OS CLI v${PKG_VERSION} -> v${latest}${trackLabel} is available.`);
|
|
265
|
+
console.log(` Dry run only: continuing with v${PKG_VERSION}.`);
|
|
266
|
+
console.log('');
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
console.log(` LDM OS CLI v${PKG_VERSION} -> v${latest}${trackLabel}. Updating first...`);
|
|
271
|
+
try {
|
|
272
|
+
execSync(`npm install -g @wipcomputer/wip-ldm-os@${latest}`, { stdio: 'inherit', timeout: 60000 });
|
|
273
|
+
console.log(` CLI updated to v${latest}. Re-running with new code...`);
|
|
274
|
+
console.log('');
|
|
275
|
+
const reArgs = process.argv.slice(2).join(' ') || 'install';
|
|
276
|
+
execSync(`LDM_SELF_UPDATED=1 ldm ${reArgs}`, { stdio: 'inherit' });
|
|
277
|
+
process.exit(0);
|
|
278
|
+
} catch (e) {
|
|
279
|
+
console.log(` ! Self-update failed: ${e.message}. Continuing with v${PKG_VERSION}.`);
|
|
280
|
+
}
|
|
281
|
+
} catch {}
|
|
282
|
+
}
|
|
283
|
+
|
|
232
284
|
// ── Dead backup trigger cleanup (#207) ──
|
|
233
285
|
// Three backup systems were competing. Only ai.openclaw.ldm-backup (3am) works.
|
|
234
286
|
// This removes: broken cron entry (LDMDevTools.app), old com.wipcomputer.daily-backup.
|
|
@@ -1476,6 +1528,8 @@ async function cmdInstall() {
|
|
|
1476
1528
|
process.exit(0);
|
|
1477
1529
|
}
|
|
1478
1530
|
|
|
1531
|
+
maybeSelfUpdateLdmCliBeforeInstall();
|
|
1532
|
+
|
|
1479
1533
|
// Find the target (skip flags)
|
|
1480
1534
|
const target = args.slice(1).find(a => !a.startsWith('--'));
|
|
1481
1535
|
|
|
@@ -1921,38 +1975,6 @@ async function cmdInstallCatalog() {
|
|
|
1921
1975
|
// No lock here. cmdInstall() already holds it when calling this.
|
|
1922
1976
|
installLog(`ldm install started (v${PKG_VERSION}, DRY_RUN=${DRY_RUN})`);
|
|
1923
1977
|
|
|
1924
|
-
// Self-update: check if CLI itself is outdated. Update first, then re-exec.
|
|
1925
|
-
// This breaks the chicken-and-egg: new features in ldm install are always
|
|
1926
|
-
// available because the installer upgrades itself before doing anything else.
|
|
1927
|
-
// --alpha and --beta flags check the corresponding npm dist-tag instead of @latest.
|
|
1928
|
-
if (!DRY_RUN && !process.env.LDM_SELF_UPDATED) {
|
|
1929
|
-
try {
|
|
1930
|
-
const npmTag = ALPHA_FLAG ? 'alpha' : BETA_FLAG ? 'beta' : 'latest';
|
|
1931
|
-
const trackLabel = npmTag === 'latest' ? '' : ` (${npmTag} track)`;
|
|
1932
|
-
const npmViewCmd = npmTag === 'latest'
|
|
1933
|
-
? 'npm view @wipcomputer/wip-ldm-os version 2>/dev/null'
|
|
1934
|
-
: `npm view @wipcomputer/wip-ldm-os dist-tags.${npmTag} 2>/dev/null`;
|
|
1935
|
-
const latest = execSync(npmViewCmd, {
|
|
1936
|
-
encoding: 'utf8', timeout: 15000,
|
|
1937
|
-
}).trim();
|
|
1938
|
-
if (latest && semverNewer(latest, PKG_VERSION)) {
|
|
1939
|
-
console.log(` LDM OS CLI v${PKG_VERSION} -> v${latest}${trackLabel}. Updating first...`);
|
|
1940
|
-
try {
|
|
1941
|
-
execSync(`npm install -g @wipcomputer/wip-ldm-os@${latest}`, { stdio: 'inherit', timeout: 60000 });
|
|
1942
|
-
console.log(` CLI updated to v${latest}. Re-running with new code...`);
|
|
1943
|
-
console.log('');
|
|
1944
|
-
// Re-exec with the new binary. LDM_SELF_UPDATED prevents infinite loop.
|
|
1945
|
-
// process.argv.slice(2) skips 'node' and the script path, keeps just 'install' + flags
|
|
1946
|
-
const reArgs = process.argv.slice(2).join(' ') || 'install';
|
|
1947
|
-
execSync(`LDM_SELF_UPDATED=1 ldm ${reArgs}`, { stdio: 'inherit' });
|
|
1948
|
-
process.exit(0);
|
|
1949
|
-
} catch (e) {
|
|
1950
|
-
console.log(` ! Self-update failed: ${e.message}. Continuing with v${PKG_VERSION}.`);
|
|
1951
|
-
}
|
|
1952
|
-
}
|
|
1953
|
-
} catch {}
|
|
1954
|
-
}
|
|
1955
|
-
|
|
1956
1978
|
autoDetectExtensions();
|
|
1957
1979
|
|
|
1958
1980
|
// Migrate old registry entries to v2 format (#262)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wipcomputer/wip-ldm-os",
|
|
3
|
-
"version": "0.4.85-alpha.
|
|
3
|
+
"version": "0.4.85-alpha.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "LDM OS: identity, memory, and sovereignty infrastructure for AI agents",
|
|
6
6
|
"engines": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"test:skill-frontmatter": "node scripts/test-skill-frontmatter.mjs",
|
|
24
24
|
"test:installer-update-tracks": "node scripts/test-installer-update-tracks.mjs",
|
|
25
25
|
"test:installer-hook-toolname": "node scripts/test-installer-hook-toolname.mjs",
|
|
26
|
+
"test:installer-target-self-update": "node scripts/test-installer-target-self-update.mjs",
|
|
26
27
|
"test:installer-skill-directory": "node scripts/test-installer-skill-directory.mjs",
|
|
27
28
|
"test:installer-skill-dry-run-destinations": "node scripts/test-installer-skill-dry-run-destinations.mjs",
|
|
28
29
|
"test:ldm-install-bin-shim": "node scripts/test-ldm-install-preserves-foreign-bin.mjs",
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
|
|
7
7
|
const server = readFileSync("src/hosted-mcp/server.mjs", "utf8");
|
|
8
8
|
const registrySource = readFileSync("src/hosted-mcp/codex-relay-e2ee-registry.mjs", "utf8");
|
|
9
|
+
const deployScript = readFileSync("src/hosted-mcp/deploy.sh", "utf8");
|
|
9
10
|
|
|
10
11
|
function assertContains(haystack, needle, label) {
|
|
11
12
|
if (!haystack.includes(needle)) {
|
|
@@ -73,6 +74,7 @@ assertContains(server, "await codexDaemonPubkeyRegistry.register(identity.agentI
|
|
|
73
74
|
assertContains(server, "if (envelope?.type === \"daemon.identity\") {", "daemon reconnect identity frame");
|
|
74
75
|
assertContains(server, "codexDaemonPubkeyRegistry.register(", "daemon reconnect register call");
|
|
75
76
|
assertContains(server, "buildCodexBootstrapPayload({ identity, threadId, daemonOnline, daemonKey })", "bootstrap uses shared payload builder");
|
|
77
|
+
assertContains(deployScript, "codex-relay-e2ee-registry.mjs", "hosted deploy copies registry module");
|
|
76
78
|
assertBefore(
|
|
77
79
|
server,
|
|
78
80
|
"await codexDaemonPubkeyRegistry.loadFromDb();",
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
7
|
+
const cli = readFileSync(join(root, 'bin', 'ldm.js'), 'utf8');
|
|
8
|
+
|
|
9
|
+
const helperName = 'function maybeSelfUpdateLdmCliBeforeInstall()';
|
|
10
|
+
const helperIdx = cli.indexOf(helperName);
|
|
11
|
+
if (helperIdx === -1) {
|
|
12
|
+
throw new Error('Missing shared LDM OS self-update preflight helper');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const helperBlock = cli.slice(helperIdx, cli.indexOf('// ── Dead backup trigger cleanup', helperIdx));
|
|
16
|
+
if (!helperBlock.includes('Dry run only: continuing with v${PKG_VERSION}.')) {
|
|
17
|
+
throw new Error('Self-update helper must warn on dry run without updating');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!helperBlock.includes("execSync(`npm install -g @wipcomputer/wip-ldm-os@${latest}`")) {
|
|
21
|
+
throw new Error('Self-update helper must update LDM OS before real installs');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!helperBlock.includes('execSync(`LDM_SELF_UPDATED=1 ldm ${reArgs}`')) {
|
|
25
|
+
throw new Error('Self-update helper must re-run the original install command');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const cmdInstallIdx = cli.indexOf('async function cmdInstall()');
|
|
29
|
+
const targetIdx = cli.indexOf('// Find the target (skip flags)', cmdInstallIdx);
|
|
30
|
+
const preflightCallIdx = cli.indexOf('maybeSelfUpdateLdmCliBeforeInstall();', cmdInstallIdx);
|
|
31
|
+
if (cmdInstallIdx === -1 || targetIdx === -1 || preflightCallIdx === -1) {
|
|
32
|
+
throw new Error('Could not find cmdInstall self-update placement');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (preflightCallIdx > targetIdx) {
|
|
36
|
+
throw new Error('Self-update preflight must run before target resolution so app installs are covered');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const catalogIdx = cli.indexOf('async function cmdInstallCatalog()');
|
|
40
|
+
const oldCatalogBlock = cli.indexOf('Self-update: check if CLI itself is outdated', catalogIdx);
|
|
41
|
+
const autoDetectIdx = cli.indexOf('autoDetectExtensions();', catalogIdx);
|
|
42
|
+
if (oldCatalogBlock !== -1 && oldCatalogBlock < autoDetectIdx) {
|
|
43
|
+
throw new Error('Catalog install should not own the only self-update block');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log('targeted install self-update regression checks passed');
|
package/src/hosted-mcp/deploy.sh
CHANGED
|
@@ -116,6 +116,7 @@ if [ "$SKIP_APP" -ne 1 ]; then
|
|
|
116
116
|
add_file "server.mjs" "${APP_REMOTE_DIR}/server.mjs"
|
|
117
117
|
add_file "inbox.mjs" "${APP_REMOTE_DIR}/inbox.mjs"
|
|
118
118
|
add_file "tools.mjs" "${APP_REMOTE_DIR}/tools.mjs"
|
|
119
|
+
add_file "codex-relay-e2ee-registry.mjs" "${APP_REMOTE_DIR}/codex-relay-e2ee-registry.mjs"
|
|
119
120
|
add_file "package.json" "${APP_REMOTE_DIR}/package.json"
|
|
120
121
|
# Phone app static files (codex-remote-control, login).
|
|
121
122
|
if [ -d "${SCRIPT_DIR}/app" ]; then
|