@wipcomputer/wip-ldm-os 0.4.30 → 0.4.32
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 +87 -9
- package/package.json +1 -1
package/SKILL.md
CHANGED
package/bin/ldm.js
CHANGED
|
@@ -766,9 +766,51 @@ async function cmdInstallCatalog() {
|
|
|
766
766
|
console.log('');
|
|
767
767
|
}
|
|
768
768
|
|
|
769
|
+
// Clean ghost entries from registry (#134, #135)
|
|
770
|
+
if (registry?.extensions) {
|
|
771
|
+
const names = Object.keys(registry.extensions);
|
|
772
|
+
let cleaned = 0;
|
|
773
|
+
for (const name of names) {
|
|
774
|
+
// Remove -private duplicates (e.g. wip-xai-grok-private when wip-xai-grok exists)
|
|
775
|
+
const publicName = name.replace(/-private$/, '');
|
|
776
|
+
if (name !== publicName && registry.extensions[publicName]) {
|
|
777
|
+
delete registry.extensions[name];
|
|
778
|
+
cleaned++;
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
// Remove ldm-install- prefixed entries (ghost from /tmp/ clones)
|
|
782
|
+
if (name.startsWith('ldm-install-')) {
|
|
783
|
+
const cleanName = name.replace(/^ldm-install-/, '');
|
|
784
|
+
delete registry.extensions[name];
|
|
785
|
+
cleaned++;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
if (cleaned > 0 && !DRY_RUN) {
|
|
789
|
+
writeFileSync(REGISTRY_PATH, JSON.stringify(registry, null, 2));
|
|
790
|
+
installLog(`Cleaned ${cleaned} ghost registry entries`);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
|
|
769
794
|
// Build the update plan: check ALL installed extensions against npm (#55)
|
|
770
795
|
const npmUpdates = [];
|
|
771
796
|
|
|
797
|
+
// Check CLI self-update (#132)
|
|
798
|
+
try {
|
|
799
|
+
const cliLatest = execSync('npm view @wipcomputer/wip-ldm-os version 2>/dev/null', {
|
|
800
|
+
encoding: 'utf8', timeout: 10000,
|
|
801
|
+
}).trim();
|
|
802
|
+
if (cliLatest && cliLatest !== PKG_VERSION) {
|
|
803
|
+
npmUpdates.push({
|
|
804
|
+
name: 'LDM OS CLI',
|
|
805
|
+
catalogNpm: '@wipcomputer/wip-ldm-os',
|
|
806
|
+
currentVersion: PKG_VERSION,
|
|
807
|
+
latestVersion: cliLatest,
|
|
808
|
+
hasUpdate: true,
|
|
809
|
+
isCLI: true,
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
} catch {}
|
|
813
|
+
|
|
772
814
|
// Check every installed extension against npm via catalog
|
|
773
815
|
console.log(' Checking npm for updates...');
|
|
774
816
|
for (const [name, entry] of Object.entries(reconciled)) {
|
|
@@ -850,17 +892,53 @@ async function cmdInstallCatalog() {
|
|
|
850
892
|
} catch {}
|
|
851
893
|
}
|
|
852
894
|
|
|
895
|
+
// Check parent packages for toolbox-style repos (#132)
|
|
896
|
+
// If sub-tools are installed but the parent npm package has a newer version,
|
|
897
|
+
// report the parent as needing an update (not the individual sub-tool).
|
|
898
|
+
// Don't skip packages already found by the extension loop. The parent check
|
|
899
|
+
// REPLACES sub-tool entries with the parent name.
|
|
900
|
+
const checkedParentNpm = new Set();
|
|
901
|
+
for (const comp of components) {
|
|
902
|
+
if (!comp.npm || checkedParentNpm.has(comp.npm)) continue;
|
|
903
|
+
if (!comp.registryMatches || comp.registryMatches.length === 0) continue;
|
|
904
|
+
|
|
905
|
+
// If any registryMatch is installed, check the parent package
|
|
906
|
+
const installedMatch = comp.registryMatches.find(m => reconciled[m]);
|
|
907
|
+
if (!installedMatch) continue;
|
|
908
|
+
|
|
909
|
+
const currentVersion = reconciled[installedMatch]?.ldmVersion || reconciled[installedMatch]?.ocVersion || '?';
|
|
910
|
+
|
|
911
|
+
try {
|
|
912
|
+
const latest = execSync(`npm view ${comp.npm} version 2>/dev/null`, {
|
|
913
|
+
encoding: 'utf8', timeout: 10000,
|
|
914
|
+
}).trim();
|
|
915
|
+
if (latest && latest !== currentVersion) {
|
|
916
|
+
// Remove any sub-tool entries that duplicate this parent
|
|
917
|
+
for (let i = npmUpdates.length - 1; i >= 0; i--) {
|
|
918
|
+
if (npmUpdates[i].catalogNpm === comp.npm && !npmUpdates[i].isCLI) {
|
|
919
|
+
npmUpdates.splice(i, 1);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
npmUpdates.push({
|
|
923
|
+
name: comp.id,
|
|
924
|
+
catalogRepo: comp.repo,
|
|
925
|
+
catalogNpm: comp.npm,
|
|
926
|
+
currentVersion,
|
|
927
|
+
latestVersion: latest,
|
|
928
|
+
hasUpdate: true,
|
|
929
|
+
isParent: true,
|
|
930
|
+
registryMatches: comp.registryMatches,
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
} catch {}
|
|
934
|
+
checkedParentNpm.add(comp.npm);
|
|
935
|
+
}
|
|
936
|
+
|
|
853
937
|
const totalUpdates = npmUpdates.length;
|
|
854
938
|
|
|
855
939
|
if (DRY_RUN) {
|
|
856
940
|
// Summary block (#80)
|
|
857
|
-
const
|
|
858
|
-
try {
|
|
859
|
-
return execSync('npm view @wipcomputer/wip-ldm-os version 2>/dev/null', {
|
|
860
|
-
encoding: 'utf8', timeout: 10000,
|
|
861
|
-
}).trim();
|
|
862
|
-
} catch { return null; }
|
|
863
|
-
})();
|
|
941
|
+
const cliUpdate = npmUpdates.find(u => u.isCLI);
|
|
864
942
|
|
|
865
943
|
const agentDirs = (() => {
|
|
866
944
|
try {
|
|
@@ -879,8 +957,8 @@ async function cmdInstallCatalog() {
|
|
|
879
957
|
console.log('');
|
|
880
958
|
console.log(' Summary');
|
|
881
959
|
console.log(' ────────────────────────────────────');
|
|
882
|
-
if (
|
|
883
|
-
console.log(` LDM OS CLI v${PKG_VERSION} -> v${
|
|
960
|
+
if (cliUpdate) {
|
|
961
|
+
console.log(` LDM OS CLI v${PKG_VERSION} -> v${cliUpdate.latestVersion}`);
|
|
884
962
|
} else {
|
|
885
963
|
console.log(` LDM OS CLI v${PKG_VERSION} (latest)`);
|
|
886
964
|
}
|