@pi-stef/catalog 0.3.2 → 0.3.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-stef/catalog",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Pi extension for managing skill/package catalogs.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -72,6 +72,11 @@ export async function removeCommand(
72
72
  }
73
73
  }
74
74
 
75
+ // --- Capture source before removing -------------------------------------
76
+ // pi uninstall needs the full source (e.g., "npm:@pi-stef/foo"), not just
77
+ // the catalog key.
78
+ const source = catalog.packages[name].source;
79
+
75
80
  // --- Remove package -------------------------------------------------------
76
81
  const updated = removePackage(catalog, name);
77
82
  writeCatalog(updated, ctx.home);
@@ -80,7 +85,7 @@ export async function removeCommand(
80
85
 
81
86
  // --- Run pi uninstall -----------------------------------------------------
82
87
  try {
83
- await piUninstall(name);
88
+ await piUninstall(source);
84
89
  } catch {
85
90
  ctx.ui.notify(
86
91
  `Warning: package "${name}" removed from catalog but uninstall failed`,
@@ -111,9 +111,11 @@ export async function syncCommand(
111
111
  errors: [],
112
112
  };
113
113
 
114
- // --- 1. Read local catalog BEFORE pulling --------------------------------
115
- // We need this to detect local-only packages that haven't been pushed yet.
114
+ // --- 1. Read local state BEFORE pulling ---------------------------------
115
+ // We need this to detect local-only packages and version changes
116
+ // (e.g., from `pi update`) that haven't been pushed yet.
116
117
  const localCatalogBeforePull = readCatalog(ctx.home);
118
+ const localLockBeforePull = readLock(ctx.home);
117
119
 
118
120
  // --- 2. Pull remote catalog (into memory only) ---------------------------
119
121
  let remoteCatalog = false;
@@ -146,6 +148,30 @@ export async function syncCommand(
146
148
  }
147
149
  }
148
150
 
151
+ // Detect local lock changes (e.g., from `pi update` bumping versions).
152
+ // If the local lock has different versions than the remote lock, we need
153
+ // to push so the remote gist reflects the actual installed state.
154
+ let hasLocalLockChanges = false;
155
+ if (pulledData) {
156
+ const remoteLock = pulledData.lock;
157
+ for (const [key, localEntry] of Object.entries(localLockBeforePull.packages)) {
158
+ const remoteEntry = remoteLock.packages[key];
159
+ if (!remoteEntry || remoteEntry.version !== localEntry.version) {
160
+ hasLocalLockChanges = true;
161
+ break;
162
+ }
163
+ }
164
+ // Also check for packages in remote but removed locally
165
+ if (!hasLocalLockChanges) {
166
+ for (const key of Object.keys(remoteLock.packages)) {
167
+ if (!(key in localLockBeforePull.packages)) {
168
+ hasLocalLockChanges = true;
169
+ break;
170
+ }
171
+ }
172
+ }
173
+ }
174
+
149
175
  const installed = scanInstalled(ctx.home);
150
176
 
151
177
  // Build catalog entries for reconcile
@@ -225,7 +251,7 @@ export async function syncCommand(
225
251
  const hasGist = readCachedGistId(ctx.home) !== undefined;
226
252
  const localHasPackages = Object.keys(catalog.packages).length > 0;
227
253
 
228
- if (force || summary.actionCount > 0 || hasLocalOnlyPackages || (!hasGist && localHasPackages)) {
254
+ if (force || summary.actionCount > 0 || hasLocalOnlyPackages || hasLocalLockChanges || (!hasGist && localHasPackages)) {
229
255
  try {
230
256
  const updatedCatalog = readCatalog(ctx.home);
231
257
  const updatedLock = readLock(ctx.home);
@@ -256,7 +282,7 @@ export async function syncCommand(
256
282
  }
257
283
  }
258
284
 
259
- if (summary.actionCount === 0 && summary.errors.length === 0 && !force && !hasLocalOnlyPackages) {
285
+ if (summary.actionCount === 0 && summary.errors.length === 0 && !force && !hasLocalOnlyPackages && !hasLocalLockChanges) {
260
286
  ctx.ui.notify("Catalog already up to date.", "info");
261
287
  return;
262
288
  }
@@ -269,6 +295,9 @@ export async function syncCommand(
269
295
  if (hasLocalOnlyPackages) {
270
296
  parts.push("Merged local-only packages.");
271
297
  }
298
+ if (hasLocalLockChanges) {
299
+ parts.push("Pushed local version updates.");
300
+ }
272
301
  if (plan.installs.length > 0) {
273
302
  parts.push(`${plan.installs.length} install(s): ${plan.installs.map((a) => a.key).join(", ")}`);
274
303
  }