rulesync 9.4.0 → 9.6.0

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/README.md CHANGED
@@ -97,7 +97,7 @@ The tables below show whether each tool supports a given feature (✅ = supporte
97
97
  | Takt | ✅ | | ✅ | ✅ | ✅ | ✅ | | ✅ |
98
98
  | Vibe Code | ✅ | ✅ | ✅ | | ✅ | ✅ | ✅ | ✅ |
99
99
  | Qwen Code | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
100
- | Reasonix | | | ✅ | ✅ | | | ✅ | ✅ |
100
+ | Reasonix || | ✅ | ✅ | || ✅ | ✅ |
101
101
  | Kiro ⚠️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
102
102
  | Kiro CLI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
103
103
  | Kiro IDE | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_import = require("../import-DVGMvuhx.cjs");
2
+ const require_import = require("../import-CiS5ckUo.cjs");
3
3
  let commander = require("commander");
4
4
  let zod_mini = require("zod/mini");
5
5
  let node_path = require("node:path");
@@ -2023,7 +2023,7 @@ function parseApmLock(content) {
2023
2023
  if (!content.trim()) return null;
2024
2024
  let loaded;
2025
2025
  try {
2026
- loaded = (0, js_yaml.load)(content);
2026
+ loaded = require_import.loadYaml(content);
2027
2027
  } catch {
2028
2028
  return null;
2029
2029
  }
@@ -2093,7 +2093,7 @@ async function apmManifestExists(projectRoot) {
2093
2093
  * or any dependency entry fails normalization.
2094
2094
  */
2095
2095
  function parseApmManifest(content) {
2096
- const loaded = (0, js_yaml.load)(content);
2096
+ const loaded = require_import.loadYaml(content);
2097
2097
  if (loaded === void 0 || loaded === null) return { dependencies: [] };
2098
2098
  const parsed = ApmManifestSchema.safeParse(loaded);
2099
2099
  if (!parsed.success) throw new Error(`Invalid apm.yml: ${parsed.error.message}`);
@@ -2582,7 +2582,7 @@ function injectSourceMetadata(params) {
2582
2582
  }
2583
2583
  let loaded;
2584
2584
  try {
2585
- loaded = (0, js_yaml.load)(fmBody);
2585
+ loaded = require_import.loadYaml(fmBody);
2586
2586
  } catch {
2587
2587
  throw new Error("invalid frontmatter");
2588
2588
  }
@@ -2668,7 +2668,7 @@ function parseGhLock(content) {
2668
2668
  if (!content.trim()) return null;
2669
2669
  let loaded;
2670
2670
  try {
2671
- loaded = (0, js_yaml.load)(content);
2671
+ loaded = require_import.loadYaml(content);
2672
2672
  } catch {
2673
2673
  return null;
2674
2674
  }
@@ -3803,6 +3803,21 @@ function getFirstPathSeparatorIndex(path) {
3803
3803
  if (backslashIndex === -1) return slashIndex;
3804
3804
  return Math.min(slashIndex, backslashIndex);
3805
3805
  }
3806
+ /**
3807
+ * Decide whether a repository's root-level files should be installed as the
3808
+ * single requested skill (the "root fallback").
3809
+ *
3810
+ * A root fallback fires only when a single, non-wildcard skill was requested,
3811
+ * that skill's own directory is absent, and the repository root actually carries
3812
+ * a `SKILL.md`. Both the git transport (`groupRemoteFilesBySkillRoot`) and the
3813
+ * GitHub transport (`discoverGithubSkillDirs`) gate on these same conditions, so
3814
+ * the decision lives here to keep the two paths from drifting.
3815
+ */
3816
+ function shouldUseRootFallback(params) {
3817
+ const { skillFilter, isWildcard, hasRootSkillFile, hasRequestedSkillDir } = params;
3818
+ const [singleSkillName] = skillFilter;
3819
+ return !isWildcard && skillFilter.length === 1 && singleSkillName !== void 0 && hasRootSkillFile && !hasRequestedSkillDir;
3820
+ }
3806
3821
  function groupRemoteFilesBySkillRoot(params) {
3807
3822
  const { remoteFiles, skillFilter, isWildcard } = params;
3808
3823
  const grouped = /* @__PURE__ */ new Map();
@@ -3825,7 +3840,12 @@ function groupRemoteFilesBySkillRoot(params) {
3825
3840
  }
3826
3841
  const [singleSkillName] = skillFilter;
3827
3842
  const hasRootSkillFile = rootLevelFiles.some((file) => file.relativePath === require_import.SKILL_FILE_NAME);
3828
- if (!isWildcard && skillFilter.length === 1 && singleSkillName !== void 0 && hasRootSkillFile && !grouped.has(singleSkillName)) grouped.set(singleSkillName, rootLevelFiles);
3843
+ if (singleSkillName !== void 0 && shouldUseRootFallback({
3844
+ skillFilter,
3845
+ isWildcard,
3846
+ hasRootSkillFile,
3847
+ hasRequestedSkillDir: grouped.has(singleSkillName)
3848
+ })) grouped.set(singleSkillName, rootLevelFiles);
3829
3849
  return grouped;
3830
3850
  }
3831
3851
  /**
@@ -3962,7 +3982,12 @@ async function discoverGithubSkillDirs(params) {
3962
3982
  }));
3963
3983
  const [singleSkillName] = skillFilter;
3964
3984
  const hasRequestedSkillDir = singleSkillName !== void 0 && remoteSkillDirs.some((d) => d.name === singleSkillName);
3965
- if (!isWildcard && skillFilter.length === 1 && !hasRequestedSkillDir) {
3985
+ if (shouldUseRootFallback({
3986
+ skillFilter,
3987
+ isWildcard,
3988
+ hasRootSkillFile: entries.some((entry) => entry.type === "file" && entry.name === "SKILL.md"),
3989
+ hasRequestedSkillDir
3990
+ })) {
3966
3991
  const fallback = await fetchRootLevelFallbackSkill({
3967
3992
  entries,
3968
3993
  parsed,
@@ -6428,7 +6453,7 @@ function wrapCommand$1({ name, errorCode, handler, getVersion, loggerFactory = c
6428
6453
  }
6429
6454
  //#endregion
6430
6455
  //#region src/cli/index.ts
6431
- const getVersion = () => "9.4.0";
6456
+ const getVersion = () => "9.6.0";
6432
6457
  function wrapCommand(name, errorCode, handler) {
6433
6458
  return wrapCommand$1({
6434
6459
  name,
package/dist/cli/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { $ as toPosixPath, A as RulesyncCommand, B as createTempDirectory, C as RulesyncHooks, Ct as RULESYNC_SKILLS_RELATIVE_DIR_PATH, D as CLAUDECODE_MEMORIES_DIR_NAME, Dt as ALL_FEATURES, E as CLAUDECODE_LOCAL_RULE_FILE_NAME, Et as formatError, F as ConsoleLogger, G as getFileSize, H as ensureDir, I as JsonLogger, J as listDirectoryFiles, K as getHomeDirectory, L as CLIError, M as stringifyFrontmatter, N as ConfigResolver, O as CLAUDECODE_SETTINGS_LOCAL_FILE_NAME, Ot as ALL_FEATURES_WITH_WILDCARD, P as findControlCharacter, Q as removeTempDirectory, R as ErrorCodes, S as HooksProcessor, St as RULESYNC_RULES_RELATIVE_DIR_PATH, T as CLAUDECODE_DIR, Tt as RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, U as fileExists, V as directoryExists, W as findFilesByGlobs, X as removeDirectory, Y as readFileContent, Z as removeFile, _ as RulesyncPermissions, _t as RULESYNC_MCP_SCHEMA_URL, a as convertFromTool, at as RULESYNC_AIIGNORE_FILE_NAME, b as IgnoreProcessor, bt as RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH, c as RulesyncRuleFrontmatterSchema, ct as RULESYNC_CONFIG_RELATIVE_FILE_PATH, d as RulesyncSubagentFrontmatterSchema, dt as RULESYNC_HOOKS_FILE_NAME, et as writeFileContent, f as SkillsProcessor, ft as RULESYNC_HOOKS_RELATIVE_FILE_PATH, g as SKILL_FILE_NAME$1, gt as RULESYNC_MCP_RELATIVE_FILE_PATH, h as RulesyncSkillFrontmatterSchema, ht as RULESYNC_MCP_FILE_NAME, i as getProcessorRegistryEntry, it as MAX_FILE_SIZE, j as RulesyncCommandFrontmatterSchema, k as CLAUDECODE_SKILLS_DIR_PATH, l as SubagentsProcessor, lt as RULESYNC_CONFIG_SCHEMA_URL, m as RulesyncSkill, mt as RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH, n as checkRulesyncDirExists, nt as ALL_TOOL_TARGETS_WITH_WILDCARD, o as RulesProcessor, ot as RULESYNC_AIIGNORE_RELATIVE_FILE_PATH, p as getLocalSkillDirNames, pt as RULESYNC_IGNORE_RELATIVE_FILE_PATH, q as isSymlink, r as generate, rt as ToolTargetSchema, s as RulesyncRule, st as RULESYNC_COMMANDS_RELATIVE_DIR_PATH, t as importFromTool, tt as ALL_TOOL_TARGETS, u as RulesyncSubagent, ut as RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH, v as McpProcessor, vt as RULESYNC_OVERVIEW_FILE_NAME, w as CommandsProcessor, wt as RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH, x as RulesyncIgnore, xt as RULESYNC_RELATIVE_DIR_PATH, y as RulesyncMcp, yt as RULESYNC_PERMISSIONS_FILE_NAME, z as checkPathTraversal } from "../import-BxqZVTKb.js";
2
+ import { $ as removeTempDirectory, A as RulesyncCommand, B as checkPathTraversal, C as RulesyncHooks, Ct as RULESYNC_RULES_RELATIVE_DIR_PATH, D as CLAUDECODE_MEMORIES_DIR_NAME, Dt as formatError, E as CLAUDECODE_LOCAL_RULE_FILE_NAME, Et as RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, F as findControlCharacter, G as findFilesByGlobs, H as directoryExists, I as ConsoleLogger, J as isSymlink, K as getFileSize, L as JsonLogger, M as stringifyFrontmatter, N as loadYaml, O as CLAUDECODE_SETTINGS_LOCAL_FILE_NAME, Ot as ALL_FEATURES, P as ConfigResolver, Q as removeFile, R as CLIError, S as HooksProcessor, St as RULESYNC_RELATIVE_DIR_PATH, T as CLAUDECODE_DIR, Tt as RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH, U as ensureDir, V as createTempDirectory, W as fileExists, X as readFileContent, Y as listDirectoryFiles, Z as removeDirectory, _ as RulesyncPermissions, _t as RULESYNC_MCP_RELATIVE_FILE_PATH, a as convertFromTool, at as MAX_FILE_SIZE, b as IgnoreProcessor, bt as RULESYNC_PERMISSIONS_FILE_NAME, c as RulesyncRuleFrontmatterSchema, ct as RULESYNC_COMMANDS_RELATIVE_DIR_PATH, d as RulesyncSubagentFrontmatterSchema, dt as RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH, et as toPosixPath, f as SkillsProcessor, ft as RULESYNC_HOOKS_FILE_NAME, g as SKILL_FILE_NAME$1, gt as RULESYNC_MCP_FILE_NAME, h as RulesyncSkillFrontmatterSchema, ht as RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH, i as getProcessorRegistryEntry, it as ToolTargetSchema, j as RulesyncCommandFrontmatterSchema, k as CLAUDECODE_SKILLS_DIR_PATH, kt as ALL_FEATURES_WITH_WILDCARD, l as SubagentsProcessor, lt as RULESYNC_CONFIG_RELATIVE_FILE_PATH, m as RulesyncSkill, mt as RULESYNC_IGNORE_RELATIVE_FILE_PATH, n as checkRulesyncDirExists, nt as ALL_TOOL_TARGETS, o as RulesProcessor, ot as RULESYNC_AIIGNORE_FILE_NAME, p as getLocalSkillDirNames, pt as RULESYNC_HOOKS_RELATIVE_FILE_PATH, q as getHomeDirectory, r as generate, rt as ALL_TOOL_TARGETS_WITH_WILDCARD, s as RulesyncRule, st as RULESYNC_AIIGNORE_RELATIVE_FILE_PATH, t as importFromTool, tt as writeFileContent, u as RulesyncSubagent, ut as RULESYNC_CONFIG_SCHEMA_URL, v as McpProcessor, vt as RULESYNC_MCP_SCHEMA_URL, w as CommandsProcessor, wt as RULESYNC_SKILLS_RELATIVE_DIR_PATH, x as RulesyncIgnore, xt as RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH, y as RulesyncMcp, yt as RULESYNC_OVERVIEW_FILE_NAME, z as ErrorCodes } from "../import-B6nwZmGl.js";
3
3
  import { Command } from "commander";
4
4
  import { nonnegative, optional, refine, z } from "zod/mini";
5
5
  import * as path$1 from "node:path";
6
6
  import { basename, dirname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
7
7
  import * as os$1 from "node:os";
8
8
  import { promisify } from "node:util";
9
- import { dump, load } from "js-yaml";
9
+ import { dump } from "js-yaml";
10
10
  import { Semaphore } from "es-toolkit/promise";
11
11
  import { RequestError } from "@octokit/request-error";
12
12
  import { Octokit } from "@octokit/rest";
@@ -2021,7 +2021,7 @@ function parseApmLock(content) {
2021
2021
  if (!content.trim()) return null;
2022
2022
  let loaded;
2023
2023
  try {
2024
- loaded = load(content);
2024
+ loaded = loadYaml(content);
2025
2025
  } catch {
2026
2026
  return null;
2027
2027
  }
@@ -2091,7 +2091,7 @@ async function apmManifestExists(projectRoot) {
2091
2091
  * or any dependency entry fails normalization.
2092
2092
  */
2093
2093
  function parseApmManifest(content) {
2094
- const loaded = load(content);
2094
+ const loaded = loadYaml(content);
2095
2095
  if (loaded === void 0 || loaded === null) return { dependencies: [] };
2096
2096
  const parsed = ApmManifestSchema.safeParse(loaded);
2097
2097
  if (!parsed.success) throw new Error(`Invalid apm.yml: ${parsed.error.message}`);
@@ -2580,7 +2580,7 @@ function injectSourceMetadata(params) {
2580
2580
  }
2581
2581
  let loaded;
2582
2582
  try {
2583
- loaded = load(fmBody);
2583
+ loaded = loadYaml(fmBody);
2584
2584
  } catch {
2585
2585
  throw new Error("invalid frontmatter");
2586
2586
  }
@@ -2666,7 +2666,7 @@ function parseGhLock(content) {
2666
2666
  if (!content.trim()) return null;
2667
2667
  let loaded;
2668
2668
  try {
2669
- loaded = load(content);
2669
+ loaded = loadYaml(content);
2670
2670
  } catch {
2671
2671
  return null;
2672
2672
  }
@@ -3801,6 +3801,21 @@ function getFirstPathSeparatorIndex(path) {
3801
3801
  if (backslashIndex === -1) return slashIndex;
3802
3802
  return Math.min(slashIndex, backslashIndex);
3803
3803
  }
3804
+ /**
3805
+ * Decide whether a repository's root-level files should be installed as the
3806
+ * single requested skill (the "root fallback").
3807
+ *
3808
+ * A root fallback fires only when a single, non-wildcard skill was requested,
3809
+ * that skill's own directory is absent, and the repository root actually carries
3810
+ * a `SKILL.md`. Both the git transport (`groupRemoteFilesBySkillRoot`) and the
3811
+ * GitHub transport (`discoverGithubSkillDirs`) gate on these same conditions, so
3812
+ * the decision lives here to keep the two paths from drifting.
3813
+ */
3814
+ function shouldUseRootFallback(params) {
3815
+ const { skillFilter, isWildcard, hasRootSkillFile, hasRequestedSkillDir } = params;
3816
+ const [singleSkillName] = skillFilter;
3817
+ return !isWildcard && skillFilter.length === 1 && singleSkillName !== void 0 && hasRootSkillFile && !hasRequestedSkillDir;
3818
+ }
3804
3819
  function groupRemoteFilesBySkillRoot(params) {
3805
3820
  const { remoteFiles, skillFilter, isWildcard } = params;
3806
3821
  const grouped = /* @__PURE__ */ new Map();
@@ -3823,7 +3838,12 @@ function groupRemoteFilesBySkillRoot(params) {
3823
3838
  }
3824
3839
  const [singleSkillName] = skillFilter;
3825
3840
  const hasRootSkillFile = rootLevelFiles.some((file) => file.relativePath === SKILL_FILE_NAME$1);
3826
- if (!isWildcard && skillFilter.length === 1 && singleSkillName !== void 0 && hasRootSkillFile && !grouped.has(singleSkillName)) grouped.set(singleSkillName, rootLevelFiles);
3841
+ if (singleSkillName !== void 0 && shouldUseRootFallback({
3842
+ skillFilter,
3843
+ isWildcard,
3844
+ hasRootSkillFile,
3845
+ hasRequestedSkillDir: grouped.has(singleSkillName)
3846
+ })) grouped.set(singleSkillName, rootLevelFiles);
3827
3847
  return grouped;
3828
3848
  }
3829
3849
  /**
@@ -3960,7 +3980,12 @@ async function discoverGithubSkillDirs(params) {
3960
3980
  }));
3961
3981
  const [singleSkillName] = skillFilter;
3962
3982
  const hasRequestedSkillDir = singleSkillName !== void 0 && remoteSkillDirs.some((d) => d.name === singleSkillName);
3963
- if (!isWildcard && skillFilter.length === 1 && !hasRequestedSkillDir) {
3983
+ if (shouldUseRootFallback({
3984
+ skillFilter,
3985
+ isWildcard,
3986
+ hasRootSkillFile: entries.some((entry) => entry.type === "file" && entry.name === "SKILL.md"),
3987
+ hasRequestedSkillDir
3988
+ })) {
3964
3989
  const fallback = await fetchRootLevelFallbackSkill({
3965
3990
  entries,
3966
3991
  parsed,
@@ -6426,7 +6451,7 @@ function wrapCommand$1({ name, errorCode, handler, getVersion, loggerFactory = c
6426
6451
  }
6427
6452
  //#endregion
6428
6453
  //#region src/cli/index.ts
6429
- const getVersion = () => "9.4.0";
6454
+ const getVersion = () => "9.6.0";
6430
6455
  function wrapCommand(name, errorCode, handler) {
6431
6456
  return wrapCommand$1({
6432
6457
  name,