@wipcomputer/wip-ldm-os 0.4.18 → 0.4.19

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.
Files changed (3) hide show
  1. package/SKILL.md +1 -1
  2. package/bin/ldm.js +72 -1
  3. package/package.json +1 -1
package/SKILL.md CHANGED
@@ -5,7 +5,7 @@ license: MIT
5
5
  interface: [cli, skill]
6
6
  metadata:
7
7
  display-name: "LDM OS"
8
- version: "0.4.18"
8
+ version: "0.4.19"
9
9
  homepage: "https://github.com/wipcomputer/wip-ldm-os"
10
10
  author: "Parker Todd Brooks"
11
11
  category: infrastructure
package/bin/ldm.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * ldm --version Show version
18
18
  */
19
19
 
20
- import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, cpSync, chmodSync, unlinkSync } from 'node:fs';
20
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, cpSync, chmodSync, unlinkSync, readlinkSync } from 'node:fs';
21
21
  import { join, basename, resolve, dirname } from 'node:path';
22
22
  import { execSync } from 'node:child_process';
23
23
  import { fileURLToPath } from 'node:url';
@@ -941,6 +941,77 @@ async function cmdInstallCatalog() {
941
941
  }
942
942
  }
943
943
 
944
+ // Health check: fix missing CLIs + dead symlinks (#90)
945
+ console.log('');
946
+ console.log(' Running health check...');
947
+ let healthFixes = 0;
948
+
949
+ // 1. Check catalog CLIs exist on disk
950
+ for (const comp of components) {
951
+ if (!comp.npm || !comp.cliMatches || comp.cliMatches.length === 0) continue;
952
+ if (!isCatalogItemInstalled(comp)) continue;
953
+
954
+ for (const binName of comp.cliMatches) {
955
+ try {
956
+ execSync(`which ${binName} 2>/dev/null`, { encoding: 'utf8' });
957
+ } catch {
958
+ // CLI binary missing. Reinstall from npm.
959
+ console.log(` ! CLI "${binName}" missing. Reinstalling ${comp.npm}...`);
960
+ try {
961
+ execSync(`npm install -g ${comp.npm}`, { stdio: 'inherit', timeout: 60000 });
962
+ healthFixes++;
963
+ ok(`CLI: ${binName} restored`);
964
+ } catch (e) {
965
+ console.error(` x Failed to restore ${binName}: ${e.message}`);
966
+ }
967
+ }
968
+ }
969
+ }
970
+
971
+ // 2. Check for /tmp/ symlinks in global npm modules
972
+ try {
973
+ const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8', timeout: 5000 }).trim();
974
+ const globalModules = join(npmPrefix, 'lib', 'node_modules', '@wipcomputer');
975
+ if (existsSync(globalModules)) {
976
+ for (const entry of readdirSync(globalModules, { withFileTypes: true })) {
977
+ if (!entry.isSymbolicLink()) continue;
978
+ try {
979
+ const target = readlinkSync(join(globalModules, entry.name));
980
+ if (target.includes('/tmp/') || target.includes('/private/tmp/')) {
981
+ const pkgName = `@wipcomputer/${entry.name}`;
982
+ console.log(` ! ${pkgName} symlinked to ${target} (will break on reboot). Reinstalling...`);
983
+ try {
984
+ execSync(`npm install -g ${pkgName}`, { stdio: 'inherit', timeout: 60000 });
985
+ healthFixes++;
986
+ ok(`${pkgName}: replaced /tmp/ symlink with registry install`);
987
+ } catch (e) {
988
+ console.error(` x Failed to fix ${pkgName}: ${e.message}`);
989
+ }
990
+ }
991
+ } catch {}
992
+ }
993
+ }
994
+ } catch {}
995
+
996
+ // 3. Clean orphaned /tmp/ldm-install-* dirs
997
+ try {
998
+ const tmpDirs = readdirSync('/private/tmp').filter(d => d.startsWith('ldm-install-'));
999
+ if (tmpDirs.length > 0) {
1000
+ console.log(` Cleaning ${tmpDirs.length} orphaned /tmp/ldm-install-* dirs...`);
1001
+ for (const d of tmpDirs) {
1002
+ try { execSync(`rm -rf "/private/tmp/${d}"`, { stdio: 'pipe', timeout: 10000 }); } catch {}
1003
+ }
1004
+ healthFixes++;
1005
+ ok(`Cleaned ${tmpDirs.length} orphaned /tmp/ clone(s)`);
1006
+ }
1007
+ } catch {}
1008
+
1009
+ if (healthFixes > 0) {
1010
+ console.log(` ${healthFixes} health issue(s) fixed.`);
1011
+ } else {
1012
+ console.log(' All healthy.');
1013
+ }
1014
+
944
1015
  // Sync boot hook from npm package (#49)
945
1016
  if (syncBootHook()) {
946
1017
  ok('Boot hook updated (sessions, messages, updates now active)');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ldm-os",
3
- "version": "0.4.18",
3
+ "version": "0.4.19",
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",