@wipcomputer/wip-ldm-os 0.4.30 → 0.4.31

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 +85 -9
  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.30"
8
+ version: "0.4.31"
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
@@ -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,51 @@ 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
+ const checkedNpm = new Set(npmUpdates.map(u => u.catalogNpm));
899
+ for (const comp of components) {
900
+ if (!comp.npm || checkedNpm.has(comp.npm)) continue;
901
+ if (!comp.registryMatches || comp.registryMatches.length === 0) continue;
902
+
903
+ // If any registryMatch is installed, check the parent package
904
+ const installedMatch = comp.registryMatches.find(m => reconciled[m]);
905
+ if (!installedMatch) continue;
906
+
907
+ const currentVersion = reconciled[installedMatch]?.ldmVersion || reconciled[installedMatch]?.ocVersion || '?';
908
+
909
+ try {
910
+ const latest = execSync(`npm view ${comp.npm} version 2>/dev/null`, {
911
+ encoding: 'utf8', timeout: 10000,
912
+ }).trim();
913
+ if (latest && latest !== currentVersion) {
914
+ // Remove any sub-tool entries that duplicate this parent
915
+ for (let i = npmUpdates.length - 1; i >= 0; i--) {
916
+ if (npmUpdates[i].catalogNpm === comp.npm && !npmUpdates[i].isCLI) {
917
+ npmUpdates.splice(i, 1);
918
+ }
919
+ }
920
+ npmUpdates.push({
921
+ name: comp.id,
922
+ catalogRepo: comp.repo,
923
+ catalogNpm: comp.npm,
924
+ currentVersion,
925
+ latestVersion: latest,
926
+ hasUpdate: true,
927
+ isParent: true,
928
+ registryMatches: comp.registryMatches,
929
+ });
930
+ }
931
+ } catch {}
932
+ checkedNpm.add(comp.npm);
933
+ }
934
+
853
935
  const totalUpdates = npmUpdates.length;
854
936
 
855
937
  if (DRY_RUN) {
856
938
  // Summary block (#80)
857
- const cliLatest = (() => {
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
- })();
939
+ const cliUpdate = npmUpdates.find(u => u.isCLI);
864
940
 
865
941
  const agentDirs = (() => {
866
942
  try {
@@ -879,8 +955,8 @@ async function cmdInstallCatalog() {
879
955
  console.log('');
880
956
  console.log(' Summary');
881
957
  console.log(' ────────────────────────────────────');
882
- if (cliLatest && cliLatest !== PKG_VERSION) {
883
- console.log(` LDM OS CLI v${PKG_VERSION} -> v${cliLatest} (auto-updates on install)`);
958
+ if (cliUpdate) {
959
+ console.log(` LDM OS CLI v${PKG_VERSION} -> v${cliUpdate.latestVersion}`);
884
960
  } else {
885
961
  console.log(` LDM OS CLI v${PKG_VERSION} (latest)`);
886
962
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-ldm-os",
3
- "version": "0.4.30",
3
+ "version": "0.4.31",
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",