@newlandnpt/pep-cli 0.6.0 → 0.6.1

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/README.md +9 -3
  2. package/dist/pep.cjs +26 -18
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -153,9 +153,12 @@ A skill's name is the folder name **inside** the repository, not the repository'
153
153
  different repositories that each ship a `semi-integration/SKILL.md` both want
154
154
  `~/.agents/skills/semi-integration/`, and the second would silently overwrite the first.
155
155
 
156
- Adding a second such repository is refused, and the error names the one already there. If you
157
- already have a colliding pair from an older version, nothing breaks — every command reports it
158
- until you `remove` one:
156
+ `add` refuses, and the error names the repository already there — it will not pick a winner for
157
+ you. `update` never fails over it: the contested skill is left exactly as it is, everything else in
158
+ that repository still refreshes, and the clash is reported every run until you `remove` one. That
159
+ matters because a clash can appear **later**, when one repository adds a folder the other already
160
+ has — you did nothing, and one upstream mistake must not stop every other repository from
161
+ updating.
159
162
 
160
163
  ```
161
164
  ⚠ 3 repositories all install "semi-integration" here:
@@ -166,6 +169,9 @@ until you `remove` one:
166
169
 
167
170
  Installing them into **different** directories is fine — that is what `-p` is for.
168
171
 
172
+ A contested skill stays frozen at whichever copy is on disk until you remove one of the claimants.
173
+ That is deliberate: stable and loudly reported beats "whoever runs update last wins".
174
+
169
175
  `remove` leaves a shared skill's files on disk (which copy it is can no longer be told) and says
170
176
  so, rather than deleting what might be the other repository's content.
171
177
 
package/dist/pep.cjs CHANGED
@@ -1272,7 +1272,19 @@ async function updateSkills(dependencies) {
1272
1272
  }
1273
1273
  const inArchive = [...bySkill.keys()].sort();
1274
1274
  const skipped = dependencies.restoreMissing ? [] : inArchive.filter((skill) => gone.has(skill));
1275
- const skills = inArchive.filter((skill) => !skipped.includes(skill));
1275
+ const candidates = inArchive.filter((skill) => !skipped.includes(skill));
1276
+ const conflicts = [];
1277
+ for (const skill of candidates) {
1278
+ const owner = claimedElsewhere(skill);
1279
+ if (owner === void 0) continue;
1280
+ if (dependencies.restoreMissing) {
1281
+ throw new Error(
1282
+ `${owner} already installs a skill named "${skill}" in ${dependencies.directory}. Two repositories cannot both provide "${skill}" there \u2014 the second would silently overwrite the first. Install this one elsewhere (-p, or --dir <path>), or run \`pep skills remove ${owner}\` first.`
1283
+ );
1284
+ }
1285
+ conflicts.push({ skill, owner });
1286
+ }
1287
+ const skills = candidates.filter((skill) => !conflicts.some((one) => one.skill === skill));
1276
1288
  const hashes = {};
1277
1289
  const updated = [];
1278
1290
  const unchanged = [];
@@ -1284,18 +1296,6 @@ async function updateSkills(dependencies) {
1284
1296
  else if (before !== void 0 && before !== "" && before === hash) unchanged.push(skill);
1285
1297
  else updated.push(skill);
1286
1298
  }
1287
- const conflicts = [];
1288
- for (const skill of skills) {
1289
- const owner = claimedElsewhere(skill);
1290
- if (owner === void 0) continue;
1291
- if (previous !== void 0 && skill in previous.skills) {
1292
- conflicts.push({ skill, owner });
1293
- continue;
1294
- }
1295
- throw new Error(
1296
- `${owner} already installs a skill named "${skill}" in ${dependencies.directory}. Two repositories cannot both provide "${skill}" there \u2014 the second would silently overwrite the first. Install this one elsewhere (-p, or --dir <path>), or run \`pep skills remove ${owner}\` first.`
1297
- );
1298
- }
1299
1299
  const removed = Object.keys(previous?.skills ?? {}).filter((skill) => !inArchive.includes(skill));
1300
1300
  if (previous !== void 0) {
1301
1301
  const stale = sameTarget ? removed : Object.keys(previous.skills);
@@ -1309,8 +1309,9 @@ async function updateSkills(dependencies) {
1309
1309
  for (const skill of skills) {
1310
1310
  await (0, import_promises4.rm)((0, import_node_path4.join)(dependencies.directory, skill), { recursive: true, force: true });
1311
1311
  }
1312
+ const untouched = /* @__PURE__ */ new Set([...skipped, ...conflicts.map((one) => one.skill)]);
1312
1313
  for (const file of files) {
1313
- if (skipped.includes(file.skill)) continue;
1314
+ if (untouched.has(file.skill)) continue;
1314
1315
  const target = (0, import_node_path4.join)(dependencies.directory, file.skill, ...file.path.split("/"));
1315
1316
  await (0, import_promises4.mkdir)((0, import_node_path4.dirname)(target), { recursive: true });
1316
1317
  await (0, import_promises4.writeFile)(target, file.data);
@@ -1337,7 +1338,12 @@ async function updateSkills(dependencies) {
1337
1338
  ...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
1338
1339
  // 跳过的那些**原样留着上次的哈希** —— 账上仍然认它是这个包的(将来 add 能补回来,
1339
1340
  // 上游删掉时也还清得动),只是这次没去碰它。
1340
- skills: { ...pickSkipped(previous, skipped), ...hashes }
1341
+ // 跳过的与让开的都**原样留着上次的哈希** —— 账上仍然认它是这个包的(将来 add
1342
+ // 能补回来、`remove` 也还清得动),只是这次没去碰它。
1343
+ skills: {
1344
+ ...pickSkipped(previous, [...skipped, ...conflicts.map((one) => one.skill)]),
1345
+ ...hashes
1346
+ }
1341
1347
  }
1342
1348
  }
1343
1349
  });
@@ -1359,7 +1365,7 @@ async function updateSkills(dependencies) {
1359
1365
  }
1360
1366
 
1361
1367
  // src/cli.ts
1362
- var VERSION = false ? "0.0.0-dev" : "0.6.0";
1368
+ var VERSION = false ? "0.0.0-dev" : "0.6.1";
1363
1369
  function usage() {
1364
1370
  return `PEP CLI ${VERSION}
1365
1371
 
@@ -1421,8 +1427,10 @@ list. It only removes what it installed itself, and it needs no login. A skill t
1421
1427
  repository also installs is left on disk (which copy it is can no longer be told) and reported.
1422
1428
 
1423
1429
  Two repositories cannot both provide a skill with the SAME NAME in one directory \u2014 the skill name
1424
- is the folder name inside the repository, so they would overwrite each other. Adding a second one
1425
- is refused; if you already have such a pair, every command says so until you remove one.
1430
+ is the folder name inside the repository, so they would overwrite each other. add refuses, naming
1431
+ the repository already there. update never fails over it: it leaves that one skill untouched,
1432
+ refreshes everything else, and reports it every run until you remove one. Installing them into
1433
+ different directories (-p, or --dir) is fine.
1426
1434
 
1427
1435
  Delete a skill folder by hand and update LEAVES IT DELETED \u2014 it refreshes what is still there and
1428
1436
  reports the ones it left alone. Run \`pep skills add <repo>\` to put them back; add is the command
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newlandnpt/pep-cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "PEP CLI —— 凭 PEP 身份读取 Newland 开发者文档与 agent skills",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",