@wipcomputer/wip-ldm-os 0.4.19 → 0.4.21
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 -4
- package/package.json +1 -1
package/SKILL.md
CHANGED
package/bin/ldm.js
CHANGED
|
@@ -655,6 +655,31 @@ function autoDetectExtensions() {
|
|
|
655
655
|
async function cmdInstallCatalog() {
|
|
656
656
|
// No lock here. cmdInstall() already holds it when calling this.
|
|
657
657
|
|
|
658
|
+
// Self-update: check if CLI itself is outdated. Update first, then re-exec.
|
|
659
|
+
// This breaks the chicken-and-egg: new features in ldm install are always
|
|
660
|
+
// available because the installer upgrades itself before doing anything else.
|
|
661
|
+
if (!DRY_RUN && !process.env.LDM_SELF_UPDATED) {
|
|
662
|
+
try {
|
|
663
|
+
const latest = execSync('npm view @wipcomputer/wip-ldm-os version 2>/dev/null', {
|
|
664
|
+
encoding: 'utf8', timeout: 15000,
|
|
665
|
+
}).trim();
|
|
666
|
+
if (latest && latest !== PKG_VERSION) {
|
|
667
|
+
console.log(` LDM OS CLI v${PKG_VERSION} -> v${latest}. Updating first...`);
|
|
668
|
+
try {
|
|
669
|
+
execSync(`npm install -g @wipcomputer/wip-ldm-os@${latest}`, { stdio: 'inherit', timeout: 60000 });
|
|
670
|
+
console.log(` CLI updated to v${latest}. Re-running with new code...`);
|
|
671
|
+
console.log('');
|
|
672
|
+
// Re-exec with the new binary. LDM_SELF_UPDATED prevents infinite loop.
|
|
673
|
+
const newArgs = process.argv.slice(1);
|
|
674
|
+
execSync(`LDM_SELF_UPDATED=1 ldm ${newArgs.join(' ')}`, { stdio: 'inherit' });
|
|
675
|
+
process.exit(0);
|
|
676
|
+
} catch (e) {
|
|
677
|
+
console.log(` ! Self-update failed: ${e.message}. Continuing with v${PKG_VERSION}.`);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
} catch {}
|
|
681
|
+
}
|
|
682
|
+
|
|
658
683
|
autoDetectExtensions();
|
|
659
684
|
|
|
660
685
|
const { detectSystemState, reconcileState, formatReconciliation } = await import('../lib/state.mjs');
|
|
@@ -811,7 +836,7 @@ async function cmdInstallCatalog() {
|
|
|
811
836
|
console.log(' Summary');
|
|
812
837
|
console.log(' ────────────────────────────────────');
|
|
813
838
|
if (cliLatest && cliLatest !== PKG_VERSION) {
|
|
814
|
-
console.log(` LDM OS CLI v${PKG_VERSION} -> v${cliLatest} (
|
|
839
|
+
console.log(` LDM OS CLI v${PKG_VERSION} -> v${cliLatest} (auto-updates on install)`);
|
|
815
840
|
} else {
|
|
816
841
|
console.log(` LDM OS CLI v${PKG_VERSION} (latest)`);
|
|
817
842
|
}
|
|
@@ -850,6 +875,50 @@ async function cmdInstallCatalog() {
|
|
|
850
875
|
console.log(' Old versions would be moved to ~/.ldm/_trash/ (never deleted).');
|
|
851
876
|
}
|
|
852
877
|
|
|
878
|
+
// Health check preview (dry-run)
|
|
879
|
+
const healthIssues = [];
|
|
880
|
+
|
|
881
|
+
// Check missing CLIs
|
|
882
|
+
for (const comp of components) {
|
|
883
|
+
if (!comp.npm || !comp.cliMatches || comp.cliMatches.length === 0) continue;
|
|
884
|
+
if (!isCatalogItemInstalled(comp)) continue;
|
|
885
|
+
for (const binName of comp.cliMatches) {
|
|
886
|
+
try { execSync(`which ${binName} 2>/dev/null`, { encoding: 'utf8' }); }
|
|
887
|
+
catch { healthIssues.push(` ! CLI "${binName}" missing (would reinstall ${comp.npm})`); }
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
// Check /tmp/ symlinks
|
|
892
|
+
try {
|
|
893
|
+
const npmPrefix = execSync('npm config get prefix', { encoding: 'utf8', timeout: 5000 }).trim();
|
|
894
|
+
const globalModules = join(npmPrefix, 'lib', 'node_modules', '@wipcomputer');
|
|
895
|
+
if (existsSync(globalModules)) {
|
|
896
|
+
for (const entry of readdirSync(globalModules, { withFileTypes: true })) {
|
|
897
|
+
if (!entry.isSymbolicLink()) continue;
|
|
898
|
+
try {
|
|
899
|
+
const target = readlinkSync(join(globalModules, entry.name));
|
|
900
|
+
if (target.includes('/tmp/') || target.includes('/private/tmp/')) {
|
|
901
|
+
healthIssues.push(` ! @wipcomputer/${entry.name} symlinked to /tmp/ (would reinstall from npm)`);
|
|
902
|
+
}
|
|
903
|
+
} catch {}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
} catch {}
|
|
907
|
+
|
|
908
|
+
// Check orphaned /tmp/ dirs
|
|
909
|
+
try {
|
|
910
|
+
const tmpCount = readdirSync('/private/tmp').filter(d => d.startsWith('ldm-install-')).length;
|
|
911
|
+
if (tmpCount > 0) {
|
|
912
|
+
healthIssues.push(` ! ${tmpCount} orphaned /tmp/ldm-install-* dirs (would clean up)`);
|
|
913
|
+
}
|
|
914
|
+
} catch {}
|
|
915
|
+
|
|
916
|
+
if (healthIssues.length > 0) {
|
|
917
|
+
console.log('');
|
|
918
|
+
console.log(' Health issues (would fix on install):');
|
|
919
|
+
for (const h of healthIssues) console.log(h);
|
|
920
|
+
}
|
|
921
|
+
|
|
853
922
|
console.log('');
|
|
854
923
|
console.log(' Dry run complete. No changes made.');
|
|
855
924
|
console.log('');
|
|
@@ -960,7 +1029,7 @@ async function cmdInstallCatalog() {
|
|
|
960
1029
|
try {
|
|
961
1030
|
execSync(`npm install -g ${comp.npm}`, { stdio: 'inherit', timeout: 60000 });
|
|
962
1031
|
healthFixes++;
|
|
963
|
-
|
|
1032
|
+
console.log(` + CLI: ${binName} restored`);
|
|
964
1033
|
} catch (e) {
|
|
965
1034
|
console.error(` x Failed to restore ${binName}: ${e.message}`);
|
|
966
1035
|
}
|
|
@@ -983,7 +1052,7 @@ async function cmdInstallCatalog() {
|
|
|
983
1052
|
try {
|
|
984
1053
|
execSync(`npm install -g ${pkgName}`, { stdio: 'inherit', timeout: 60000 });
|
|
985
1054
|
healthFixes++;
|
|
986
|
-
|
|
1055
|
+
console.log(` + ${pkgName}: replaced /tmp/ symlink with registry install`);
|
|
987
1056
|
} catch (e) {
|
|
988
1057
|
console.error(` x Failed to fix ${pkgName}: ${e.message}`);
|
|
989
1058
|
}
|
|
@@ -1002,7 +1071,7 @@ async function cmdInstallCatalog() {
|
|
|
1002
1071
|
try { execSync(`rm -rf "/private/tmp/${d}"`, { stdio: 'pipe', timeout: 10000 }); } catch {}
|
|
1003
1072
|
}
|
|
1004
1073
|
healthFixes++;
|
|
1005
|
-
|
|
1074
|
+
console.log(` + Cleaned ${tmpDirs.length} orphaned /tmp/ clone(s)`);
|
|
1006
1075
|
}
|
|
1007
1076
|
} catch {}
|
|
1008
1077
|
|