rulesync 8.16.0 → 8.18.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/dist/cli/index.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  stringifyFrontmatter,
80
80
  toPosixPath,
81
81
  writeFileContent
82
- } from "../chunk-DOWXY74I.js";
82
+ } from "../chunk-KDGHMXTY.js";
83
83
 
84
84
  // src/cli/index.ts
85
85
  import { Command } from "commander";
@@ -6485,7 +6485,7 @@ function wrapCommand({
6485
6485
  }
6486
6486
 
6487
6487
  // src/cli/index.ts
6488
- var getVersion = () => "8.16.0";
6488
+ var getVersion = () => "8.18.0";
6489
6489
  function wrapCommand2(name, errorCode, handler) {
6490
6490
  return wrapCommand({ name, errorCode, handler, getVersion });
6491
6491
  }
package/dist/index.cjs CHANGED
@@ -7516,6 +7516,16 @@ var McpServerSchema = import_mini24.z.looseObject({
7516
7516
  tools: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string())),
7517
7517
  kiroAutoApprove: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string())),
7518
7518
  kiroAutoBlock: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string())),
7519
+ // Codex CLI-specific: list of shell env var names that codex should pass
7520
+ // through from the user's environment to the MCP server process.
7521
+ // Distinct from `env` (a literal name→value map): `envVars` is a list of
7522
+ // variable NAMES whose values come from the user's shell at runtime.
7523
+ // Only honoured by the codex generator (renamed to `env_vars` in codex
7524
+ // TOML output, matching codex's native field name — see the
7525
+ // `enabledTools`→`enabled_tools` precedent in `codexcli-mcp.ts`).
7526
+ // Stripped by `RulesyncMcp.getMcpServers()` so it does not leak into
7527
+ // other tools' configs.
7528
+ envVars: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string())),
7519
7529
  headers: import_mini24.z.optional(import_mini24.z.record(import_mini24.z.string(), import_mini24.z.string())),
7520
7530
  enabledTools: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string())),
7521
7531
  disabledTools: import_mini24.z.optional(import_mini24.z.array(import_mini24.z.string()))
@@ -7618,10 +7628,11 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
7618
7628
  });
7619
7629
  }
7620
7630
  getMcpServers() {
7621
- const entries = Object.entries(this.json.mcpServers);
7631
+ const mcpServers = this.json.mcpServers ?? {};
7632
+ const entries = Object.entries(mcpServers);
7622
7633
  return Object.fromEntries(
7623
7634
  entries.map(([serverName, serverConfig]) => {
7624
- return [serverName, (0, import_object.omit)(serverConfig, ["targets", "description", "exposed"])];
7635
+ return [serverName, (0, import_object.omit)(serverConfig, ["targets", "description", "exposed", "envVars"])];
7625
7636
  })
7626
7637
  );
7627
7638
  }
@@ -7840,11 +7851,17 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
7840
7851
  rulesyncMcp,
7841
7852
  validate = true
7842
7853
  }) {
7854
+ const json = rulesyncMcp.getJson();
7855
+ const fileContent = JSON.stringify(
7856
+ { ...json, mcpServers: rulesyncMcp.getMcpServers() },
7857
+ null,
7858
+ 2
7859
+ );
7843
7860
  return new _ClineMcp({
7844
7861
  outputRoot,
7845
7862
  relativeDirPath: this.getSettablePaths().relativeDirPath,
7846
7863
  relativeFilePath: this.getSettablePaths().relativeFilePath,
7847
- fileContent: rulesyncMcp.getFileContent(),
7864
+ fileContent,
7848
7865
  validate
7849
7866
  });
7850
7867
  }
@@ -7872,14 +7889,21 @@ var ClineMcp = class _ClineMcp extends ToolMcp {
7872
7889
  // src/features/mcp/codexcli-mcp.ts
7873
7890
  var import_node_path54 = require("path");
7874
7891
  var smolToml3 = __toESM(require("smol-toml"), 1);
7892
+ var MAX_REMOVE_EMPTY_ENTRIES_DEPTH = 32;
7893
+ var PROTOTYPE_POLLUTION_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
7894
+ function isPlainObject2(value) {
7895
+ if (!isRecord(value)) return false;
7896
+ const proto = Object.getPrototypeOf(value);
7897
+ return proto === null || proto === Object.prototype;
7898
+ }
7875
7899
  function convertFromCodexFormat(codexMcp) {
7876
7900
  const result = {};
7877
7901
  for (const [name, config] of Object.entries(codexMcp)) {
7878
- if (typeof config !== "object" || config === null || Array.isArray(config)) {
7879
- continue;
7880
- }
7902
+ if (PROTOTYPE_POLLUTION_KEYS.has(name)) continue;
7903
+ if (!isRecord(config)) continue;
7881
7904
  const converted = {};
7882
7905
  for (const [key, value] of Object.entries(config)) {
7906
+ if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
7883
7907
  if (key === "enabled") {
7884
7908
  if (value === false) {
7885
7909
  converted["disabled"] = true;
@@ -7888,6 +7912,8 @@ function convertFromCodexFormat(codexMcp) {
7888
7912
  converted["enabledTools"] = value;
7889
7913
  } else if (key === "disabled_tools") {
7890
7914
  converted["disabledTools"] = value;
7915
+ } else if (key === "env_vars") {
7916
+ converted["envVars"] = value;
7891
7917
  } else {
7892
7918
  converted[key] = value;
7893
7919
  }
@@ -7899,8 +7925,11 @@ function convertFromCodexFormat(codexMcp) {
7899
7925
  function convertToCodexFormat(mcpServers) {
7900
7926
  const result = {};
7901
7927
  for (const [name, config] of Object.entries(mcpServers)) {
7928
+ if (PROTOTYPE_POLLUTION_KEYS.has(name)) continue;
7929
+ if (!isRecord(config)) continue;
7902
7930
  const converted = {};
7903
7931
  for (const [key, value] of Object.entries(config)) {
7932
+ if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
7904
7933
  if (key === "disabled") {
7905
7934
  if (value === true) {
7906
7935
  converted["enabled"] = false;
@@ -7909,6 +7938,8 @@ function convertToCodexFormat(mcpServers) {
7909
7938
  converted["enabled_tools"] = value;
7910
7939
  } else if (key === "disabledTools") {
7911
7940
  converted["disabled_tools"] = value;
7941
+ } else if (key === "envVars") {
7942
+ converted["env_vars"] = value;
7912
7943
  } else {
7913
7944
  converted[key] = value;
7914
7945
  }
@@ -7980,6 +8011,14 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
7980
8011
  const mcpServers = rulesyncMcp.getJson().mcpServers;
7981
8012
  const converted = convertToCodexFormat(mcpServers);
7982
8013
  const filteredMcpServers = this.removeEmptyEntries(converted);
8014
+ for (const name of Object.keys(converted)) {
8015
+ if (!Object.hasOwn(filteredMcpServers, name)) {
8016
+ warnWithFallback(
8017
+ void 0,
8018
+ `MCP server "${name}" had no non-empty configuration and was dropped from the codex CLI config`
8019
+ );
8020
+ }
8021
+ }
7983
8022
  configToml["mcp_servers"] = filteredMcpServers;
7984
8023
  return new _CodexcliMcp({
7985
8024
  outputRoot,
@@ -7999,12 +8038,25 @@ var CodexcliMcp = class _CodexcliMcp extends ToolMcp {
7999
8038
  validate() {
8000
8039
  return { success: true, error: null };
8001
8040
  }
8002
- static removeEmptyEntries(obj) {
8041
+ static removeEmptyEntries(obj, depth = 0) {
8003
8042
  if (!obj) return {};
8043
+ if (depth > MAX_REMOVE_EMPTY_ENTRIES_DEPTH) {
8044
+ warnWithFallback(
8045
+ void 0,
8046
+ `removeEmptyEntries: maximum recursion depth (${MAX_REMOVE_EMPTY_ENTRIES_DEPTH}) exceeded; empty nested objects may remain`
8047
+ );
8048
+ return obj;
8049
+ }
8004
8050
  const filtered = {};
8005
8051
  for (const [key, value] of Object.entries(obj)) {
8052
+ if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
8006
8053
  if (value === null) continue;
8007
- if (typeof value === "object" && Object.keys(value).length === 0) continue;
8054
+ if (isPlainObject2(value)) {
8055
+ const cleaned = this.removeEmptyEntries(value, depth + 1);
8056
+ if (Object.keys(cleaned).length === 0) continue;
8057
+ filtered[key] = cleaned;
8058
+ continue;
8059
+ }
8008
8060
  filtered[key] = value;
8009
8061
  }
8010
8062
  return filtered;
@@ -8381,8 +8433,7 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
8381
8433
  { cause: error }
8382
8434
  );
8383
8435
  }
8384
- const rulesyncJson = rulesyncMcp.getJson();
8385
- const mcpServers = isMcpServers(rulesyncJson.mcpServers) ? rulesyncJson.mcpServers : {};
8436
+ const mcpServers = rulesyncMcp.getMcpServers();
8386
8437
  const transformedServers = convertEnvToCursorFormat(mcpServers);
8387
8438
  const cursorConfig = { ...json, mcpServers: transformedServers };
8388
8439
  return new _CursorMcp({
@@ -8551,9 +8602,9 @@ var FactorydroidMcp = class _FactorydroidMcp extends ToolMcp {
8551
8602
  rulesyncMcp,
8552
8603
  validate = true
8553
8604
  }) {
8554
- const json = rulesyncMcp.getJson();
8605
+ const mcpServers = rulesyncMcp.getMcpServers();
8555
8606
  const factorydroidConfig = {
8556
- mcpServers: json.mcpServers || {}
8607
+ mcpServers
8557
8608
  };
8558
8609
  const fileContent = JSON.stringify(factorydroidConfig, null, 2);
8559
8610
  return new _FactorydroidMcp({
@@ -8639,7 +8690,7 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
8639
8690
  JSON.stringify({ mcpServers: {} }, null, 2)
8640
8691
  );
8641
8692
  const json = JSON.parse(fileContent);
8642
- const newJson = { ...json, mcpServers: rulesyncMcp.getJson().mcpServers };
8693
+ const newJson = { ...json, mcpServers: rulesyncMcp.getMcpServers() };
8643
8694
  return new _GeminiCliMcp({
8644
8695
  outputRoot,
8645
8696
  relativeDirPath: paths.relativeDirPath,
@@ -8720,11 +8771,17 @@ var JunieMcp = class _JunieMcp extends ToolMcp {
8720
8771
  rulesyncMcp,
8721
8772
  validate = true
8722
8773
  }) {
8774
+ const json = rulesyncMcp.getJson();
8775
+ const fileContent = JSON.stringify(
8776
+ { ...json, mcpServers: rulesyncMcp.getMcpServers() },
8777
+ null,
8778
+ 2
8779
+ );
8723
8780
  return new _JunieMcp({
8724
8781
  outputRoot,
8725
8782
  relativeDirPath: this.getSettablePaths().relativeDirPath,
8726
8783
  relativeFilePath: this.getSettablePaths().relativeFilePath,
8727
- fileContent: rulesyncMcp.getFileContent(),
8784
+ fileContent,
8728
8785
  validate
8729
8786
  });
8730
8787
  }
@@ -9504,8 +9561,7 @@ var RovodevMcp = class _RovodevMcp extends ToolMcp {
9504
9561
  JSON.stringify({ mcpServers: {} }, null, 2)
9505
9562
  );
9506
9563
  const json = parseRovodevMcpJson(fileContent, paths.relativeDirPath, paths.relativeFilePath);
9507
- const rulesyncJson = rulesyncMcp.getJson();
9508
- const mcpServers = isMcpServers(rulesyncJson.mcpServers) ? rulesyncJson.mcpServers : {};
9564
+ const mcpServers = rulesyncMcp.getMcpServers();
9509
9565
  const rovodevConfig = { ...json, mcpServers };
9510
9566
  return new _RovodevMcp({
9511
9567
  outputRoot,
@@ -9689,7 +9745,13 @@ var toolMcpFactories = /* @__PURE__ */ new Map([
9689
9745
  class: KiloMcp,
9690
9746
  meta: {
9691
9747
  supportsProject: true,
9692
- supportsGlobal: false,
9748
+ // Kilo CLI reads global MCP from `~/.config/kilo/kilo.json` (or
9749
+ // `kilo.jsonc`). The path machinery in `KiloMcp.getSettablePaths`
9750
+ // already routes global mode to that location; only this flag
9751
+ // was gating it off. Kilo is an OpenCode fork and uses an
9752
+ // identical native MCP schema, so global parity with opencode
9753
+ // is the natural state.
9754
+ supportsGlobal: true,
9693
9755
  supportsEnabledTools: false,
9694
9756
  supportsDisabledTools: false
9695
9757
  }
@@ -10930,7 +10992,8 @@ function convertRulesyncToCodexProfile({
10930
10992
  filesystem,
10931
10993
  projectRootFilesystem,
10932
10994
  pattern,
10933
- access: mapReadAction(action)
10995
+ access: mapReadAction(action),
10996
+ logger
10934
10997
  });
10935
10998
  }
10936
10999
  continue;
@@ -10941,7 +11004,8 @@ function convertRulesyncToCodexProfile({
10941
11004
  filesystem,
10942
11005
  projectRootFilesystem,
10943
11006
  pattern,
10944
- access: mapWriteAction(action)
11007
+ access: mapWriteAction(action),
11008
+ logger
10945
11009
  });
10946
11010
  }
10947
11011
  continue;
@@ -10963,6 +11027,11 @@ function convertRulesyncToCodexProfile({
10963
11027
  );
10964
11028
  }
10965
11029
  if (Object.keys(projectRootFilesystem).length > 0) {
11030
+ if (typeof filesystem[CODEX_PROJECT_ROOTS_KEY] === "string") {
11031
+ logger?.warn(
11032
+ `"${CODEX_PROJECT_ROOTS_KEY}" is set as a direct filesystem access rule in the permissions, but it will be overwritten by project-root rules. Consider removing the direct "${CODEX_PROJECT_ROOTS_KEY}" entry.`
11033
+ );
11034
+ }
10966
11035
  if (Object.keys(projectRootFilesystem).some((pattern) => pattern.includes("**"))) {
10967
11036
  filesystem.glob_scan_max_depth = CODEX_GLOB_SCAN_MAX_DEPTH;
10968
11037
  }
@@ -11013,8 +11082,13 @@ function addFilesystemRule({
11013
11082
  filesystem,
11014
11083
  projectRootFilesystem,
11015
11084
  pattern,
11016
- access
11085
+ access,
11086
+ logger
11017
11087
  }) {
11088
+ if (pattern.trim() === "") {
11089
+ logger?.warn("Skipping empty pattern in filesystem permissions.");
11090
+ return;
11091
+ }
11018
11092
  if (canBeCodexFilesystemRoot(pattern)) {
11019
11093
  filesystem[pattern] = access;
11020
11094
  return;
@@ -12798,7 +12872,7 @@ var PermissionsProcessor = class extends FeatureProcessor {
12798
12872
  // src/features/rules/rules-processor.ts
12799
12873
  var import_node_path154 = require("path");
12800
12874
  var import_toon = require("@toon-format/toon");
12801
- var import_mini79 = require("zod/mini");
12875
+ var import_mini80 = require("zod/mini");
12802
12876
 
12803
12877
  // src/constants/general.ts
12804
12878
  var SKILL_FILE_NAME = "SKILL.md";
@@ -17750,7 +17824,7 @@ var RovodevSubagent = class _RovodevSubagent extends ToolSubagent {
17750
17824
 
17751
17825
  // src/features/subagents/subagents-processor.ts
17752
17826
  var import_node_path125 = require("path");
17753
- var import_mini72 = require("zod/mini");
17827
+ var import_mini73 = require("zod/mini");
17754
17828
 
17755
17829
  // src/features/subagents/claudecode-subagent.ts
17756
17830
  var import_node_path113 = require("path");
@@ -18910,6 +18984,7 @@ var JunieSubagent = class _JunieSubagent extends ToolSubagent {
18910
18984
 
18911
18985
  // src/features/subagents/kilo-subagent.ts
18912
18986
  var import_node_path121 = require("path");
18987
+ var import_mini71 = require("zod/mini");
18913
18988
 
18914
18989
  // src/features/subagents/opencode-style-subagent.ts
18915
18990
  var import_node_path120 = require("path");
@@ -18976,7 +19051,13 @@ var OpenCodeStyleSubagent = class extends ToolSubagent {
18976
19051
  };
18977
19052
 
18978
19053
  // src/features/subagents/kilo-subagent.ts
18979
- var KiloSubagentFrontmatterSchema = OpenCodeStyleSubagentFrontmatterSchema;
19054
+ var KiloSubagentFrontmatterSchema = import_mini71.z.looseObject({
19055
+ description: import_mini71.z.optional(import_mini71.z.string()),
19056
+ // Kilo's documented default for user-defined agents is "all":
19057
+ // available both as a top-level pick and as a subagent.
19058
+ mode: import_mini71.z._default(import_mini71.z.string(), "all"),
19059
+ name: import_mini71.z.optional(import_mini71.z.string())
19060
+ });
18980
19061
  var KiloSubagent = class _KiloSubagent extends OpenCodeStyleSubagent {
18981
19062
  getToolTarget() {
18982
19063
  return "kilo";
@@ -18996,12 +19077,11 @@ var KiloSubagent = class _KiloSubagent extends OpenCodeStyleSubagent {
18996
19077
  }) {
18997
19078
  const rulesyncFrontmatter = rulesyncSubagent.getFrontmatter();
18998
19079
  const kiloSection = rulesyncFrontmatter.kilo ?? {};
18999
- const kiloFrontmatter = {
19080
+ const kiloFrontmatter = KiloSubagentFrontmatterSchema.parse({
19000
19081
  ...kiloSection,
19001
19082
  description: rulesyncFrontmatter.description,
19002
- mode: typeof kiloSection.mode === "string" ? kiloSection.mode : "subagent",
19003
19083
  ...rulesyncFrontmatter.name && { name: rulesyncFrontmatter.name }
19004
- };
19084
+ });
19005
19085
  const body = rulesyncSubagent.getBody();
19006
19086
  const fileContent = stringifyFrontmatter(body, kiloFrontmatter);
19007
19087
  const paths = this.getSettablePaths({ global });
@@ -19050,38 +19130,40 @@ var KiloSubagent = class _KiloSubagent extends OpenCodeStyleSubagent {
19050
19130
  static forDeletion({
19051
19131
  outputRoot = process.cwd(),
19052
19132
  relativeDirPath,
19053
- relativeFilePath
19133
+ relativeFilePath,
19134
+ global = false
19054
19135
  }) {
19055
19136
  return new _KiloSubagent({
19056
19137
  outputRoot,
19057
19138
  relativeDirPath,
19058
19139
  relativeFilePath,
19059
- frontmatter: { description: "", mode: "subagent" },
19140
+ frontmatter: { description: "", mode: "all" },
19060
19141
  body: "",
19061
19142
  fileContent: "",
19062
- validate: false
19143
+ validate: false,
19144
+ global
19063
19145
  });
19064
19146
  }
19065
19147
  };
19066
19148
 
19067
19149
  // src/features/subagents/kiro-subagent.ts
19068
19150
  var import_node_path122 = require("path");
19069
- var import_mini71 = require("zod/mini");
19070
- var KiroCliSubagentJsonSchema = import_mini71.z.looseObject({
19071
- name: import_mini71.z.string(),
19072
- description: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.string())),
19073
- prompt: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.string())),
19074
- tools: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.array(import_mini71.z.string()))),
19075
- toolAliases: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.record(import_mini71.z.string(), import_mini71.z.string()))),
19076
- toolSettings: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.unknown())),
19077
- toolSchema: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.unknown())),
19078
- hooks: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.record(import_mini71.z.string(), import_mini71.z.array(import_mini71.z.unknown())))),
19079
- model: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.string())),
19080
- mcpServers: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.record(import_mini71.z.string(), import_mini71.z.unknown()))),
19081
- useLegacyMcpJson: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.boolean())),
19082
- resources: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.array(import_mini71.z.string()))),
19083
- allowedTools: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.array(import_mini71.z.string()))),
19084
- includeMcpJson: import_mini71.z.optional(import_mini71.z.nullable(import_mini71.z.boolean()))
19151
+ var import_mini72 = require("zod/mini");
19152
+ var KiroCliSubagentJsonSchema = import_mini72.z.looseObject({
19153
+ name: import_mini72.z.string(),
19154
+ description: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.string())),
19155
+ prompt: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.string())),
19156
+ tools: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.array(import_mini72.z.string()))),
19157
+ toolAliases: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.record(import_mini72.z.string(), import_mini72.z.string()))),
19158
+ toolSettings: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.unknown())),
19159
+ toolSchema: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.unknown())),
19160
+ hooks: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.record(import_mini72.z.string(), import_mini72.z.array(import_mini72.z.unknown())))),
19161
+ model: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.string())),
19162
+ mcpServers: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.record(import_mini72.z.string(), import_mini72.z.unknown()))),
19163
+ useLegacyMcpJson: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.boolean())),
19164
+ resources: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.array(import_mini72.z.string()))),
19165
+ allowedTools: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.array(import_mini72.z.string()))),
19166
+ includeMcpJson: import_mini72.z.optional(import_mini72.z.nullable(import_mini72.z.boolean()))
19085
19167
  });
19086
19168
  var KiroSubagent = class _KiroSubagent extends ToolSubagent {
19087
19169
  body;
@@ -19447,7 +19529,7 @@ var subagentsProcessorToolTargetTuple = [
19447
19529
  "rovodev",
19448
19530
  "takt"
19449
19531
  ];
19450
- var SubagentsProcessorToolTargetSchema = import_mini72.z.enum(subagentsProcessorToolTargetTuple);
19532
+ var SubagentsProcessorToolTargetSchema = import_mini73.z.enum(subagentsProcessorToolTargetTuple);
19451
19533
  var toolSubagentFactories = /* @__PURE__ */ new Map([
19452
19534
  [
19453
19535
  "agentsmd",
@@ -19776,48 +19858,48 @@ var import_node_path127 = require("path");
19776
19858
 
19777
19859
  // src/features/rules/rulesync-rule.ts
19778
19860
  var import_node_path126 = require("path");
19779
- var import_mini73 = require("zod/mini");
19780
- var RulesyncRuleFrontmatterSchema = import_mini73.z.object({
19781
- root: import_mini73.z.optional(import_mini73.z.boolean()),
19782
- localRoot: import_mini73.z.optional(import_mini73.z.boolean()),
19783
- targets: import_mini73.z._default(RulesyncTargetsSchema, ["*"]),
19784
- description: import_mini73.z.optional(import_mini73.z.string()),
19785
- globs: import_mini73.z.optional(import_mini73.z.array(import_mini73.z.string())),
19786
- agentsmd: import_mini73.z.optional(
19787
- import_mini73.z.looseObject({
19861
+ var import_mini74 = require("zod/mini");
19862
+ var RulesyncRuleFrontmatterSchema = import_mini74.z.object({
19863
+ root: import_mini74.z.optional(import_mini74.z.boolean()),
19864
+ localRoot: import_mini74.z.optional(import_mini74.z.boolean()),
19865
+ targets: import_mini74.z._default(RulesyncTargetsSchema, ["*"]),
19866
+ description: import_mini74.z.optional(import_mini74.z.string()),
19867
+ globs: import_mini74.z.optional(import_mini74.z.array(import_mini74.z.string())),
19868
+ agentsmd: import_mini74.z.optional(
19869
+ import_mini74.z.looseObject({
19788
19870
  // @example "path/to/subproject"
19789
- subprojectPath: import_mini73.z.optional(import_mini73.z.string())
19871
+ subprojectPath: import_mini74.z.optional(import_mini74.z.string())
19790
19872
  })
19791
19873
  ),
19792
- claudecode: import_mini73.z.optional(
19793
- import_mini73.z.looseObject({
19874
+ claudecode: import_mini74.z.optional(
19875
+ import_mini74.z.looseObject({
19794
19876
  // Glob patterns for conditional rules (takes precedence over globs)
19795
19877
  // @example ["src/**/*.ts", "tests/**/*.test.ts"]
19796
- paths: import_mini73.z.optional(import_mini73.z.array(import_mini73.z.string()))
19878
+ paths: import_mini74.z.optional(import_mini74.z.array(import_mini74.z.string()))
19797
19879
  })
19798
19880
  ),
19799
- cursor: import_mini73.z.optional(
19800
- import_mini73.z.looseObject({
19801
- alwaysApply: import_mini73.z.optional(import_mini73.z.boolean()),
19802
- description: import_mini73.z.optional(import_mini73.z.string()),
19803
- globs: import_mini73.z.optional(import_mini73.z.array(import_mini73.z.string()))
19881
+ cursor: import_mini74.z.optional(
19882
+ import_mini74.z.looseObject({
19883
+ alwaysApply: import_mini74.z.optional(import_mini74.z.boolean()),
19884
+ description: import_mini74.z.optional(import_mini74.z.string()),
19885
+ globs: import_mini74.z.optional(import_mini74.z.array(import_mini74.z.string()))
19804
19886
  })
19805
19887
  ),
19806
- copilot: import_mini73.z.optional(
19807
- import_mini73.z.looseObject({
19808
- excludeAgent: import_mini73.z.optional(import_mini73.z.union([import_mini73.z.literal("code-review"), import_mini73.z.literal("coding-agent")]))
19888
+ copilot: import_mini74.z.optional(
19889
+ import_mini74.z.looseObject({
19890
+ excludeAgent: import_mini74.z.optional(import_mini74.z.union([import_mini74.z.literal("code-review"), import_mini74.z.literal("coding-agent")]))
19809
19891
  })
19810
19892
  ),
19811
- antigravity: import_mini73.z.optional(
19812
- import_mini73.z.looseObject({
19813
- trigger: import_mini73.z.optional(import_mini73.z.string()),
19814
- globs: import_mini73.z.optional(import_mini73.z.array(import_mini73.z.string()))
19893
+ antigravity: import_mini74.z.optional(
19894
+ import_mini74.z.looseObject({
19895
+ trigger: import_mini74.z.optional(import_mini74.z.string()),
19896
+ globs: import_mini74.z.optional(import_mini74.z.array(import_mini74.z.string()))
19815
19897
  })
19816
19898
  ),
19817
- takt: import_mini73.z.optional(
19818
- import_mini73.z.looseObject({
19899
+ takt: import_mini74.z.optional(
19900
+ import_mini74.z.looseObject({
19819
19901
  // Rename the emitted file stem (e.g. "coder.md" → "{name}.md").
19820
- name: import_mini73.z.optional(import_mini73.z.string())
19902
+ name: import_mini74.z.optional(import_mini74.z.string())
19821
19903
  })
19822
19904
  )
19823
19905
  });
@@ -20118,20 +20200,20 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
20118
20200
 
20119
20201
  // src/features/rules/antigravity-rule.ts
20120
20202
  var import_node_path129 = require("path");
20121
- var import_mini74 = require("zod/mini");
20122
- var AntigravityRuleFrontmatterSchema = import_mini74.z.looseObject({
20123
- trigger: import_mini74.z.optional(
20124
- import_mini74.z.union([
20125
- import_mini74.z.literal("always_on"),
20126
- import_mini74.z.literal("glob"),
20127
- import_mini74.z.literal("manual"),
20128
- import_mini74.z.literal("model_decision"),
20129
- import_mini74.z.string()
20203
+ var import_mini75 = require("zod/mini");
20204
+ var AntigravityRuleFrontmatterSchema = import_mini75.z.looseObject({
20205
+ trigger: import_mini75.z.optional(
20206
+ import_mini75.z.union([
20207
+ import_mini75.z.literal("always_on"),
20208
+ import_mini75.z.literal("glob"),
20209
+ import_mini75.z.literal("manual"),
20210
+ import_mini75.z.literal("model_decision"),
20211
+ import_mini75.z.string()
20130
20212
  // accepts any string for forward compatibility
20131
20213
  ])
20132
20214
  ),
20133
- globs: import_mini74.z.optional(import_mini74.z.string()),
20134
- description: import_mini74.z.optional(import_mini74.z.string())
20215
+ globs: import_mini75.z.optional(import_mini75.z.string()),
20216
+ description: import_mini75.z.optional(import_mini75.z.string())
20135
20217
  });
20136
20218
  function parseGlobsString(globs) {
20137
20219
  if (!globs) {
@@ -20718,9 +20800,9 @@ var ClaudecodeLegacyRule = class _ClaudecodeLegacyRule extends ToolRule {
20718
20800
 
20719
20801
  // src/features/rules/claudecode-rule.ts
20720
20802
  var import_node_path133 = require("path");
20721
- var import_mini75 = require("zod/mini");
20722
- var ClaudecodeRuleFrontmatterSchema = import_mini75.z.object({
20723
- paths: import_mini75.z.optional(import_mini75.z.array(import_mini75.z.string()))
20803
+ var import_mini76 = require("zod/mini");
20804
+ var ClaudecodeRuleFrontmatterSchema = import_mini76.z.object({
20805
+ paths: import_mini76.z.optional(import_mini76.z.array(import_mini76.z.string()))
20724
20806
  });
20725
20807
  var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
20726
20808
  frontmatter;
@@ -20936,9 +21018,9 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
20936
21018
 
20937
21019
  // src/features/rules/cline-rule.ts
20938
21020
  var import_node_path134 = require("path");
20939
- var import_mini76 = require("zod/mini");
20940
- var ClineRuleFrontmatterSchema = import_mini76.z.object({
20941
- description: import_mini76.z.string()
21021
+ var import_mini77 = require("zod/mini");
21022
+ var ClineRuleFrontmatterSchema = import_mini77.z.object({
21023
+ description: import_mini77.z.string()
20942
21024
  });
20943
21025
  var ClineRule = class _ClineRule extends ToolRule {
20944
21026
  static getSettablePaths(_options = {}) {
@@ -21117,11 +21199,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
21117
21199
 
21118
21200
  // src/features/rules/copilot-rule.ts
21119
21201
  var import_node_path136 = require("path");
21120
- var import_mini77 = require("zod/mini");
21121
- var CopilotRuleFrontmatterSchema = import_mini77.z.object({
21122
- description: import_mini77.z.optional(import_mini77.z.string()),
21123
- applyTo: import_mini77.z.optional(import_mini77.z.string()),
21124
- excludeAgent: import_mini77.z.optional(import_mini77.z.union([import_mini77.z.literal("code-review"), import_mini77.z.literal("coding-agent")]))
21202
+ var import_mini78 = require("zod/mini");
21203
+ var CopilotRuleFrontmatterSchema = import_mini78.z.object({
21204
+ description: import_mini78.z.optional(import_mini78.z.string()),
21205
+ applyTo: import_mini78.z.optional(import_mini78.z.string()),
21206
+ excludeAgent: import_mini78.z.optional(import_mini78.z.union([import_mini78.z.literal("code-review"), import_mini78.z.literal("coding-agent")]))
21125
21207
  });
21126
21208
  var normalizeRelativePath = (path4) => path4.replace(/\\/g, "/").replace(/\/+/g, "/");
21127
21209
  var sameRelativePath = (leftDir, leftFile, rightDir, rightFile) => normalizeRelativePath((0, import_node_path136.join)(leftDir, leftFile)) === normalizeRelativePath((0, import_node_path136.join)(rightDir, rightFile));
@@ -21375,11 +21457,11 @@ var CopilotcliRule = class _CopilotcliRule extends CopilotRule {
21375
21457
 
21376
21458
  // src/features/rules/cursor-rule.ts
21377
21459
  var import_node_path137 = require("path");
21378
- var import_mini78 = require("zod/mini");
21379
- var CursorRuleFrontmatterSchema = import_mini78.z.object({
21380
- description: import_mini78.z.optional(import_mini78.z.string()),
21381
- globs: import_mini78.z.optional(import_mini78.z.string()),
21382
- alwaysApply: import_mini78.z.optional(import_mini78.z.boolean())
21460
+ var import_mini79 = require("zod/mini");
21461
+ var CursorRuleFrontmatterSchema = import_mini79.z.object({
21462
+ description: import_mini79.z.optional(import_mini79.z.string()),
21463
+ globs: import_mini79.z.optional(import_mini79.z.string()),
21464
+ alwaysApply: import_mini79.z.optional(import_mini79.z.boolean())
21383
21465
  });
21384
21466
  var CursorRule = class _CursorRule extends ToolRule {
21385
21467
  frontmatter;
@@ -23262,11 +23344,11 @@ var rulesProcessorToolTargets = [
23262
23344
  "warp",
23263
23345
  "windsurf"
23264
23346
  ];
23265
- var RulesProcessorToolTargetSchema = import_mini79.z.enum(rulesProcessorToolTargets);
23347
+ var RulesProcessorToolTargetSchema = import_mini80.z.enum(rulesProcessorToolTargets);
23266
23348
  var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path154.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
23267
- var RulesFeatureOptionsSchema = import_mini79.z.looseObject({
23268
- ruleDiscoveryMode: import_mini79.z.optional(import_mini79.z.enum(["none", "explicit"])),
23269
- includeLocalRoot: import_mini79.z.optional(import_mini79.z.boolean())
23349
+ var RulesFeatureOptionsSchema = import_mini80.z.looseObject({
23350
+ ruleDiscoveryMode: import_mini80.z.optional(import_mini80.z.enum(["none", "explicit"])),
23351
+ includeLocalRoot: import_mini80.z.optional(import_mini80.z.boolean())
23270
23352
  });
23271
23353
  var resolveRuleDiscoveryMode = ({
23272
23354
  defaultMode,
@@ -23287,8 +23369,8 @@ var resolveRuleDiscoveryMode = ({
23287
23369
  }
23288
23370
  return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
23289
23371
  };
23290
- var IncludeLocalRootSchema = import_mini79.z.looseObject({
23291
- includeLocalRoot: import_mini79.z.optional(import_mini79.z.boolean())
23372
+ var IncludeLocalRootSchema = import_mini80.z.looseObject({
23373
+ includeLocalRoot: import_mini80.z.optional(import_mini80.z.boolean())
23292
23374
  });
23293
23375
  var resolveIncludeLocalRoot = (options) => {
23294
23376
  if (!options) return true;
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  convertFromTool,
8
8
  generate,
9
9
  importFromTool
10
- } from "./chunk-DOWXY74I.js";
10
+ } from "./chunk-KDGHMXTY.js";
11
11
 
12
12
  // src/index.ts
13
13
  async function generate2(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "8.16.0",
3
+ "version": "8.18.0",
4
4
  "description": "Unified AI rules management CLI tool that generates configuration files for various AI development tools",
5
5
  "keywords": [
6
6
  "ai",
@@ -90,6 +90,7 @@
90
90
  "repomix": "1.12.0",
91
91
  "resend": "6.9.4",
92
92
  "secretlint": "11.3.1",
93
+ "simple-git": "3.36.0",
93
94
  "simple-git-hooks": "2.13.1",
94
95
  "sort-package-json": "3.6.1",
95
96
  "tsup": "8.5.1",
@@ -129,6 +130,7 @@
129
130
  "knip": "knip",
130
131
  "oxlint": "oxlint . --max-warnings 0",
131
132
  "oxlint:fix": "oxlint . --fix --max-warnings 0",
133
+ "pr-continuation": "tsx scripts/pr-continuation.ts",
132
134
  "secretlint": "secretlint --secretlintignore .gitignore \"**/*\"",
133
135
  "sort": "sort-package-json",
134
136
  "task": "tsx scripts/run-tasks.ts",