@alessandroraffa/tangyr 0.11.0 → 0.11.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 +146 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20139,7 +20139,7 @@ import path17 from "path";
20139
20139
  var import_yaml5 = __toESM(require_dist(), 1);
20140
20140
  import fs16 from "fs";
20141
20141
  import path16 from "path";
20142
- function resolveKitHookNames(sourceRoot) {
20142
+ function resolveKitComponentNames(sourceRoot, category) {
20143
20143
  const manifestPath = path16.resolve(sourceRoot, "tangyr-kit.yaml");
20144
20144
  if (!fs16.existsSync(manifestPath)) {
20145
20145
  return void 0;
@@ -20149,10 +20149,10 @@ function resolveKitHookNames(sourceRoot) {
20149
20149
  const doc = (0, import_yaml5.parse)(raw);
20150
20150
  if (doc && typeof doc === "object" && !Array.isArray(doc) && "components" in doc) {
20151
20151
  const components = doc.components;
20152
- if (components && typeof components === "object" && !Array.isArray(components) && "hooks" in components) {
20153
- const hooks = components.hooks;
20154
- if (Array.isArray(hooks) && hooks.every((h) => typeof h === "string")) {
20155
- return hooks;
20152
+ if (components && typeof components === "object" && !Array.isArray(components) && category in components) {
20153
+ const names = components[category];
20154
+ if (Array.isArray(names) && names.every((n7) => typeof n7 === "string")) {
20155
+ return names;
20156
20156
  }
20157
20157
  }
20158
20158
  }
@@ -20160,6 +20160,12 @@ function resolveKitHookNames(sourceRoot) {
20160
20160
  }
20161
20161
  return void 0;
20162
20162
  }
20163
+ function resolveKitHookNames(sourceRoot) {
20164
+ return resolveKitComponentNames(sourceRoot, "hooks");
20165
+ }
20166
+ function resolveKitSkillNames(sourceRoot) {
20167
+ return resolveKitComponentNames(sourceRoot, "skills");
20168
+ }
20163
20169
  function resolveHooksSourceFile(sourceRoot, config) {
20164
20170
  return path16.resolve(sourceRoot, config.source.hooks, "hooks.json");
20165
20171
  }
@@ -28419,12 +28425,6 @@ function buildDirectComponents(profile) {
28419
28425
  destination: profile.agents,
28420
28426
  type: "dir"
28421
28427
  },
28422
- {
28423
- component: "skills",
28424
- sourceKey: "skills",
28425
- destination: profile.skills,
28426
- type: "dir"
28427
- },
28428
28428
  {
28429
28429
  component: "commands",
28430
28430
  sourceKey: "commands",
@@ -28490,6 +28490,19 @@ function syncClaudeCode(config, sourceRoot, options, logger, mappings, manifest,
28490
28490
  )
28491
28491
  );
28492
28492
  }
28493
+ if (!shouldSkipComponent6(options, "skills")) {
28494
+ outcomes.push(
28495
+ ...syncClaudeCodeSkills(
28496
+ config,
28497
+ sourceRoot,
28498
+ options,
28499
+ logger,
28500
+ profile.skills,
28501
+ manifest,
28502
+ scopePath
28503
+ )
28504
+ );
28505
+ }
28493
28506
  if (!shouldSkipComponent6(options, "instructions") && manifest && scopePath) {
28494
28507
  const shimPath = profile.instructions_shim;
28495
28508
  const agentsMdPath = path36.resolve(sourceRoot, config.source.instructions);
@@ -28662,6 +28675,128 @@ function syncDirectComponent(config, sourceRoot, options, logger, directComponen
28662
28675
  path: destination
28663
28676
  };
28664
28677
  }
28678
+ function syncClaudeCodeSkills(config, sourceRoot, options, logger, destination, manifest, scopePath) {
28679
+ const source = path36.resolve(sourceRoot, config.source.skills);
28680
+ if (!fs34.existsSync(source)) {
28681
+ return [skippedMissingSource6("skills", source)];
28682
+ }
28683
+ const declaredNames = resolveKitSkillNames(sourceRoot);
28684
+ const isLegacyWholesaleSymlink = isSymlinkPath(destination);
28685
+ if (options.dryRun) {
28686
+ const outcomes2 = [];
28687
+ if (isLegacyWholesaleSymlink) {
28688
+ for (const name of foreignSkillNames(source, declaredNames)) {
28689
+ logger.info(
28690
+ `[dry-run] skills: migrate foreign skill ${path36.join(source, name)} -> ${path36.join(destination, name)}`
28691
+ );
28692
+ }
28693
+ logger.info(
28694
+ `[dry-run] skills: replace wholesale symlink with real directory ${destination}`
28695
+ );
28696
+ }
28697
+ for (const name of declaredNames ?? listSkillDirNames(source)) {
28698
+ const skillDestination = path36.join(destination, name);
28699
+ logger.info(
28700
+ `[dry-run] skills: symlink ${path36.join(source, name)} -> ${skillDestination}`
28701
+ );
28702
+ outcomes2.push({
28703
+ component: "skills",
28704
+ status: "dry-run",
28705
+ path: skillDestination
28706
+ });
28707
+ }
28708
+ return outcomes2;
28709
+ }
28710
+ if (isLegacyWholesaleSymlink) {
28711
+ migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger);
28712
+ }
28713
+ ensureDir(destination);
28714
+ const outcomes = [];
28715
+ for (const name of declaredNames ?? listSkillDirNames(source)) {
28716
+ outcomes.push(
28717
+ syncSingleSkill(
28718
+ config,
28719
+ sourceRoot,
28720
+ options,
28721
+ logger,
28722
+ source,
28723
+ destination,
28724
+ name,
28725
+ manifest,
28726
+ scopePath
28727
+ )
28728
+ );
28729
+ }
28730
+ return outcomes;
28731
+ }
28732
+ function syncSingleSkill(config, sourceRoot, options, logger, source, destination, name, manifest, scopePath) {
28733
+ const skillSource = path36.join(source, name);
28734
+ const skillDestination = path36.join(destination, name);
28735
+ if (!fs34.existsSync(skillSource)) {
28736
+ return skippedMissingSource6("skills", skillSource);
28737
+ }
28738
+ const artifactClass = classifyArtifact(skillDestination, config, sourceRoot);
28739
+ if (artifactClass === "managed-symlink" && isSymlinkTo6(skillDestination, skillSource)) {
28740
+ return {
28741
+ component: "skills",
28742
+ status: "skipped-current",
28743
+ path: skillDestination
28744
+ };
28745
+ }
28746
+ if (artifactClass === "managed-stale" && isOurStaleSymlink(skillDestination, /* @__PURE__ */ new Set([skillDestination]), config)) {
28747
+ fs34.unlinkSync(skillDestination);
28748
+ } else if (artifactClass === "unmanaged-conflict" && !handleConflict6(
28749
+ skillDestination,
28750
+ config,
28751
+ options,
28752
+ logger,
28753
+ manifest,
28754
+ scopePath
28755
+ )) {
28756
+ return { component: "skills", status: "conflict", path: skillDestination };
28757
+ } else if (artifactClass === "managed-symlink") {
28758
+ fs34.unlinkSync(skillDestination);
28759
+ }
28760
+ createRelativeSymlink(skillSource, skillDestination, "dir");
28761
+ return { component: "skills", status: "success", path: skillDestination };
28762
+ }
28763
+ function migrateWholesaleSkillsSymlink(source, destination, declaredNames, logger) {
28764
+ const foreignNames = foreignSkillNames(source, declaredNames);
28765
+ fs34.unlinkSync(destination);
28766
+ ensureDir(destination);
28767
+ for (const name of foreignNames) {
28768
+ const from = path36.join(source, name);
28769
+ const to = path36.join(destination, name);
28770
+ if (fs34.existsSync(to)) {
28771
+ logger.warn(
28772
+ `skills migration: ${to} already exists \u2014 skipping move of ${from} to avoid overwrite`
28773
+ );
28774
+ continue;
28775
+ }
28776
+ fs34.renameSync(from, to);
28777
+ logger.info(`skills migration: moved ${from} -> ${to}`);
28778
+ }
28779
+ }
28780
+ function foreignSkillNames(source, declaredNames) {
28781
+ if (!declaredNames) {
28782
+ return [];
28783
+ }
28784
+ const declaredSet = new Set(declaredNames);
28785
+ return listSkillDirNames(source).filter((name) => !declaredSet.has(name));
28786
+ }
28787
+ function listSkillDirNames(dir) {
28788
+ if (!fs34.existsSync(dir)) {
28789
+ return [];
28790
+ }
28791
+ return fs34.readdirSync(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
28792
+ }
28793
+ function isSymlinkPath(filePath) {
28794
+ try {
28795
+ return fs34.lstatSync(filePath).isSymbolicLink();
28796
+ } catch {
28797
+ return false;
28798
+ }
28799
+ }
28665
28800
  function syncHookScriptsBridge(config, sourceRoot, options, logger, destination, manifest, scopePath) {
28666
28801
  const source = path36.resolve(sourceRoot, config.source.hooks);
28667
28802
  if (!fs34.existsSync(source)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alessandroraffa/tangyr",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "CLI for the Tangyr discipline — install and manage operating kits for AI coding tools",
5
5
  "license": "MIT",
6
6
  "type": "module",