@iseoane/agent-depot 0.6.1 → 0.6.2

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/CHANGELOG.md CHANGED
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.2] - 2026-10-13
11
+
12
+ ### Fixed
13
+
14
+ - Pi Package update comparison no longer treats npm's generated dependency-free
15
+ root `package-lock.json` as a local checkout change. Any other lockfile, and
16
+ any tracked modification or additional untracked file, still blocks the
17
+ comparison.
18
+
10
19
  ## [0.6.1] - 2026-10-13
11
20
 
12
21
  ### Added
@@ -258,7 +258,9 @@ async function readPiCheckoutEvidence(checkoutPath, sourceIdentity) {
258
258
  const version = isRecord(packageJson) && typeof packageJson.version === "string" && packageJson.version.trim() !== ""
259
259
  ? packageJson.version
260
260
  : undefined;
261
- if (status !== "") {
261
+ const generatedRootLock = status === "?? package-lock.json"
262
+ && await isMatchingRootOnlyNpmLock(checkoutPath, packageJson);
263
+ if (status !== "" && !generatedRootLock) {
262
264
  return {
263
265
  ...(version === undefined ? {} : { version }),
264
266
  issue: `Pi reports this Package installed, but the Pi Git checkout has local modifications. Update assessment is unavailable; inspect the checkout before updating.`,
@@ -276,6 +278,48 @@ async function readPiCheckoutEvidence(checkoutPath, sourceIdentity) {
276
278
  return unavailable(reason);
277
279
  }
278
280
  }
281
+ /** Recognize only npm's dependency-free generated root lock, never tracked edits. */
282
+ async function isMatchingRootOnlyNpmLock(checkoutPath, manifest) {
283
+ try {
284
+ if (!isRecord(manifest))
285
+ return false;
286
+ const lockPath = path.join(checkoutPath, "package-lock.json");
287
+ await assertNoSymlinkPath(lockPath, "Pi generated lockfile");
288
+ const stat = await lstat(lockPath);
289
+ if (!stat.isFile() || stat.size > 64 * 1024)
290
+ return false;
291
+ const lock = JSON.parse(await readFile(lockPath, "utf8"));
292
+ if (!isRecord(lock) || lock.lockfileVersion !== 3 || lock.requires !== true
293
+ || typeof manifest.name !== "string" || typeof manifest.version !== "string"
294
+ || lock.name !== manifest.name || lock.version !== manifest.version
295
+ || Object.keys(lock).some((key) => !["name", "version", "lockfileVersion", "requires", "packages"].includes(key))
296
+ || !isRecord(lock.packages) || Object.keys(lock.packages).length !== 1)
297
+ return false;
298
+ const root = lock.packages[""];
299
+ if (!isRecord(root) || root.name !== manifest.name || root.version !== manifest.version)
300
+ return false;
301
+ // Ordinary dependencies mean this is more than the harmless root-only artifact.
302
+ for (const key of ["dependencies", "devDependencies", "optionalDependencies"]) {
303
+ if (manifest[key] !== undefined && (!isRecord(manifest[key]) || Object.keys(manifest[key]).length !== 0))
304
+ return false;
305
+ }
306
+ const allowed = ["name", "version", "license", "peerDependencies", "peerDependenciesMeta"];
307
+ const equalJson = (left, right) => {
308
+ if (left === right)
309
+ return true;
310
+ if (!isRecord(left) || !isRecord(right))
311
+ return false;
312
+ const keys = Object.keys(left);
313
+ return keys.length === Object.keys(right).length
314
+ && keys.every((key) => Object.hasOwn(right, key) && equalJson(left[key], right[key]));
315
+ };
316
+ return Object.keys(root).every((key) => allowed.includes(key) && equalJson(root[key], manifest[key]))
317
+ && ["peerDependencies", "peerDependenciesMeta"].every((key) => equalJson(root[key], manifest[key]));
318
+ }
319
+ catch {
320
+ return false;
321
+ }
322
+ }
279
323
  async function runPiGit(checkoutPath, args) {
280
324
  const result = await runProcess("git", ["-C", checkoutPath, ...args], {
281
325
  captureStdout: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iseoane/agent-depot",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "A cross-platform catalog for reusable coding-agent skills.",
5
5
  "license": "MIT",
6
6
  "author": "iseoane",