@newlandnpt/pep-cli 0.9.0 → 0.9.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 (2) hide show
  1. package/dist/pep.cjs +53 -4
  2. package/package.json +1 -1
package/dist/pep.cjs CHANGED
@@ -1524,6 +1524,11 @@ function tooBig(what, limit) {
1524
1524
  );
1525
1525
  }
1526
1526
  var SKILL_MANIFEST = "SKILL.md";
1527
+ function occupiedByOutsider(skill, path) {
1528
+ return new Error(
1529
+ `${path} already exists and pep did not install it. Installing "${skill}" would delete it, so this repository was left alone. Move that directory aside (or delete it yourself), then run this again \u2014 pep never overwrites what it does not track.`
1530
+ );
1531
+ }
1527
1532
  function nameClash(owner, skill, directory) {
1528
1533
  return new Error(
1529
1534
  `${owner} already installs a skill named "${skill}" in ${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.`
@@ -1768,6 +1773,15 @@ function pickSkipped(previous, skipped) {
1768
1773
  skipped.map((skill) => [skill, previous?.skills[skill] ?? ""])
1769
1774
  );
1770
1775
  }
1776
+ async function outsidersAt(directory, skills, ours) {
1777
+ const blocked = [];
1778
+ for (const skill of skills) {
1779
+ if (ours.has(skill)) continue;
1780
+ const path = (0, import_node_path4.join)(directory, skill);
1781
+ if (await (0, import_promises4.stat)(path).catch(() => null)) blocked.push({ skill, path });
1782
+ }
1783
+ return blocked;
1784
+ }
1771
1785
  async function missingSkills(directory, skills) {
1772
1786
  const gone = /* @__PURE__ */ new Set();
1773
1787
  for (const skill of skills) {
@@ -1809,7 +1823,14 @@ async function updateSkills(dependencies) {
1809
1823
  }
1810
1824
  if (commit !== void 0 && commit === previous?.commit && sameTarget && nothingToRestore) {
1811
1825
  await response.body?.cancel();
1812
- return { status: "unchanged", name, commit, conflicts: standing, skipped: [...gone] };
1826
+ return {
1827
+ status: "unchanged",
1828
+ name,
1829
+ commit,
1830
+ conflicts: standing,
1831
+ skipped: [...gone],
1832
+ blocked: []
1833
+ };
1813
1834
  }
1814
1835
  const gzipped = await readCapped(response, dependencies.maxArchiveBytes ?? MAX_ARCHIVE_BYTES);
1815
1836
  let unpacked;
@@ -1844,7 +1865,22 @@ async function updateSkills(dependencies) {
1844
1865
  if (dependencies.restoreMissing) throw nameClash(owner, skill, dependencies.directory);
1845
1866
  conflicts.push({ skill, owner });
1846
1867
  }
1847
- const skills = candidates.filter((skill) => !conflicts.some((one) => one.skill === skill));
1868
+ const unclashed = candidates.filter((skill) => !conflicts.some((one) => one.skill === skill));
1869
+ const ours = new Set(
1870
+ sameTarget ? Object.keys(previous?.skills ?? {}) : []
1871
+ );
1872
+ const blocked = [];
1873
+ for (const one of [
1874
+ ...await outsidersAt(dependencies.directory, unclashed, ours),
1875
+ ...dependencies.linkInto !== void 0 ? await outsidersAt(dependencies.linkInto, unclashed, ours) : []
1876
+ ]) {
1877
+ if (!blocked.some((seen) => seen.skill === one.skill)) blocked.push(one);
1878
+ }
1879
+ if (dependencies.restoreMissing && blocked.length > 0) {
1880
+ const [first] = blocked;
1881
+ throw occupiedByOutsider(first.skill, first.path);
1882
+ }
1883
+ const skills = unclashed.filter((skill) => !blocked.some((one) => one.skill === skill));
1848
1884
  const hashes = {};
1849
1885
  const updated = [];
1850
1886
  const unchanged = [];
@@ -1872,7 +1908,11 @@ async function updateSkills(dependencies) {
1872
1908
  for (const skill of skills) {
1873
1909
  await (0, import_promises4.rm)((0, import_node_path4.join)(dependencies.directory, skill), { recursive: true, force: true });
1874
1910
  }
1875
- const untouched = /* @__PURE__ */ new Set([...skipped, ...conflicts.map((one) => one.skill)]);
1911
+ const untouched = /* @__PURE__ */ new Set([
1912
+ ...skipped,
1913
+ ...conflicts.map((one) => one.skill),
1914
+ ...blocked.map((one) => one.skill)
1915
+ ]);
1876
1916
  for (const file of files) {
1877
1917
  if (untouched.has(file.skill)) continue;
1878
1918
  const target = (0, import_node_path4.join)(dependencies.directory, file.skill, ...file.path.split("/"));
@@ -1923,6 +1963,7 @@ async function updateSkills(dependencies) {
1923
1963
  removed,
1924
1964
  skipped,
1925
1965
  conflicts,
1966
+ blocked,
1926
1967
  directory: dependencies.directory,
1927
1968
  ...dependencies.linkInto !== void 0 ? { linkedInto: dependencies.linkInto } : {},
1928
1969
  ...copiedCount > 0 ? { copiedCount } : {},
@@ -2128,7 +2169,7 @@ async function planSetup(dependencies) {
2128
2169
  }
2129
2170
 
2130
2171
  // src/cli.ts
2131
- var VERSION = false ? "0.0.0-dev" : "0.9.0";
2172
+ var VERSION = false ? "0.0.0-dev" : "0.9.1";
2132
2173
  var SKILLS_ADD_DEPRECATION = "\u26A0 `pep skills add` will be removed in a future release.";
2133
2174
  function reportUpdate(result) {
2134
2175
  const conflicts = () => {
@@ -2137,6 +2178,12 @@ function reportUpdate(result) {
2137
2178
  console.error(` each other. \`pep skills remove\` one of them to settle it.`);
2138
2179
  }
2139
2180
  };
2181
+ const blocked = () => {
2182
+ for (const { skill, path } of result.blocked) {
2183
+ console.error(` \u26A0 "${skill}" was not installed \u2014 ${path} already exists`);
2184
+ console.error(` and pep did not put it there. Move it aside, then run this again.`);
2185
+ }
2186
+ };
2140
2187
  const skipped = (list, name) => {
2141
2188
  if (list.length === 0) return;
2142
2189
  console.log(` deleted locally, left alone: ${list.join(" ")}`);
@@ -2146,6 +2193,7 @@ function reportUpdate(result) {
2146
2193
  console.log(`${result.name}: already at ${result.commit}. Nothing to do.`);
2147
2194
  skipped(result.skipped, result.name);
2148
2195
  conflicts();
2196
+ blocked();
2149
2197
  return;
2150
2198
  }
2151
2199
  console.log(
@@ -2156,6 +2204,7 @@ function reportUpdate(result) {
2156
2204
  }
2157
2205
  skipped(result.skipped, result.name);
2158
2206
  conflicts();
2207
+ blocked();
2159
2208
  console.log(` ${result.fileCount} file(s) in ${result.directory}`);
2160
2209
  if (result.linkedInto !== void 0) {
2161
2210
  console.log(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newlandnpt/pep-cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "PEP CLI —— 凭 PEP 身份读取 Newland 开发者文档与 agent skills",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",