rulesync 7.25.0 → 7.26.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
@@ -71,7 +71,7 @@ See [Quick Start guide](https://dyoshikawa.github.io/rulesync/getting-started/qu
71
71
  | Gemini CLI | geminicli | ✅ 🌏 | ✅ | ✅ 🌏 | ✅ 🌏 | 🎮 | ✅ 🌏 | ✅ 🌏 |
72
72
  | Goose | goose | ✅ 🌏 | ✅ | | | | | |
73
73
  | GitHub Copilot | copilot | ✅ 🌏 | | ✅ | ✅ | ✅ | ✅ | ✅ |
74
- | GitHub Copilot CLI | copilotcli | | | ✅ 🌏 | | | | |
74
+ | GitHub Copilot CLI | copilotcli | ✅ 🌏 | | ✅ 🌏 | | | | |
75
75
  | Cursor | cursor | ✅ | ✅ | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ 🌏 | ✅ |
76
76
  | deepagents-cli | deepagents | ✅ | | ✅ 🌏 | | ✅ | ✅ | 🌏 |
77
77
  | Factory Droid | factorydroid | ✅ 🌏 | | ✅ 🌏 | 🎮 | 🎮 | 🎮 | ✅ 🌏 |
@@ -6128,7 +6128,7 @@ import { z as z21 } from "zod/mini";
6128
6128
  // src/types/mcp.ts
6129
6129
  import { z as z20 } from "zod/mini";
6130
6130
  var McpServerSchema = z20.looseObject({
6131
- type: z20.optional(z20.enum(["stdio", "sse", "http"])),
6131
+ type: z20.optional(z20.enum(["local", "stdio", "sse", "http"])),
6132
6132
  command: z20.optional(z20.union([z20.string(), z20.array(z20.string())])),
6133
6133
  args: z20.optional(z20.array(z20.string())),
6134
6134
  url: z20.optional(z20.string()),
@@ -6139,7 +6139,7 @@ var McpServerSchema = z20.looseObject({
6139
6139
  timeout: z20.optional(z20.number()),
6140
6140
  trust: z20.optional(z20.boolean()),
6141
6141
  cwd: z20.optional(z20.string()),
6142
- transport: z20.optional(z20.enum(["stdio", "sse", "http"])),
6142
+ transport: z20.optional(z20.enum(["local", "stdio", "sse", "http"])),
6143
6143
  alwaysAllow: z20.optional(z20.array(z20.string())),
6144
6144
  tools: z20.optional(z20.array(z20.string())),
6145
6145
  kiroAutoApprove: z20.optional(z20.array(z20.string())),
@@ -6724,13 +6724,38 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
6724
6724
 
6725
6725
  // src/features/mcp/copilotcli-mcp.ts
6726
6726
  import { join as join48 } from "path";
6727
+ var isRemoteServerType = (type) => {
6728
+ return type === "http" || type === "sse";
6729
+ };
6730
+ var resolveCopilotcliServerType = (server) => {
6731
+ if (server.type) {
6732
+ return server.type;
6733
+ }
6734
+ if (server.transport === "http" || server.transport === "sse" || server.transport === "local") {
6735
+ return server.transport;
6736
+ }
6737
+ return "stdio";
6738
+ };
6727
6739
  function addTypeField(mcpServers) {
6728
6740
  const result = {};
6729
6741
  for (const [name, server] of Object.entries(mcpServers)) {
6730
6742
  const parsed = McpServerSchema.parse(server);
6743
+ const type = resolveCopilotcliServerType(parsed);
6744
+ if (isRemoteServerType(type)) {
6745
+ if (!parsed.url && !parsed.httpUrl) {
6746
+ throw new Error(
6747
+ `MCP server "${name}" is missing a url or httpUrl. GitHub Copilot CLI ${type} servers require a non-empty url or httpUrl.`
6748
+ );
6749
+ }
6750
+ result[name] = {
6751
+ ...parsed,
6752
+ type
6753
+ };
6754
+ continue;
6755
+ }
6731
6756
  if (!parsed.command) {
6732
6757
  throw new Error(
6733
- `MCP server "${name}" is missing a command. GitHub Copilot CLI stdio servers require a non-empty command.`
6758
+ `MCP server "${name}" is missing a command. GitHub Copilot CLI ${type} servers require a non-empty command.`
6734
6759
  );
6735
6760
  }
6736
6761
  let command;
@@ -6746,11 +6771,9 @@ function addTypeField(mcpServers) {
6746
6771
  command = cmd;
6747
6772
  args = cmdArgs.length > 0 ? [...cmdArgs, ...parsed.args ?? []] : parsed.args;
6748
6773
  }
6749
- const serverRecord = server;
6750
6774
  result[name] = {
6751
- ...serverRecord,
6752
6775
  ...parsed,
6753
- type: parsed.type ?? "stdio",
6776
+ type,
6754
6777
  command,
6755
6778
  ...args && { args }
6756
6779
  };
@@ -6760,6 +6783,10 @@ function addTypeField(mcpServers) {
6760
6783
  function removeTypeField(config) {
6761
6784
  const result = {};
6762
6785
  for (const [name, server] of Object.entries(config.mcpServers ?? {})) {
6786
+ if (server.type !== "stdio") {
6787
+ result[name] = server;
6788
+ continue;
6789
+ }
6763
6790
  const { type: _, ...rest } = server;
6764
6791
  result[name] = rest;
6765
6792
  }
@@ -6782,13 +6809,7 @@ var CopilotcliMcp = class _CopilotcliMcp extends ToolMcp {
6782
6809
  isDeletable() {
6783
6810
  return !this.global;
6784
6811
  }
6785
- static getSettablePaths({ global } = {}) {
6786
- if (global) {
6787
- return {
6788
- relativeDirPath: ".copilot",
6789
- relativeFilePath: "mcp-config.json"
6790
- };
6791
- }
6812
+ static getSettablePaths(_options = {}) {
6792
6813
  return {
6793
6814
  relativeDirPath: ".copilot",
6794
6815
  relativeFilePath: "mcp-config.json"
@@ -15766,6 +15787,42 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15766
15787
  }
15767
15788
  };
15768
15789
 
15790
+ // src/features/rules/copilotcli-rule.ts
15791
+ var CopilotcliRule = class _CopilotcliRule extends CopilotRule {
15792
+ static fromCopilotRule(copilotRule, validate = true) {
15793
+ return new _CopilotcliRule({
15794
+ baseDir: copilotRule.getBaseDir(),
15795
+ relativeDirPath: copilotRule.getRelativeDirPath(),
15796
+ relativeFilePath: copilotRule.getRelativeFilePath(),
15797
+ frontmatter: copilotRule.getFrontmatter(),
15798
+ body: copilotRule.getBody(),
15799
+ validate,
15800
+ root: copilotRule.isRoot()
15801
+ });
15802
+ }
15803
+ static fromRulesyncRule({
15804
+ validate = true,
15805
+ ...rest
15806
+ }) {
15807
+ return this.fromCopilotRule(CopilotRule.fromRulesyncRule({ validate, ...rest }), validate);
15808
+ }
15809
+ static async fromFile({
15810
+ validate = true,
15811
+ ...rest
15812
+ }) {
15813
+ return this.fromCopilotRule(await CopilotRule.fromFile({ validate, ...rest }), validate);
15814
+ }
15815
+ static forDeletion(params) {
15816
+ return this.fromCopilotRule(CopilotRule.forDeletion(params), false);
15817
+ }
15818
+ static isTargetedByRulesyncRule(rulesyncRule) {
15819
+ return this.isTargetedByRulesyncRuleDefault({
15820
+ rulesyncRule,
15821
+ toolTarget: "copilotcli"
15822
+ });
15823
+ }
15824
+ };
15825
+
15769
15826
  // src/features/rules/cursor-rule.ts
15770
15827
  import { join as join111 } from "path";
15771
15828
  import { z as z60 } from "zod/mini";
@@ -17343,6 +17400,7 @@ var rulesProcessorToolTargets = [
17343
17400
  "cline",
17344
17401
  "codexcli",
17345
17402
  "copilot",
17403
+ "copilotcli",
17346
17404
  "cursor",
17347
17405
  "deepagents",
17348
17406
  "factorydroid",
@@ -17466,6 +17524,17 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
17466
17524
  }
17467
17525
  }
17468
17526
  ],
17527
+ [
17528
+ "copilotcli",
17529
+ {
17530
+ class: CopilotcliRule,
17531
+ meta: {
17532
+ extension: "md",
17533
+ supportsGlobal: true,
17534
+ ruleDiscoveryMode: "auto"
17535
+ }
17536
+ }
17537
+ ],
17469
17538
  [
17470
17539
  "cursor",
17471
17540
  {
@@ -5837,7 +5837,7 @@ var import_mini20 = require("zod/mini");
5837
5837
  // src/types/mcp.ts
5838
5838
  var import_mini19 = require("zod/mini");
5839
5839
  var McpServerSchema = import_mini19.z.looseObject({
5840
- type: import_mini19.z.optional(import_mini19.z.enum(["stdio", "sse", "http"])),
5840
+ type: import_mini19.z.optional(import_mini19.z.enum(["local", "stdio", "sse", "http"])),
5841
5841
  command: import_mini19.z.optional(import_mini19.z.union([import_mini19.z.string(), import_mini19.z.array(import_mini19.z.string())])),
5842
5842
  args: import_mini19.z.optional(import_mini19.z.array(import_mini19.z.string())),
5843
5843
  url: import_mini19.z.optional(import_mini19.z.string()),
@@ -5848,7 +5848,7 @@ var McpServerSchema = import_mini19.z.looseObject({
5848
5848
  timeout: import_mini19.z.optional(import_mini19.z.number()),
5849
5849
  trust: import_mini19.z.optional(import_mini19.z.boolean()),
5850
5850
  cwd: import_mini19.z.optional(import_mini19.z.string()),
5851
- transport: import_mini19.z.optional(import_mini19.z.enum(["stdio", "sse", "http"])),
5851
+ transport: import_mini19.z.optional(import_mini19.z.enum(["local", "stdio", "sse", "http"])),
5852
5852
  alwaysAllow: import_mini19.z.optional(import_mini19.z.array(import_mini19.z.string())),
5853
5853
  tools: import_mini19.z.optional(import_mini19.z.array(import_mini19.z.string())),
5854
5854
  kiroAutoApprove: import_mini19.z.optional(import_mini19.z.array(import_mini19.z.string())),
@@ -6433,13 +6433,38 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
6433
6433
 
6434
6434
  // src/features/mcp/copilotcli-mcp.ts
6435
6435
  var import_node_path49 = require("path");
6436
+ var isRemoteServerType = (type) => {
6437
+ return type === "http" || type === "sse";
6438
+ };
6439
+ var resolveCopilotcliServerType = (server) => {
6440
+ if (server.type) {
6441
+ return server.type;
6442
+ }
6443
+ if (server.transport === "http" || server.transport === "sse" || server.transport === "local") {
6444
+ return server.transport;
6445
+ }
6446
+ return "stdio";
6447
+ };
6436
6448
  function addTypeField(mcpServers) {
6437
6449
  const result = {};
6438
6450
  for (const [name, server] of Object.entries(mcpServers)) {
6439
6451
  const parsed = McpServerSchema.parse(server);
6452
+ const type = resolveCopilotcliServerType(parsed);
6453
+ if (isRemoteServerType(type)) {
6454
+ if (!parsed.url && !parsed.httpUrl) {
6455
+ throw new Error(
6456
+ `MCP server "${name}" is missing a url or httpUrl. GitHub Copilot CLI ${type} servers require a non-empty url or httpUrl.`
6457
+ );
6458
+ }
6459
+ result[name] = {
6460
+ ...parsed,
6461
+ type
6462
+ };
6463
+ continue;
6464
+ }
6440
6465
  if (!parsed.command) {
6441
6466
  throw new Error(
6442
- `MCP server "${name}" is missing a command. GitHub Copilot CLI stdio servers require a non-empty command.`
6467
+ `MCP server "${name}" is missing a command. GitHub Copilot CLI ${type} servers require a non-empty command.`
6443
6468
  );
6444
6469
  }
6445
6470
  let command;
@@ -6455,11 +6480,9 @@ function addTypeField(mcpServers) {
6455
6480
  command = cmd;
6456
6481
  args = cmdArgs.length > 0 ? [...cmdArgs, ...parsed.args ?? []] : parsed.args;
6457
6482
  }
6458
- const serverRecord = server;
6459
6483
  result[name] = {
6460
- ...serverRecord,
6461
6484
  ...parsed,
6462
- type: parsed.type ?? "stdio",
6485
+ type,
6463
6486
  command,
6464
6487
  ...args && { args }
6465
6488
  };
@@ -6469,6 +6492,10 @@ function addTypeField(mcpServers) {
6469
6492
  function removeTypeField(config) {
6470
6493
  const result = {};
6471
6494
  for (const [name, server] of Object.entries(config.mcpServers ?? {})) {
6495
+ if (server.type !== "stdio") {
6496
+ result[name] = server;
6497
+ continue;
6498
+ }
6472
6499
  const { type: _, ...rest } = server;
6473
6500
  result[name] = rest;
6474
6501
  }
@@ -6491,13 +6518,7 @@ var CopilotcliMcp = class _CopilotcliMcp extends ToolMcp {
6491
6518
  isDeletable() {
6492
6519
  return !this.global;
6493
6520
  }
6494
- static getSettablePaths({ global } = {}) {
6495
- if (global) {
6496
- return {
6497
- relativeDirPath: ".copilot",
6498
- relativeFilePath: "mcp-config.json"
6499
- };
6500
- }
6521
+ static getSettablePaths(_options = {}) {
6501
6522
  return {
6502
6523
  relativeDirPath: ".copilot",
6503
6524
  relativeFilePath: "mcp-config.json"
@@ -15475,6 +15496,42 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15475
15496
  }
15476
15497
  };
15477
15498
 
15499
+ // src/features/rules/copilotcli-rule.ts
15500
+ var CopilotcliRule = class _CopilotcliRule extends CopilotRule {
15501
+ static fromCopilotRule(copilotRule, validate = true) {
15502
+ return new _CopilotcliRule({
15503
+ baseDir: copilotRule.getBaseDir(),
15504
+ relativeDirPath: copilotRule.getRelativeDirPath(),
15505
+ relativeFilePath: copilotRule.getRelativeFilePath(),
15506
+ frontmatter: copilotRule.getFrontmatter(),
15507
+ body: copilotRule.getBody(),
15508
+ validate,
15509
+ root: copilotRule.isRoot()
15510
+ });
15511
+ }
15512
+ static fromRulesyncRule({
15513
+ validate = true,
15514
+ ...rest
15515
+ }) {
15516
+ return this.fromCopilotRule(CopilotRule.fromRulesyncRule({ validate, ...rest }), validate);
15517
+ }
15518
+ static async fromFile({
15519
+ validate = true,
15520
+ ...rest
15521
+ }) {
15522
+ return this.fromCopilotRule(await CopilotRule.fromFile({ validate, ...rest }), validate);
15523
+ }
15524
+ static forDeletion(params) {
15525
+ return this.fromCopilotRule(CopilotRule.forDeletion(params), false);
15526
+ }
15527
+ static isTargetedByRulesyncRule(rulesyncRule) {
15528
+ return this.isTargetedByRulesyncRuleDefault({
15529
+ rulesyncRule,
15530
+ toolTarget: "copilotcli"
15531
+ });
15532
+ }
15533
+ };
15534
+
15478
15535
  // src/features/rules/cursor-rule.ts
15479
15536
  var import_node_path112 = require("path");
15480
15537
  var import_mini59 = require("zod/mini");
@@ -17052,6 +17109,7 @@ var rulesProcessorToolTargets = [
17052
17109
  "cline",
17053
17110
  "codexcli",
17054
17111
  "copilot",
17112
+ "copilotcli",
17055
17113
  "cursor",
17056
17114
  "deepagents",
17057
17115
  "factorydroid",
@@ -17175,6 +17233,17 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
17175
17233
  }
17176
17234
  }
17177
17235
  ],
17236
+ [
17237
+ "copilotcli",
17238
+ {
17239
+ class: CopilotcliRule,
17240
+ meta: {
17241
+ extension: "md",
17242
+ supportsGlobal: true,
17243
+ ruleDiscoveryMode: "auto"
17244
+ }
17245
+ }
17246
+ ],
17178
17247
  [
17179
17248
  "cursor",
17180
17249
  {
@@ -19802,6 +19871,9 @@ async function generateCommand(logger5, options) {
19802
19871
  var import_node_path132 = require("path");
19803
19872
 
19804
19873
  // src/cli/commands/gitignore-entries.ts
19874
+ var normalizeGitignoreEntryTargets = (target) => {
19875
+ return typeof target === "string" ? [target] : target;
19876
+ };
19805
19877
  var GITIGNORE_ENTRY_REGISTRY = [
19806
19878
  // Common / general
19807
19879
  {
@@ -19904,11 +19976,15 @@ var GITIGNORE_ENTRY_REGISTRY = [
19904
19976
  { target: "goose", feature: "ignore", entry: "**/.gooseignore" },
19905
19977
  // GitHub Copilot
19906
19978
  {
19907
- target: "copilot",
19979
+ target: ["copilot", "copilotcli"],
19908
19980
  feature: "rules",
19909
19981
  entry: "**/.github/copilot-instructions.md"
19910
19982
  },
19911
- { target: "copilot", feature: "rules", entry: "**/.github/instructions/" },
19983
+ {
19984
+ target: ["copilot", "copilotcli"],
19985
+ feature: "rules",
19986
+ entry: "**/.github/instructions/"
19987
+ },
19912
19988
  { target: "copilot", feature: "commands", entry: "**/.github/prompts/" },
19913
19989
  { target: "copilot", feature: "subagents", entry: "**/.github/agents/" },
19914
19990
  { target: "copilot", feature: "skills", entry: "**/.github/skills/" },
@@ -19977,12 +20053,21 @@ var ALL_GITIGNORE_ENTRIES = GITIGNORE_ENTRY_REGISTRY.map(
19977
20053
  (tag) => tag.entry
19978
20054
  );
19979
20055
  var isTargetSelected = (target, selectedTargets) => {
19980
- if (target === "common") return true;
20056
+ const targets = normalizeGitignoreEntryTargets(target);
20057
+ if (targets.includes("common")) return true;
19981
20058
  if (!selectedTargets || selectedTargets.length === 0) return true;
19982
20059
  if (selectedTargets.includes("*")) return true;
19983
- return selectedTargets.includes(target);
20060
+ return targets.some((candidate) => selectedTargets.includes(candidate));
19984
20061
  };
19985
- var isFeatureSelected = (feature, target, features) => {
20062
+ var getSelectedGitignoreEntryTargets = (target, selectedTargets) => {
20063
+ const targets = normalizeGitignoreEntryTargets(target);
20064
+ if (targets.includes("common")) return ["common"];
20065
+ if (!selectedTargets || selectedTargets.length === 0 || selectedTargets.includes("*")) {
20066
+ return targets;
20067
+ }
20068
+ return targets.filter((candidate) => selectedTargets.includes(candidate));
20069
+ };
20070
+ var isFeatureSelectedForTarget = (feature, target, features) => {
19986
20071
  if (feature === "general") return true;
19987
20072
  if (!features) return true;
19988
20073
  if (Array.isArray(features)) {
@@ -19996,6 +20081,11 @@ var isFeatureSelected = (feature, target, features) => {
19996
20081
  if (targetFeatures.includes("*")) return true;
19997
20082
  return targetFeatures.includes(feature);
19998
20083
  };
20084
+ var isFeatureSelected = (feature, target, features) => {
20085
+ return normalizeGitignoreEntryTargets(target).some(
20086
+ (candidate) => isFeatureSelectedForTarget(feature, candidate, features)
20087
+ );
20088
+ };
19999
20089
  var warnInvalidTargets = (targets, logger5) => {
20000
20090
  const validTargets = new Set(ALL_TOOL_TARGETS_WITH_WILDCARD);
20001
20091
  for (const target of targets) {
@@ -20042,7 +20132,8 @@ var filterGitignoreEntries = (params) => {
20042
20132
  const result = [];
20043
20133
  for (const tag of GITIGNORE_ENTRY_REGISTRY) {
20044
20134
  if (!isTargetSelected(tag.target, targets)) continue;
20045
- if (!isFeatureSelected(tag.feature, tag.target, features)) continue;
20135
+ const selectedTagTargets = getSelectedGitignoreEntryTargets(tag.target, targets);
20136
+ if (!isFeatureSelected(tag.feature, selectedTagTargets, features)) continue;
20046
20137
  if (seen.has(tag.entry)) continue;
20047
20138
  seen.add(tag.entry);
20048
20139
  result.push(tag.entry);
@@ -23463,7 +23554,7 @@ function wrapCommand({
23463
23554
  }
23464
23555
 
23465
23556
  // src/cli/index.ts
23466
- var getVersion = () => "7.25.0";
23557
+ var getVersion = () => "7.26.0";
23467
23558
  function wrapCommand2(name, errorCode, handler) {
23468
23559
  return wrapCommand({ name, errorCode, handler, getVersion });
23469
23560
  }
package/dist/cli/index.js CHANGED
@@ -71,7 +71,7 @@ import {
71
71
  stringifyFrontmatter,
72
72
  toPosixPath,
73
73
  writeFileContent
74
- } from "../chunk-XGT6BGPR.js";
74
+ } from "../chunk-MMC5VK27.js";
75
75
 
76
76
  // src/cli/index.ts
77
77
  import { Command } from "commander";
@@ -1149,6 +1149,9 @@ async function generateCommand(logger5, options) {
1149
1149
  import { join as join2 } from "path";
1150
1150
 
1151
1151
  // src/cli/commands/gitignore-entries.ts
1152
+ var normalizeGitignoreEntryTargets = (target) => {
1153
+ return typeof target === "string" ? [target] : target;
1154
+ };
1152
1155
  var GITIGNORE_ENTRY_REGISTRY = [
1153
1156
  // Common / general
1154
1157
  {
@@ -1251,11 +1254,15 @@ var GITIGNORE_ENTRY_REGISTRY = [
1251
1254
  { target: "goose", feature: "ignore", entry: "**/.gooseignore" },
1252
1255
  // GitHub Copilot
1253
1256
  {
1254
- target: "copilot",
1257
+ target: ["copilot", "copilotcli"],
1255
1258
  feature: "rules",
1256
1259
  entry: "**/.github/copilot-instructions.md"
1257
1260
  },
1258
- { target: "copilot", feature: "rules", entry: "**/.github/instructions/" },
1261
+ {
1262
+ target: ["copilot", "copilotcli"],
1263
+ feature: "rules",
1264
+ entry: "**/.github/instructions/"
1265
+ },
1259
1266
  { target: "copilot", feature: "commands", entry: "**/.github/prompts/" },
1260
1267
  { target: "copilot", feature: "subagents", entry: "**/.github/agents/" },
1261
1268
  { target: "copilot", feature: "skills", entry: "**/.github/skills/" },
@@ -1324,12 +1331,21 @@ var ALL_GITIGNORE_ENTRIES = GITIGNORE_ENTRY_REGISTRY.map(
1324
1331
  (tag) => tag.entry
1325
1332
  );
1326
1333
  var isTargetSelected = (target, selectedTargets) => {
1327
- if (target === "common") return true;
1334
+ const targets = normalizeGitignoreEntryTargets(target);
1335
+ if (targets.includes("common")) return true;
1328
1336
  if (!selectedTargets || selectedTargets.length === 0) return true;
1329
1337
  if (selectedTargets.includes("*")) return true;
1330
- return selectedTargets.includes(target);
1338
+ return targets.some((candidate) => selectedTargets.includes(candidate));
1331
1339
  };
1332
- var isFeatureSelected = (feature, target, features) => {
1340
+ var getSelectedGitignoreEntryTargets = (target, selectedTargets) => {
1341
+ const targets = normalizeGitignoreEntryTargets(target);
1342
+ if (targets.includes("common")) return ["common"];
1343
+ if (!selectedTargets || selectedTargets.length === 0 || selectedTargets.includes("*")) {
1344
+ return targets;
1345
+ }
1346
+ return targets.filter((candidate) => selectedTargets.includes(candidate));
1347
+ };
1348
+ var isFeatureSelectedForTarget = (feature, target, features) => {
1333
1349
  if (feature === "general") return true;
1334
1350
  if (!features) return true;
1335
1351
  if (Array.isArray(features)) {
@@ -1343,6 +1359,11 @@ var isFeatureSelected = (feature, target, features) => {
1343
1359
  if (targetFeatures.includes("*")) return true;
1344
1360
  return targetFeatures.includes(feature);
1345
1361
  };
1362
+ var isFeatureSelected = (feature, target, features) => {
1363
+ return normalizeGitignoreEntryTargets(target).some(
1364
+ (candidate) => isFeatureSelectedForTarget(feature, candidate, features)
1365
+ );
1366
+ };
1346
1367
  var warnInvalidTargets = (targets, logger5) => {
1347
1368
  const validTargets = new Set(ALL_TOOL_TARGETS_WITH_WILDCARD);
1348
1369
  for (const target of targets) {
@@ -1389,7 +1410,8 @@ var filterGitignoreEntries = (params) => {
1389
1410
  const result = [];
1390
1411
  for (const tag of GITIGNORE_ENTRY_REGISTRY) {
1391
1412
  if (!isTargetSelected(tag.target, targets)) continue;
1392
- if (!isFeatureSelected(tag.feature, tag.target, features)) continue;
1413
+ const selectedTagTargets = getSelectedGitignoreEntryTargets(tag.target, targets);
1414
+ if (!isFeatureSelected(tag.feature, selectedTagTargets, features)) continue;
1393
1415
  if (seen.has(tag.entry)) continue;
1394
1416
  seen.add(tag.entry);
1395
1417
  result.push(tag.entry);
@@ -4438,7 +4460,7 @@ function wrapCommand({
4438
4460
  }
4439
4461
 
4440
4462
  // src/cli/index.ts
4441
- var getVersion = () => "7.25.0";
4463
+ var getVersion = () => "7.26.0";
4442
4464
  function wrapCommand2(name, errorCode, handler) {
4443
4465
  return wrapCommand({ name, errorCode, handler, getVersion });
4444
4466
  }
package/dist/index.cjs CHANGED
@@ -6135,7 +6135,7 @@ var import_mini21 = require("zod/mini");
6135
6135
  // src/types/mcp.ts
6136
6136
  var import_mini20 = require("zod/mini");
6137
6137
  var McpServerSchema = import_mini20.z.looseObject({
6138
- type: import_mini20.z.optional(import_mini20.z.enum(["stdio", "sse", "http"])),
6138
+ type: import_mini20.z.optional(import_mini20.z.enum(["local", "stdio", "sse", "http"])),
6139
6139
  command: import_mini20.z.optional(import_mini20.z.union([import_mini20.z.string(), import_mini20.z.array(import_mini20.z.string())])),
6140
6140
  args: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string())),
6141
6141
  url: import_mini20.z.optional(import_mini20.z.string()),
@@ -6146,7 +6146,7 @@ var McpServerSchema = import_mini20.z.looseObject({
6146
6146
  timeout: import_mini20.z.optional(import_mini20.z.number()),
6147
6147
  trust: import_mini20.z.optional(import_mini20.z.boolean()),
6148
6148
  cwd: import_mini20.z.optional(import_mini20.z.string()),
6149
- transport: import_mini20.z.optional(import_mini20.z.enum(["stdio", "sse", "http"])),
6149
+ transport: import_mini20.z.optional(import_mini20.z.enum(["local", "stdio", "sse", "http"])),
6150
6150
  alwaysAllow: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string())),
6151
6151
  tools: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string())),
6152
6152
  kiroAutoApprove: import_mini20.z.optional(import_mini20.z.array(import_mini20.z.string())),
@@ -6731,13 +6731,38 @@ var CopilotMcp = class _CopilotMcp extends ToolMcp {
6731
6731
 
6732
6732
  // src/features/mcp/copilotcli-mcp.ts
6733
6733
  var import_node_path51 = require("path");
6734
+ var isRemoteServerType = (type) => {
6735
+ return type === "http" || type === "sse";
6736
+ };
6737
+ var resolveCopilotcliServerType = (server) => {
6738
+ if (server.type) {
6739
+ return server.type;
6740
+ }
6741
+ if (server.transport === "http" || server.transport === "sse" || server.transport === "local") {
6742
+ return server.transport;
6743
+ }
6744
+ return "stdio";
6745
+ };
6734
6746
  function addTypeField(mcpServers) {
6735
6747
  const result = {};
6736
6748
  for (const [name, server] of Object.entries(mcpServers)) {
6737
6749
  const parsed = McpServerSchema.parse(server);
6750
+ const type = resolveCopilotcliServerType(parsed);
6751
+ if (isRemoteServerType(type)) {
6752
+ if (!parsed.url && !parsed.httpUrl) {
6753
+ throw new Error(
6754
+ `MCP server "${name}" is missing a url or httpUrl. GitHub Copilot CLI ${type} servers require a non-empty url or httpUrl.`
6755
+ );
6756
+ }
6757
+ result[name] = {
6758
+ ...parsed,
6759
+ type
6760
+ };
6761
+ continue;
6762
+ }
6738
6763
  if (!parsed.command) {
6739
6764
  throw new Error(
6740
- `MCP server "${name}" is missing a command. GitHub Copilot CLI stdio servers require a non-empty command.`
6765
+ `MCP server "${name}" is missing a command. GitHub Copilot CLI ${type} servers require a non-empty command.`
6741
6766
  );
6742
6767
  }
6743
6768
  let command;
@@ -6753,11 +6778,9 @@ function addTypeField(mcpServers) {
6753
6778
  command = cmd;
6754
6779
  args = cmdArgs.length > 0 ? [...cmdArgs, ...parsed.args ?? []] : parsed.args;
6755
6780
  }
6756
- const serverRecord = server;
6757
6781
  result[name] = {
6758
- ...serverRecord,
6759
6782
  ...parsed,
6760
- type: parsed.type ?? "stdio",
6783
+ type,
6761
6784
  command,
6762
6785
  ...args && { args }
6763
6786
  };
@@ -6767,6 +6790,10 @@ function addTypeField(mcpServers) {
6767
6790
  function removeTypeField(config) {
6768
6791
  const result = {};
6769
6792
  for (const [name, server] of Object.entries(config.mcpServers ?? {})) {
6793
+ if (server.type !== "stdio") {
6794
+ result[name] = server;
6795
+ continue;
6796
+ }
6770
6797
  const { type: _, ...rest } = server;
6771
6798
  result[name] = rest;
6772
6799
  }
@@ -6789,13 +6816,7 @@ var CopilotcliMcp = class _CopilotcliMcp extends ToolMcp {
6789
6816
  isDeletable() {
6790
6817
  return !this.global;
6791
6818
  }
6792
- static getSettablePaths({ global } = {}) {
6793
- if (global) {
6794
- return {
6795
- relativeDirPath: ".copilot",
6796
- relativeFilePath: "mcp-config.json"
6797
- };
6798
- }
6819
+ static getSettablePaths(_options = {}) {
6799
6820
  return {
6800
6821
  relativeDirPath: ".copilot",
6801
6822
  relativeFilePath: "mcp-config.json"
@@ -15773,6 +15794,42 @@ var CopilotRule = class _CopilotRule extends ToolRule {
15773
15794
  }
15774
15795
  };
15775
15796
 
15797
+ // src/features/rules/copilotcli-rule.ts
15798
+ var CopilotcliRule = class _CopilotcliRule extends CopilotRule {
15799
+ static fromCopilotRule(copilotRule, validate = true) {
15800
+ return new _CopilotcliRule({
15801
+ baseDir: copilotRule.getBaseDir(),
15802
+ relativeDirPath: copilotRule.getRelativeDirPath(),
15803
+ relativeFilePath: copilotRule.getRelativeFilePath(),
15804
+ frontmatter: copilotRule.getFrontmatter(),
15805
+ body: copilotRule.getBody(),
15806
+ validate,
15807
+ root: copilotRule.isRoot()
15808
+ });
15809
+ }
15810
+ static fromRulesyncRule({
15811
+ validate = true,
15812
+ ...rest
15813
+ }) {
15814
+ return this.fromCopilotRule(CopilotRule.fromRulesyncRule({ validate, ...rest }), validate);
15815
+ }
15816
+ static async fromFile({
15817
+ validate = true,
15818
+ ...rest
15819
+ }) {
15820
+ return this.fromCopilotRule(await CopilotRule.fromFile({ validate, ...rest }), validate);
15821
+ }
15822
+ static forDeletion(params) {
15823
+ return this.fromCopilotRule(CopilotRule.forDeletion(params), false);
15824
+ }
15825
+ static isTargetedByRulesyncRule(rulesyncRule) {
15826
+ return this.isTargetedByRulesyncRuleDefault({
15827
+ rulesyncRule,
15828
+ toolTarget: "copilotcli"
15829
+ });
15830
+ }
15831
+ };
15832
+
15776
15833
  // src/features/rules/cursor-rule.ts
15777
15834
  var import_node_path114 = require("path");
15778
15835
  var import_mini60 = require("zod/mini");
@@ -17350,6 +17407,7 @@ var rulesProcessorToolTargets = [
17350
17407
  "cline",
17351
17408
  "codexcli",
17352
17409
  "copilot",
17410
+ "copilotcli",
17353
17411
  "cursor",
17354
17412
  "deepagents",
17355
17413
  "factorydroid",
@@ -17473,6 +17531,17 @@ var toolRuleFactories = /* @__PURE__ */ new Map([
17473
17531
  }
17474
17532
  }
17475
17533
  ],
17534
+ [
17535
+ "copilotcli",
17536
+ {
17537
+ class: CopilotcliRule,
17538
+ meta: {
17539
+ extension: "md",
17540
+ supportsGlobal: true,
17541
+ ruleDiscoveryMode: "auto"
17542
+ }
17543
+ }
17544
+ ],
17476
17545
  [
17477
17546
  "cursor",
17478
17547
  {
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  checkRulesyncDirExists,
7
7
  generate,
8
8
  importFromTool
9
- } from "./chunk-XGT6BGPR.js";
9
+ } from "./chunk-MMC5VK27.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": "7.25.0",
3
+ "version": "7.26.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",