@withone/cli 2.14.0 → 2.14.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/index.js +41 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -13245,8 +13245,9 @@ function copyDir(src, dest) {
13245
13245
  if (entry.name === SKILL_STAMP) continue;
13246
13246
  const from = path12.join(src, entry.name);
13247
13247
  const to = path12.join(dest, entry.name);
13248
+ if (entry.isSymbolicLink()) continue;
13248
13249
  if (entry.isDirectory()) copyDir(from, to);
13249
- else fs14.copyFileSync(from, to);
13250
+ else if (entry.isFile()) fs14.copyFileSync(from, to);
13250
13251
  }
13251
13252
  }
13252
13253
  function removePath(target) {
@@ -13273,20 +13274,50 @@ function linkDir(target, linkPath) {
13273
13274
  copyDir(target, linkPath);
13274
13275
  return "copy";
13275
13276
  }
13277
+ function knownLinkPaths(skill, scope) {
13278
+ const canonical = `${UNIVERSAL_PROJECT_DIR}/${skill.dirName}`;
13279
+ return new Set(
13280
+ SKILL_AGENT_TARGETS.map((a) => `${scope === "project" ? a.projectDir : a.homeDir}/${skill.dirName}`).filter((p9) => p9 !== canonical)
13281
+ );
13282
+ }
13283
+ function stampLinkPath(skill, plan, rel) {
13284
+ return knownLinkPaths(skill, plan.scope).has(toPosix(rel)) ? fromStamp(plan.root, rel) : null;
13285
+ }
13286
+ function assertInsideProject(plan, target) {
13287
+ if (plan.scope !== "project") return;
13288
+ let dir = path12.dirname(target);
13289
+ while (!fs14.existsSync(dir)) {
13290
+ const parent = path12.dirname(dir);
13291
+ if (parent === dir) break;
13292
+ dir = parent;
13293
+ }
13294
+ const realRoot = fs14.realpathSync(plan.root);
13295
+ const rel = path12.relative(realRoot, fs14.realpathSync(dir));
13296
+ if (rel.startsWith("..") || path12.isAbsolute(rel)) {
13297
+ throw new Error(`Refusing to change ${target}: a folder on that path leads outside the project (${plan.root}).`);
13298
+ }
13299
+ }
13276
13300
  function installSkill(skill, source, plan, cliVersion2) {
13277
13301
  const canonical = canonicalSkillDir(skill, plan);
13278
13302
  const previous = readStamp(canonical);
13279
13303
  const { readers, folders } = resolveAgentFolders(plan);
13280
13304
  const nextPaths = new Set(folders.map((f) => `${f.dir}/${skill.dirName}`));
13305
+ const targets = folders.map((folder) => {
13306
+ const rel = `${folder.dir}/${skill.dirName}`;
13307
+ return { rel, full: fromStamp(plan.root, rel), agents: folder.agents };
13308
+ });
13309
+ assertInsideProject(plan, canonical);
13310
+ for (const t of targets) assertInsideProject(plan, t.full);
13281
13311
  for (const link of previous?.links ?? []) {
13282
- if (!nextPaths.has(toPosix(link.path))) removePath(fromStamp(plan.root, link.path));
13312
+ if (nextPaths.has(toPosix(link.path))) continue;
13313
+ const full = stampLinkPath(skill, plan, link.path);
13314
+ if (!full) continue;
13315
+ assertInsideProject(plan, full);
13316
+ removePath(full);
13283
13317
  }
13284
13318
  removePath(canonical);
13285
13319
  copyDir(source.dir, canonical);
13286
- const links = folders.map((folder) => {
13287
- const rel = `${folder.dir}/${skill.dirName}`;
13288
- return { path: rel, kind: linkDir(canonical, fromStamp(plan.root, rel)), agents: folder.agents };
13289
- });
13320
+ const links = targets.map((t) => ({ path: t.rel, kind: linkDir(canonical, t.full), agents: t.agents }));
13290
13321
  const stamp = {
13291
13322
  skill: skill.name,
13292
13323
  package: skill.packageName,
@@ -13305,8 +13336,11 @@ function removeSkill(skill, plan) {
13305
13336
  const stamp = readStamp(canonical);
13306
13337
  if (!stamp && !fs14.existsSync(path12.join(canonical, "SKILL.md"))) return { removed: false, paths: [] };
13307
13338
  const paths = [];
13339
+ assertInsideProject(plan, canonical);
13308
13340
  for (const link of stamp?.links ?? []) {
13309
- const full = fromStamp(plan.root, link.path);
13341
+ const full = stampLinkPath(skill, plan, link.path);
13342
+ if (!full) continue;
13343
+ assertInsideProject(plan, full);
13310
13344
  if (fs14.existsSync(full) || isDanglingLink(full)) {
13311
13345
  removePath(full);
13312
13346
  paths.push(full);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withone/cli",
3
- "version": "2.14.0",
3
+ "version": "2.14.1",
4
4
  "description": "CLI for managing One",
5
5
  "type": "module",
6
6
  "files": [