rulesync 8.0.0 → 8.1.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
@@ -28,7 +28,7 @@ npm install -g rulesync
28
28
  brew install rulesync
29
29
  ```
30
30
 
31
- ### Single Binary (Experimental)
31
+ ### Single Binary
32
32
 
33
33
  ```bash
34
34
  curl -fsSL https://github.com/dyoshikawa/rulesync/releases/latest/download/install.sh | bash
@@ -348,6 +348,7 @@ var ConfigParamsSchema = z3.object({
348
348
  simulateCommands: optional(z3.boolean()),
349
349
  simulateSubagents: optional(z3.boolean()),
350
350
  simulateSkills: optional(z3.boolean()),
351
+ gitignoreTargetsOnly: optional(z3.boolean()),
351
352
  dryRun: optional(z3.boolean()),
352
353
  check: optional(z3.boolean()),
353
354
  // Declarative skill sources
@@ -375,6 +376,7 @@ var Config = class _Config {
375
376
  simulateCommands;
376
377
  simulateSubagents;
377
378
  simulateSkills;
379
+ gitignoreTargetsOnly;
378
380
  dryRun;
379
381
  check;
380
382
  sources;
@@ -389,6 +391,7 @@ var Config = class _Config {
389
391
  simulateCommands,
390
392
  simulateSubagents,
391
393
  simulateSkills,
394
+ gitignoreTargetsOnly,
392
395
  dryRun,
393
396
  check,
394
397
  sources
@@ -407,6 +410,7 @@ var Config = class _Config {
407
410
  this.simulateCommands = simulateCommands ?? false;
408
411
  this.simulateSubagents = simulateSubagents ?? false;
409
412
  this.simulateSkills = simulateSkills ?? false;
413
+ this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
410
414
  this.dryRun = dryRun ?? false;
411
415
  this.check = check ?? false;
412
416
  this.sources = sources ?? [];
@@ -532,6 +536,9 @@ var Config = class _Config {
532
536
  getSimulateSkills() {
533
537
  return this.simulateSkills;
534
538
  }
539
+ getGitignoreTargetsOnly() {
540
+ return this.gitignoreTargetsOnly;
541
+ }
535
542
  getDryRun() {
536
543
  return this.dryRun;
537
544
  }
@@ -563,6 +570,7 @@ var getDefaults = () => ({
563
570
  simulateCommands: false,
564
571
  simulateSubagents: false,
565
572
  simulateSkills: false,
573
+ gitignoreTargetsOnly: true,
566
574
  dryRun: false,
567
575
  check: false,
568
576
  sources: []
@@ -589,6 +597,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
589
597
  simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
590
598
  simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
591
599
  simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
600
+ gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
592
601
  dryRun: localConfig.dryRun ?? baseConfig.dryRun,
593
602
  check: localConfig.check ?? baseConfig.check,
594
603
  sources: localConfig.sources ?? baseConfig.sources
@@ -607,6 +616,7 @@ var ConfigResolver = class {
607
616
  simulateCommands,
608
617
  simulateSubagents,
609
618
  simulateSkills,
619
+ gitignoreTargetsOnly,
610
620
  dryRun,
611
621
  check
612
622
  }) {
@@ -620,6 +630,7 @@ var ConfigResolver = class {
620
630
  const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
621
631
  const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
622
632
  const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
633
+ const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
623
634
  const configParams = {
624
635
  targets: targets ?? configByFile.targets ?? getDefaults().targets,
625
636
  features: features ?? configByFile.features ?? getDefaults().features,
@@ -634,6 +645,7 @@ var ConfigResolver = class {
634
645
  simulateCommands: resolvedSimulateCommands,
635
646
  simulateSubagents: resolvedSimulateSubagents,
636
647
  simulateSkills: resolvedSimulateSkills,
648
+ gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
637
649
  dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
638
650
  check: check ?? configByFile.check ?? getDefaults().check,
639
651
  sources: configByFile.sources ?? getDefaults().sources
@@ -14799,12 +14811,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
14799
14811
  const body = rulesyncSubagent.getBody();
14800
14812
  const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
14801
14813
  const paths = this.getSettablePaths({ global });
14814
+ let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
14815
+ if (!relativeFilePath.endsWith(".agent.md")) {
14816
+ relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
14817
+ }
14802
14818
  return new _CopilotSubagent({
14803
14819
  baseDir,
14804
14820
  frontmatter: copilotFrontmatter,
14805
14821
  body,
14806
14822
  relativeDirPath: paths.relativeDirPath,
14807
- relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
14823
+ relativeFilePath,
14808
14824
  fileContent,
14809
14825
  validate,
14810
14826
  global
@@ -19323,7 +19339,8 @@ var rulesProcessorToolTargets = [
19323
19339
  var RulesProcessorToolTargetSchema = z70.enum(rulesProcessorToolTargets);
19324
19340
  var formatRulePaths = (rules) => rules.map((r) => join135(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
19325
19341
  var RulesFeatureOptionsSchema = z70.looseObject({
19326
- ruleDiscoveryMode: z70.optional(z70.enum(["none", "explicit"]))
19342
+ ruleDiscoveryMode: z70.optional(z70.enum(["none", "explicit"])),
19343
+ includeLocalRoot: z70.optional(z70.boolean())
19327
19344
  });
19328
19345
  var resolveRuleDiscoveryMode = ({
19329
19346
  defaultMode,
@@ -19344,6 +19361,19 @@ var resolveRuleDiscoveryMode = ({
19344
19361
  }
19345
19362
  return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
19346
19363
  };
19364
+ var IncludeLocalRootSchema = z70.looseObject({
19365
+ includeLocalRoot: z70.optional(z70.boolean())
19366
+ });
19367
+ var resolveIncludeLocalRoot = (options) => {
19368
+ if (!options) return true;
19369
+ const parsed = IncludeLocalRootSchema.safeParse(options);
19370
+ if (!parsed.success) {
19371
+ throw new Error(
19372
+ `Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
19373
+ );
19374
+ }
19375
+ return parsed.data.includeLocalRoot ?? true;
19376
+ };
19347
19377
  var toolRuleFactories = /* @__PURE__ */ new Map([
19348
19378
  [
19349
19379
  "agentsmd",
@@ -19707,7 +19737,8 @@ var RulesProcessor = class extends FeatureProcessor {
19707
19737
  global: this.global
19708
19738
  });
19709
19739
  }).filter((rule) => rule !== null);
19710
- if (localRootRules.length > 0 && !this.global) {
19740
+ const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
19741
+ if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
19711
19742
  const localRootRule = localRootRules[0];
19712
19743
  if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
19713
19744
  this.handleLocalRootRule(toolRules, localRootRule, factory);
@@ -21123,6 +21154,7 @@ var JsonLogger = class extends BaseLogger {
21123
21154
 
21124
21155
  export {
21125
21156
  RULESYNC_CONFIG_RELATIVE_FILE_PATH,
21157
+ RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH,
21126
21158
  RULESYNC_RELATIVE_DIR_PATH,
21127
21159
  RULESYNC_RULES_RELATIVE_DIR_PATH,
21128
21160
  RULESYNC_COMMANDS_RELATIVE_DIR_PATH,
@@ -13495,12 +13495,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
13495
13495
  const body = rulesyncSubagent.getBody();
13496
13496
  const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
13497
13497
  const paths = this.getSettablePaths({ global });
13498
+ let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
13499
+ if (!relativeFilePath.endsWith(".agent.md")) {
13500
+ relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
13501
+ }
13498
13502
  return new _CopilotSubagent({
13499
13503
  baseDir,
13500
13504
  frontmatter: copilotFrontmatter,
13501
13505
  body,
13502
13506
  relativeDirPath: paths.relativeDirPath,
13503
- relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
13507
+ relativeFilePath,
13504
13508
  fileContent,
13505
13509
  validate,
13506
13510
  global
@@ -18019,7 +18023,8 @@ var rulesProcessorToolTargets = [
18019
18023
  var RulesProcessorToolTargetSchema = import_mini65.z.enum(rulesProcessorToolTargets);
18020
18024
  var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path131.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
18021
18025
  var RulesFeatureOptionsSchema = import_mini65.z.looseObject({
18022
- ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"]))
18026
+ ruleDiscoveryMode: import_mini65.z.optional(import_mini65.z.enum(["none", "explicit"])),
18027
+ includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
18023
18028
  });
18024
18029
  var resolveRuleDiscoveryMode = ({
18025
18030
  defaultMode,
@@ -18040,6 +18045,19 @@ var resolveRuleDiscoveryMode = ({
18040
18045
  }
18041
18046
  return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
18042
18047
  };
18048
+ var IncludeLocalRootSchema = import_mini65.z.looseObject({
18049
+ includeLocalRoot: import_mini65.z.optional(import_mini65.z.boolean())
18050
+ });
18051
+ var resolveIncludeLocalRoot = (options) => {
18052
+ if (!options) return true;
18053
+ const parsed = IncludeLocalRootSchema.safeParse(options);
18054
+ if (!parsed.success) {
18055
+ throw new Error(
18056
+ `Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
18057
+ );
18058
+ }
18059
+ return parsed.data.includeLocalRoot ?? true;
18060
+ };
18043
18061
  var toolRuleFactories = /* @__PURE__ */ new Map([
18044
18062
  [
18045
18063
  "agentsmd",
@@ -18403,7 +18421,8 @@ var RulesProcessor = class extends FeatureProcessor {
18403
18421
  global: this.global
18404
18422
  });
18405
18423
  }).filter((rule) => rule !== null);
18406
- if (localRootRules.length > 0 && !this.global) {
18424
+ const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
18425
+ if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
18407
18426
  const localRootRule = localRootRules[0];
18408
18427
  if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
18409
18428
  this.handleLocalRootRule(toolRules, localRootRule, factory);
@@ -19985,6 +20004,7 @@ var ConfigParamsSchema = import_mini69.z.object({
19985
20004
  simulateCommands: (0, import_mini69.optional)(import_mini69.z.boolean()),
19986
20005
  simulateSubagents: (0, import_mini69.optional)(import_mini69.z.boolean()),
19987
20006
  simulateSkills: (0, import_mini69.optional)(import_mini69.z.boolean()),
20007
+ gitignoreTargetsOnly: (0, import_mini69.optional)(import_mini69.z.boolean()),
19988
20008
  dryRun: (0, import_mini69.optional)(import_mini69.z.boolean()),
19989
20009
  check: (0, import_mini69.optional)(import_mini69.z.boolean()),
19990
20010
  // Declarative skill sources
@@ -20012,6 +20032,7 @@ var Config = class _Config {
20012
20032
  simulateCommands;
20013
20033
  simulateSubagents;
20014
20034
  simulateSkills;
20035
+ gitignoreTargetsOnly;
20015
20036
  dryRun;
20016
20037
  check;
20017
20038
  sources;
@@ -20026,6 +20047,7 @@ var Config = class _Config {
20026
20047
  simulateCommands,
20027
20048
  simulateSubagents,
20028
20049
  simulateSkills,
20050
+ gitignoreTargetsOnly,
20029
20051
  dryRun,
20030
20052
  check,
20031
20053
  sources
@@ -20044,6 +20066,7 @@ var Config = class _Config {
20044
20066
  this.simulateCommands = simulateCommands ?? false;
20045
20067
  this.simulateSubagents = simulateSubagents ?? false;
20046
20068
  this.simulateSkills = simulateSkills ?? false;
20069
+ this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
20047
20070
  this.dryRun = dryRun ?? false;
20048
20071
  this.check = check ?? false;
20049
20072
  this.sources = sources ?? [];
@@ -20169,6 +20192,9 @@ var Config = class _Config {
20169
20192
  getSimulateSkills() {
20170
20193
  return this.simulateSkills;
20171
20194
  }
20195
+ getGitignoreTargetsOnly() {
20196
+ return this.gitignoreTargetsOnly;
20197
+ }
20172
20198
  getDryRun() {
20173
20199
  return this.dryRun;
20174
20200
  }
@@ -20200,6 +20226,7 @@ var getDefaults = () => ({
20200
20226
  simulateCommands: false,
20201
20227
  simulateSubagents: false,
20202
20228
  simulateSkills: false,
20229
+ gitignoreTargetsOnly: true,
20203
20230
  dryRun: false,
20204
20231
  check: false,
20205
20232
  sources: []
@@ -20226,6 +20253,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
20226
20253
  simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
20227
20254
  simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
20228
20255
  simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
20256
+ gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
20229
20257
  dryRun: localConfig.dryRun ?? baseConfig.dryRun,
20230
20258
  check: localConfig.check ?? baseConfig.check,
20231
20259
  sources: localConfig.sources ?? baseConfig.sources
@@ -20244,6 +20272,7 @@ var ConfigResolver = class {
20244
20272
  simulateCommands,
20245
20273
  simulateSubagents,
20246
20274
  simulateSkills,
20275
+ gitignoreTargetsOnly,
20247
20276
  dryRun,
20248
20277
  check
20249
20278
  }) {
@@ -20257,6 +20286,7 @@ var ConfigResolver = class {
20257
20286
  const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
20258
20287
  const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
20259
20288
  const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
20289
+ const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
20260
20290
  const configParams = {
20261
20291
  targets: targets ?? configByFile.targets ?? getDefaults().targets,
20262
20292
  features: features ?? configByFile.features ?? getDefaults().features,
@@ -20271,6 +20301,7 @@ var ConfigResolver = class {
20271
20301
  simulateCommands: resolvedSimulateCommands,
20272
20302
  simulateSubagents: resolvedSimulateSubagents,
20273
20303
  simulateSkills: resolvedSimulateSkills,
20304
+ gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
20274
20305
  dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
20275
20306
  check: check ?? configByFile.check ?? getDefaults().check,
20276
20307
  sources: configByFile.sources ?? getDefaults().sources
@@ -21860,6 +21891,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
21860
21891
  feature: "general",
21861
21892
  entry: "**/.claude/settings.local.json"
21862
21893
  },
21894
+ { target: "claudecode", feature: "general", entry: "**/.claude/*.lock" },
21863
21895
  // Cline
21864
21896
  { target: "cline", feature: "rules", entry: "**/.clinerules/" },
21865
21897
  { target: "cline", feature: "commands", entry: "**/.clinerules/workflows/" },
@@ -21968,6 +22000,11 @@ var GITIGNORE_ENTRY_REGISTRY = [
21968
22000
  { target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
21969
22001
  { target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
21970
22002
  { target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
22003
+ {
22004
+ target: "opencode",
22005
+ feature: "general",
22006
+ entry: "**/.opencode/package-lock.json"
22007
+ },
21971
22008
  // Qwen Code
21972
22009
  { target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
21973
22010
  { target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
@@ -22541,7 +22578,8 @@ async function createConfigFile() {
22541
22578
  global: false,
22542
22579
  simulateCommands: false,
22543
22580
  simulateSubagents: false,
22544
- simulateSkills: false
22581
+ simulateSkills: false,
22582
+ gitignoreTargetsOnly: true
22545
22583
  },
22546
22584
  null,
22547
22585
  2
@@ -25152,6 +25190,31 @@ async function mcpCommand(logger5, { version }) {
25152
25190
  });
25153
25191
  }
25154
25192
 
25193
+ // src/cli/commands/resolve-gitignore-targets.ts
25194
+ var import_node_path152 = require("path");
25195
+ var resolveGitignoreTargets = async ({
25196
+ cliTargets,
25197
+ cwd = process.cwd()
25198
+ }) => {
25199
+ if (cliTargets !== void 0) {
25200
+ return cliTargets;
25201
+ }
25202
+ const baseConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
25203
+ const localConfigPath = (0, import_node_path152.join)(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
25204
+ const [hasBase, hasLocal] = await Promise.all([
25205
+ fileExists(baseConfigPath),
25206
+ fileExists(localConfigPath)
25207
+ ]);
25208
+ if (!hasBase && !hasLocal) {
25209
+ return void 0;
25210
+ }
25211
+ const config = await ConfigResolver.resolve({});
25212
+ if (config.getGitignoreTargetsOnly()) {
25213
+ return config.getTargets();
25214
+ }
25215
+ return void 0;
25216
+ };
25217
+
25155
25218
  // src/lib/update.ts
25156
25219
  var crypto = __toESM(require("crypto"), 1);
25157
25220
  var fs = __toESM(require("fs"), 1);
@@ -25554,7 +25617,7 @@ function wrapCommand({
25554
25617
  }
25555
25618
 
25556
25619
  // src/cli/index.ts
25557
- var getVersion = () => "8.0.0";
25620
+ var getVersion = () => "8.1.0";
25558
25621
  function wrapCommand2(name, errorCode, handler) {
25559
25622
  return wrapCommand({ name, errorCode, handler, getVersion });
25560
25623
  }
@@ -25577,11 +25640,12 @@ var main = async () => {
25577
25640
  parseCommaSeparatedList
25578
25641
  ).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
25579
25642
  wrapCommand2("gitignore", "GITIGNORE_FAILED", async (logger5, options) => {
25643
+ const cliTargets = options.targets;
25644
+ const cliFeatures = options.features;
25645
+ const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
25580
25646
  await gitignoreCommand(logger5, {
25581
- // eslint-disable-next-line no-type-assertion/no-type-assertion
25582
- targets: options.targets,
25583
- // eslint-disable-next-line no-type-assertion/no-type-assertion
25584
- features: options.features
25647
+ targets: resolvedTargets ? [...resolvedTargets] : void 0,
25648
+ features: cliFeatures
25585
25649
  });
25586
25650
  })
25587
25651
  );
package/dist/cli/index.js CHANGED
@@ -24,6 +24,7 @@ import {
24
24
  RULESYNC_HOOKS_FILE_NAME,
25
25
  RULESYNC_HOOKS_RELATIVE_FILE_PATH,
26
26
  RULESYNC_IGNORE_RELATIVE_FILE_PATH,
27
+ RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH,
27
28
  RULESYNC_MCP_FILE_NAME,
28
29
  RULESYNC_MCP_RELATIVE_FILE_PATH,
29
30
  RULESYNC_MCP_SCHEMA_URL,
@@ -72,7 +73,7 @@ import {
72
73
  stringifyFrontmatter,
73
74
  toPosixPath,
74
75
  writeFileContent
75
- } from "../chunk-GB6XLCGB.js";
76
+ } from "../chunk-FLZZ3LEK.js";
76
77
 
77
78
  // src/cli/index.ts
78
79
  import { Command } from "commander";
@@ -1196,6 +1197,7 @@ var GITIGNORE_ENTRY_REGISTRY = [
1196
1197
  feature: "general",
1197
1198
  entry: "**/.claude/settings.local.json"
1198
1199
  },
1200
+ { target: "claudecode", feature: "general", entry: "**/.claude/*.lock" },
1199
1201
  // Cline
1200
1202
  { target: "cline", feature: "rules", entry: "**/.clinerules/" },
1201
1203
  { target: "cline", feature: "commands", entry: "**/.clinerules/workflows/" },
@@ -1304,6 +1306,11 @@ var GITIGNORE_ENTRY_REGISTRY = [
1304
1306
  { target: "opencode", feature: "skills", entry: "**/.opencode/skill/" },
1305
1307
  { target: "opencode", feature: "mcp", entry: "**/.opencode/plugins/" },
1306
1308
  { target: "opencode", feature: "general", entry: "**/.opencode/memories/" },
1309
+ {
1310
+ target: "opencode",
1311
+ feature: "general",
1312
+ entry: "**/.opencode/package-lock.json"
1313
+ },
1307
1314
  // Qwen Code
1308
1315
  { target: "qwencode", feature: "rules", entry: "**/QWEN.md" },
1309
1316
  { target: "qwencode", feature: "general", entry: "**/.qwen/memories/" },
@@ -1613,7 +1620,8 @@ async function createConfigFile() {
1613
1620
  global: false,
1614
1621
  simulateCommands: false,
1615
1622
  simulateSubagents: false,
1616
- simulateSkills: false
1623
+ simulateSkills: false,
1624
+ gitignoreTargetsOnly: true
1617
1625
  },
1618
1626
  null,
1619
1627
  2
@@ -4078,6 +4086,31 @@ async function mcpCommand(logger5, { version }) {
4078
4086
  });
4079
4087
  }
4080
4088
 
4089
+ // src/cli/commands/resolve-gitignore-targets.ts
4090
+ import { join as join13 } from "path";
4091
+ var resolveGitignoreTargets = async ({
4092
+ cliTargets,
4093
+ cwd = process.cwd()
4094
+ }) => {
4095
+ if (cliTargets !== void 0) {
4096
+ return cliTargets;
4097
+ }
4098
+ const baseConfigPath = join13(cwd, RULESYNC_CONFIG_RELATIVE_FILE_PATH);
4099
+ const localConfigPath = join13(cwd, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH);
4100
+ const [hasBase, hasLocal] = await Promise.all([
4101
+ fileExists(baseConfigPath),
4102
+ fileExists(localConfigPath)
4103
+ ]);
4104
+ if (!hasBase && !hasLocal) {
4105
+ return void 0;
4106
+ }
4107
+ const config = await ConfigResolver.resolve({});
4108
+ if (config.getGitignoreTargetsOnly()) {
4109
+ return config.getTargets();
4110
+ }
4111
+ return void 0;
4112
+ };
4113
+
4081
4114
  // src/lib/update.ts
4082
4115
  import * as crypto from "crypto";
4083
4116
  import * as fs from "fs";
@@ -4480,7 +4513,7 @@ function wrapCommand({
4480
4513
  }
4481
4514
 
4482
4515
  // src/cli/index.ts
4483
- var getVersion = () => "8.0.0";
4516
+ var getVersion = () => "8.1.0";
4484
4517
  function wrapCommand2(name, errorCode, handler) {
4485
4518
  return wrapCommand({ name, errorCode, handler, getVersion });
4486
4519
  }
@@ -4503,11 +4536,12 @@ var main = async () => {
4503
4536
  parseCommaSeparatedList
4504
4537
  ).option("-V, --verbose", "Verbose output").option("-s, --silent", "Suppress all output").action(
4505
4538
  wrapCommand2("gitignore", "GITIGNORE_FAILED", async (logger5, options) => {
4539
+ const cliTargets = options.targets;
4540
+ const cliFeatures = options.features;
4541
+ const resolvedTargets = await resolveGitignoreTargets({ cliTargets });
4506
4542
  await gitignoreCommand(logger5, {
4507
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4508
- targets: options.targets,
4509
- // eslint-disable-next-line no-type-assertion/no-type-assertion
4510
- features: options.features
4543
+ targets: resolvedTargets ? [...resolvedTargets] : void 0,
4544
+ features: cliFeatures
4511
4545
  });
4512
4546
  })
4513
4547
  );
package/dist/index.cjs CHANGED
@@ -356,6 +356,7 @@ var ConfigParamsSchema = import_mini3.z.object({
356
356
  simulateCommands: (0, import_mini3.optional)(import_mini3.z.boolean()),
357
357
  simulateSubagents: (0, import_mini3.optional)(import_mini3.z.boolean()),
358
358
  simulateSkills: (0, import_mini3.optional)(import_mini3.z.boolean()),
359
+ gitignoreTargetsOnly: (0, import_mini3.optional)(import_mini3.z.boolean()),
359
360
  dryRun: (0, import_mini3.optional)(import_mini3.z.boolean()),
360
361
  check: (0, import_mini3.optional)(import_mini3.z.boolean()),
361
362
  // Declarative skill sources
@@ -383,6 +384,7 @@ var Config = class _Config {
383
384
  simulateCommands;
384
385
  simulateSubagents;
385
386
  simulateSkills;
387
+ gitignoreTargetsOnly;
386
388
  dryRun;
387
389
  check;
388
390
  sources;
@@ -397,6 +399,7 @@ var Config = class _Config {
397
399
  simulateCommands,
398
400
  simulateSubagents,
399
401
  simulateSkills,
402
+ gitignoreTargetsOnly,
400
403
  dryRun,
401
404
  check,
402
405
  sources
@@ -415,6 +418,7 @@ var Config = class _Config {
415
418
  this.simulateCommands = simulateCommands ?? false;
416
419
  this.simulateSubagents = simulateSubagents ?? false;
417
420
  this.simulateSkills = simulateSkills ?? false;
421
+ this.gitignoreTargetsOnly = gitignoreTargetsOnly ?? true;
418
422
  this.dryRun = dryRun ?? false;
419
423
  this.check = check ?? false;
420
424
  this.sources = sources ?? [];
@@ -540,6 +544,9 @@ var Config = class _Config {
540
544
  getSimulateSkills() {
541
545
  return this.simulateSkills;
542
546
  }
547
+ getGitignoreTargetsOnly() {
548
+ return this.gitignoreTargetsOnly;
549
+ }
543
550
  getDryRun() {
544
551
  return this.dryRun;
545
552
  }
@@ -571,6 +578,7 @@ var getDefaults = () => ({
571
578
  simulateCommands: false,
572
579
  simulateSubagents: false,
573
580
  simulateSkills: false,
581
+ gitignoreTargetsOnly: true,
574
582
  dryRun: false,
575
583
  check: false,
576
584
  sources: []
@@ -597,6 +605,7 @@ var mergeConfigs = (baseConfig, localConfig) => {
597
605
  simulateCommands: localConfig.simulateCommands ?? baseConfig.simulateCommands,
598
606
  simulateSubagents: localConfig.simulateSubagents ?? baseConfig.simulateSubagents,
599
607
  simulateSkills: localConfig.simulateSkills ?? baseConfig.simulateSkills,
608
+ gitignoreTargetsOnly: localConfig.gitignoreTargetsOnly ?? baseConfig.gitignoreTargetsOnly,
600
609
  dryRun: localConfig.dryRun ?? baseConfig.dryRun,
601
610
  check: localConfig.check ?? baseConfig.check,
602
611
  sources: localConfig.sources ?? baseConfig.sources
@@ -615,6 +624,7 @@ var ConfigResolver = class {
615
624
  simulateCommands,
616
625
  simulateSubagents,
617
626
  simulateSkills,
627
+ gitignoreTargetsOnly,
618
628
  dryRun,
619
629
  check
620
630
  }) {
@@ -628,6 +638,7 @@ var ConfigResolver = class {
628
638
  const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? getDefaults().simulateCommands;
629
639
  const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? getDefaults().simulateSubagents;
630
640
  const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
641
+ const resolvedGitignoreTargetsOnly = gitignoreTargetsOnly ?? configByFile.gitignoreTargetsOnly ?? getDefaults().gitignoreTargetsOnly;
631
642
  const configParams = {
632
643
  targets: targets ?? configByFile.targets ?? getDefaults().targets,
633
644
  features: features ?? configByFile.features ?? getDefaults().features,
@@ -642,6 +653,7 @@ var ConfigResolver = class {
642
653
  simulateCommands: resolvedSimulateCommands,
643
654
  simulateSubagents: resolvedSimulateSubagents,
644
655
  simulateSkills: resolvedSimulateSkills,
656
+ gitignoreTargetsOnly: resolvedGitignoreTargetsOnly,
645
657
  dryRun: dryRun ?? configByFile.dryRun ?? getDefaults().dryRun,
646
658
  check: check ?? configByFile.check ?? getDefaults().check,
647
659
  sources: configByFile.sources ?? getDefaults().sources
@@ -14807,12 +14819,16 @@ var CopilotSubagent = class _CopilotSubagent extends ToolSubagent {
14807
14819
  const body = rulesyncSubagent.getBody();
14808
14820
  const fileContent = stringifyFrontmatter(body, copilotFrontmatter);
14809
14821
  const paths = this.getSettablePaths({ global });
14822
+ let relativeFilePath = rulesyncSubagent.getRelativeFilePath();
14823
+ if (!relativeFilePath.endsWith(".agent.md")) {
14824
+ relativeFilePath = relativeFilePath.replace(/\.md$/, ".agent.md");
14825
+ }
14810
14826
  return new _CopilotSubagent({
14811
14827
  baseDir,
14812
14828
  frontmatter: copilotFrontmatter,
14813
14829
  body,
14814
14830
  relativeDirPath: paths.relativeDirPath,
14815
- relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
14831
+ relativeFilePath,
14816
14832
  fileContent,
14817
14833
  validate,
14818
14834
  global
@@ -19331,7 +19347,8 @@ var rulesProcessorToolTargets = [
19331
19347
  var RulesProcessorToolTargetSchema = import_mini70.z.enum(rulesProcessorToolTargets);
19332
19348
  var formatRulePaths = (rules) => rules.map((r) => (0, import_node_path138.join)(r.getRelativeDirPath(), r.getRelativeFilePath())).join(", ");
19333
19349
  var RulesFeatureOptionsSchema = import_mini70.z.looseObject({
19334
- ruleDiscoveryMode: import_mini70.z.optional(import_mini70.z.enum(["none", "explicit"]))
19350
+ ruleDiscoveryMode: import_mini70.z.optional(import_mini70.z.enum(["none", "explicit"])),
19351
+ includeLocalRoot: import_mini70.z.optional(import_mini70.z.boolean())
19335
19352
  });
19336
19353
  var resolveRuleDiscoveryMode = ({
19337
19354
  defaultMode,
@@ -19352,6 +19369,19 @@ var resolveRuleDiscoveryMode = ({
19352
19369
  }
19353
19370
  return parsed.data.ruleDiscoveryMode === "none" ? "auto" : "toon";
19354
19371
  };
19372
+ var IncludeLocalRootSchema = import_mini70.z.looseObject({
19373
+ includeLocalRoot: import_mini70.z.optional(import_mini70.z.boolean())
19374
+ });
19375
+ var resolveIncludeLocalRoot = (options) => {
19376
+ if (!options) return true;
19377
+ const parsed = IncludeLocalRootSchema.safeParse(options);
19378
+ if (!parsed.success) {
19379
+ throw new Error(
19380
+ `Invalid options for rules feature: ${parsed.error.message}. \`includeLocalRoot\` must be a boolean.`
19381
+ );
19382
+ }
19383
+ return parsed.data.includeLocalRoot ?? true;
19384
+ };
19355
19385
  var toolRuleFactories = /* @__PURE__ */ new Map([
19356
19386
  [
19357
19387
  "agentsmd",
@@ -19715,7 +19745,8 @@ var RulesProcessor = class extends FeatureProcessor {
19715
19745
  global: this.global
19716
19746
  });
19717
19747
  }).filter((rule) => rule !== null);
19718
- if (localRootRules.length > 0 && !this.global) {
19748
+ const includeLocalRoot = resolveIncludeLocalRoot(this.featureOptions);
19749
+ if (localRootRules.length > 0 && !this.global && includeLocalRoot) {
19719
19750
  const localRootRule = localRootRules[0];
19720
19751
  if (localRootRule && factory.class.isTargetedByRulesyncRule(localRootRule)) {
19721
19752
  this.handleLocalRootRule(toolRules, localRootRule, factory);
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  checkRulesyncDirExists,
7
7
  generate,
8
8
  importFromTool
9
- } from "./chunk-GB6XLCGB.js";
9
+ } from "./chunk-FLZZ3LEK.js";
10
10
 
11
11
  // src/index.ts
12
12
  async function generate2(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rulesync",
3
- "version": "8.0.0",
3
+ "version": "8.1.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",
@@ -93,9 +93,9 @@
93
93
  "simple-git-hooks": "2.13.1",
94
94
  "sort-package-json": "3.6.1",
95
95
  "tsup": "8.5.1",
96
- "tsx": "4.21.0",
97
96
  "typescript": "5.9.3",
98
97
  "typescript-eslint": "8.57.1",
98
+ "vite": "7.3.1",
99
99
  "vitepress": "1.6.4",
100
100
  "vitest": "4.1.0"
101
101
  },
@@ -113,7 +113,7 @@
113
113
  "cicheck:code": "pnpm run check && pnpm run test",
114
114
  "cicheck:content": "pnpm run cspell && pnpm run secretlint",
115
115
  "cspell": "cspell --no-progress --gitignore .",
116
- "dev": "tsx src/cli/index.ts",
116
+ "dev": "node --experimental-transform-types --experimental-loader ./scripts/strip-types-loader.mjs src/cli/index.ts",
117
117
  "docs:build": "vitepress build docs",
118
118
  "docs:dev": "vitepress dev docs",
119
119
  "docs:preview": "vitepress preview docs",
@@ -123,13 +123,13 @@
123
123
  "fmt": "oxfmt .",
124
124
  "fmt:check": "oxfmt --check .",
125
125
  "generate": "pnpm run dev generate",
126
- "generate:schema": "tsx scripts/generate-json-schema.ts",
126
+ "generate:schema": "node --experimental-transform-types --experimental-loader ./scripts/strip-types-loader.mjs scripts/generate-json-schema.ts",
127
127
  "knip": "knip",
128
128
  "oxlint": "oxlint . --max-warnings 0",
129
129
  "oxlint:fix": "oxlint . --fix --max-warnings 0",
130
130
  "secretlint": "secretlint --secretlintignore .gitignore \"**/*\"",
131
131
  "sort": "sort-package-json",
132
- "task": "tsx scripts/run-tasks.ts",
132
+ "task": "node --experimental-transform-types --experimental-loader ./scripts/strip-types-loader.mjs scripts/run-tasks.ts",
133
133
  "test": "vitest run --silent=true",
134
134
  "test:coverage": "vitest run --coverage --silent=true",
135
135
  "test:e2e": "vitest run --config vitest.e2e.config.ts --silent=false",