rulesync 0.36.0 → 0.38.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.
@@ -1,29 +1,376 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- generateClaudeMcp
4
- } from "./chunk-UNTCJDMQ.mjs";
5
- import {
6
- generateClineMcp
7
- } from "./chunk-QHXMJZTJ.mjs";
8
- import {
9
- generateCopilotMcp
10
- } from "./chunk-YGXGGUBG.mjs";
11
- import {
12
- generateCursorMcp
13
- } from "./chunk-SBYRCTWS.mjs";
14
- import {
15
- generateGeminiCliMcp
16
- } from "./chunk-6PQ4APY4.mjs";
17
- import {
18
- generateRooMcp
19
- } from "./chunk-QVPQ2X4L.mjs";
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+
29
+ // src/schemas/mcp.ts
30
+ var import_zod, ToolTargetSchema, WildcardTargetSchema, SpecificTargetsSchema, RulesyncTargetsSchema, McpTransportTypeSchema, McpServerBaseSchema, RulesyncMcpServerSchema;
31
+ var init_mcp = __esm({
32
+ "src/schemas/mcp.ts"() {
33
+ "use strict";
34
+ import_zod = require("zod");
35
+ ToolTargetSchema = import_zod.z.enum([
36
+ "copilot",
37
+ "cursor",
38
+ "cline",
39
+ "claudecode",
40
+ "claude",
41
+ "roo",
42
+ "geminicli"
43
+ ]);
44
+ WildcardTargetSchema = import_zod.z.tuple([import_zod.z.literal("*")]);
45
+ SpecificTargetsSchema = import_zod.z.array(ToolTargetSchema);
46
+ RulesyncTargetsSchema = import_zod.z.union([SpecificTargetsSchema, WildcardTargetSchema]);
47
+ McpTransportTypeSchema = import_zod.z.enum(["stdio", "sse", "http"]);
48
+ McpServerBaseSchema = import_zod.z.object({
49
+ command: import_zod.z.string().optional(),
50
+ args: import_zod.z.array(import_zod.z.string()).optional(),
51
+ url: import_zod.z.string().optional(),
52
+ httpUrl: import_zod.z.string().optional(),
53
+ env: import_zod.z.record(import_zod.z.string()).optional(),
54
+ disabled: import_zod.z.boolean().optional(),
55
+ networkTimeout: import_zod.z.number().optional(),
56
+ timeout: import_zod.z.number().optional(),
57
+ trust: import_zod.z.boolean().optional(),
58
+ cwd: import_zod.z.string().optional(),
59
+ transport: McpTransportTypeSchema.optional(),
60
+ type: import_zod.z.enum(["sse", "streamable-http"]).optional(),
61
+ alwaysAllow: import_zod.z.array(import_zod.z.string()).optional(),
62
+ tools: import_zod.z.array(import_zod.z.string()).optional()
63
+ });
64
+ RulesyncMcpServerSchema = McpServerBaseSchema.extend({
65
+ rulesyncTargets: RulesyncTargetsSchema.optional()
66
+ });
67
+ }
68
+ });
69
+
70
+ // src/utils/mcp-helpers.ts
71
+ function shouldIncludeServer(server, targetTool) {
72
+ if (!server.rulesyncTargets || server.rulesyncTargets.length === 0) {
73
+ return true;
74
+ }
75
+ const parsedTargets = RulesyncTargetsSchema.parse(server.rulesyncTargets);
76
+ if (parsedTargets.length === 1 && parsedTargets[0] === "*") {
77
+ return true;
78
+ }
79
+ const validatedTool = ToolTargetSchema.parse(targetTool);
80
+ for (const target of parsedTargets) {
81
+ if (target === validatedTool) {
82
+ return true;
83
+ }
84
+ }
85
+ return false;
86
+ }
87
+ var init_mcp_helpers = __esm({
88
+ "src/utils/mcp-helpers.ts"() {
89
+ "use strict";
90
+ init_mcp();
91
+ }
92
+ });
93
+
94
+ // src/generators/mcp/claude.ts
95
+ function generateClaudeMcp(config, _target) {
96
+ const claudeSettings = {
97
+ mcpServers: {}
98
+ };
99
+ const shouldInclude = (server) => {
100
+ return shouldIncludeServer(server, "claude");
101
+ };
102
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
103
+ if (!shouldInclude(server)) continue;
104
+ const claudeServer = {};
105
+ if (server.command) {
106
+ claudeServer.command = server.command;
107
+ if (server.args) claudeServer.args = server.args;
108
+ } else if (server.url || server.httpUrl) {
109
+ const url = server.httpUrl || server.url;
110
+ if (url) {
111
+ claudeServer.url = url;
112
+ }
113
+ if (server.httpUrl) {
114
+ claudeServer.transport = "http";
115
+ } else if (server.transport === "sse") {
116
+ claudeServer.transport = "sse";
117
+ }
118
+ }
119
+ if (server.env) {
120
+ claudeServer.env = server.env;
121
+ }
122
+ claudeSettings.mcpServers[serverName] = claudeServer;
123
+ }
124
+ return JSON.stringify(claudeSettings, null, 2);
125
+ }
126
+ var init_claude = __esm({
127
+ "src/generators/mcp/claude.ts"() {
128
+ "use strict";
129
+ init_mcp_helpers();
130
+ }
131
+ });
132
+
133
+ // src/generators/mcp/cline.ts
134
+ function generateClineMcp(config, _target) {
135
+ const clineConfig = {
136
+ mcpServers: {}
137
+ };
138
+ const shouldInclude = (server) => {
139
+ return shouldIncludeServer(server, "cline");
140
+ };
141
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
142
+ if (!shouldInclude(server)) continue;
143
+ const clineServer = {};
144
+ if (server.command) {
145
+ clineServer.command = server.command;
146
+ if (server.args) clineServer.args = server.args;
147
+ } else if (server.url) {
148
+ clineServer.url = server.url;
149
+ }
150
+ if (server.env) {
151
+ clineServer.env = server.env;
152
+ }
153
+ if (server.disabled !== void 0) {
154
+ clineServer.disabled = server.disabled;
155
+ }
156
+ if (server.alwaysAllow) {
157
+ clineServer.alwaysAllow = server.alwaysAllow;
158
+ }
159
+ if (server.networkTimeout !== void 0) {
160
+ clineServer.networkTimeout = server.networkTimeout;
161
+ }
162
+ clineConfig.mcpServers[serverName] = clineServer;
163
+ }
164
+ return JSON.stringify(clineConfig, null, 2);
165
+ }
166
+ var init_cline = __esm({
167
+ "src/generators/mcp/cline.ts"() {
168
+ "use strict";
169
+ init_mcp_helpers();
170
+ }
171
+ });
172
+
173
+ // src/generators/mcp/copilot.ts
174
+ function generateCopilotMcp(config, target) {
175
+ const servers = {};
176
+ const inputs = [];
177
+ const inputMap = /* @__PURE__ */ new Map();
178
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
179
+ if (!shouldIncludeServer(server, "copilot")) continue;
180
+ const copilotServer = {};
181
+ if (server.command) {
182
+ copilotServer.command = server.command;
183
+ if (server.args) copilotServer.args = server.args;
184
+ } else if (server.url || server.httpUrl) {
185
+ const url = server.httpUrl || server.url;
186
+ if (url) {
187
+ copilotServer.url = url;
188
+ }
189
+ }
190
+ if (server.env) {
191
+ copilotServer.env = {};
192
+ for (const [key, value] of Object.entries(server.env)) {
193
+ if (target === "editor" && value.includes("SECRET")) {
194
+ const inputId = `${serverName}_${key}`;
195
+ inputMap.set(inputId, value);
196
+ copilotServer.env[key] = `\${input:${inputId}}`;
197
+ inputs.push({
198
+ id: inputId,
199
+ type: "password",
200
+ description: `${key} for ${serverName}`
201
+ });
202
+ } else {
203
+ copilotServer.env[key] = value;
204
+ }
205
+ }
206
+ }
207
+ if (server.tools) {
208
+ copilotServer.tools = server.tools;
209
+ } else if (server.alwaysAllow) {
210
+ copilotServer.tools = server.alwaysAllow;
211
+ }
212
+ servers[serverName] = copilotServer;
213
+ }
214
+ if (target === "codingAgent") {
215
+ const config2 = { mcpServers: servers };
216
+ return JSON.stringify(config2, null, 2);
217
+ } else {
218
+ const config2 = { servers };
219
+ if (inputs.length > 0) {
220
+ config2.inputs = inputs;
221
+ }
222
+ return JSON.stringify(config2, null, 2);
223
+ }
224
+ }
225
+ var init_copilot = __esm({
226
+ "src/generators/mcp/copilot.ts"() {
227
+ "use strict";
228
+ init_mcp_helpers();
229
+ }
230
+ });
231
+
232
+ // src/generators/mcp/cursor.ts
233
+ function generateCursorMcp(config, _target) {
234
+ const cursorConfig = {
235
+ mcpServers: {}
236
+ };
237
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
238
+ if (!shouldIncludeServer(server, "cursor")) continue;
239
+ const cursorServer = {};
240
+ if (server.command) {
241
+ cursorServer.command = server.command;
242
+ if (server.args) cursorServer.args = server.args;
243
+ } else if (server.url || server.httpUrl) {
244
+ const url = server.httpUrl || server.url;
245
+ if (url) {
246
+ cursorServer.url = url;
247
+ }
248
+ if (server.httpUrl || server.transport === "http") {
249
+ cursorServer.type = "streamable-http";
250
+ } else if (server.transport === "sse" || server.type === "sse") {
251
+ cursorServer.type = "sse";
252
+ }
253
+ }
254
+ if (server.env) {
255
+ cursorServer.env = server.env;
256
+ }
257
+ if (server.cwd) {
258
+ cursorServer.cwd = server.cwd;
259
+ }
260
+ cursorConfig.mcpServers[serverName] = cursorServer;
261
+ }
262
+ return JSON.stringify(cursorConfig, null, 2);
263
+ }
264
+ var init_cursor = __esm({
265
+ "src/generators/mcp/cursor.ts"() {
266
+ "use strict";
267
+ init_mcp_helpers();
268
+ }
269
+ });
270
+
271
+ // src/generators/mcp/geminicli.ts
272
+ function generateGeminiCliMcp(config, _target) {
273
+ const geminiSettings = {
274
+ mcpServers: {}
275
+ };
276
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
277
+ if (!shouldIncludeServer(server, "geminicli")) continue;
278
+ const geminiServer = {};
279
+ if (server.command) {
280
+ geminiServer.command = server.command;
281
+ if (server.args) geminiServer.args = server.args;
282
+ } else if (server.url || server.httpUrl) {
283
+ if (server.httpUrl) {
284
+ geminiServer.httpUrl = server.httpUrl;
285
+ } else if (server.url) {
286
+ geminiServer.url = server.url;
287
+ }
288
+ }
289
+ if (server.env) {
290
+ geminiServer.env = {};
291
+ for (const [key, value] of Object.entries(server.env)) {
292
+ if (value.startsWith("${") && value.endsWith("}")) {
293
+ geminiServer.env[key] = value;
294
+ } else {
295
+ geminiServer.env[key] = `\${${value}}`;
296
+ }
297
+ }
298
+ }
299
+ if (server.timeout !== void 0) {
300
+ geminiServer.timeout = server.timeout;
301
+ }
302
+ if (server.trust !== void 0) {
303
+ geminiServer.trust = server.trust;
304
+ }
305
+ geminiSettings.mcpServers[serverName] = geminiServer;
306
+ }
307
+ return JSON.stringify(geminiSettings, null, 2);
308
+ }
309
+ var init_geminicli = __esm({
310
+ "src/generators/mcp/geminicli.ts"() {
311
+ "use strict";
312
+ init_mcp_helpers();
313
+ }
314
+ });
315
+
316
+ // src/generators/mcp/roo.ts
317
+ function generateRooMcp(config, _target) {
318
+ const rooConfig = {
319
+ mcpServers: {}
320
+ };
321
+ for (const [serverName, server] of Object.entries(config.mcpServers)) {
322
+ if (!shouldIncludeServer(server, "roo")) continue;
323
+ const rooServer = {};
324
+ if (server.command) {
325
+ rooServer.command = server.command;
326
+ if (server.args) rooServer.args = server.args;
327
+ } else if (server.url || server.httpUrl) {
328
+ const url = server.httpUrl || server.url;
329
+ if (url) {
330
+ rooServer.url = url;
331
+ }
332
+ if (server.httpUrl || server.transport === "http") {
333
+ rooServer.type = "streamable-http";
334
+ } else if (server.transport === "sse" || server.type === "sse") {
335
+ rooServer.type = "sse";
336
+ }
337
+ }
338
+ if (server.env) {
339
+ rooServer.env = {};
340
+ for (const [key, value] of Object.entries(server.env)) {
341
+ if (value.startsWith("${env:") && value.endsWith("}")) {
342
+ rooServer.env[key] = value;
343
+ } else {
344
+ rooServer.env[key] = `\${env:${value}}`;
345
+ }
346
+ }
347
+ }
348
+ if (server.disabled !== void 0) {
349
+ rooServer.disabled = server.disabled;
350
+ }
351
+ if (server.alwaysAllow) {
352
+ rooServer.alwaysAllow = server.alwaysAllow;
353
+ }
354
+ if (server.networkTimeout !== void 0) {
355
+ rooServer.networkTimeout = Math.max(3e4, Math.min(3e5, server.networkTimeout));
356
+ }
357
+ rooConfig.mcpServers[serverName] = rooServer;
358
+ }
359
+ return JSON.stringify(rooConfig, null, 2);
360
+ }
361
+ var init_roo = __esm({
362
+ "src/generators/mcp/roo.ts"() {
363
+ "use strict";
364
+ init_mcp_helpers();
365
+ }
366
+ });
20
367
 
21
368
  // src/cli/index.ts
22
- import { Command } from "commander";
369
+ var import_commander = require("commander");
23
370
 
24
371
  // src/cli/commands/add.ts
25
- import { mkdir, writeFile } from "fs/promises";
26
- import path from "path";
372
+ var import_promises = require("fs/promises");
373
+ var import_node_path = __toESM(require("path"), 1);
27
374
 
28
375
  // src/utils/config.ts
29
376
  function getDefaultConfig() {
@@ -71,10 +418,10 @@ async function addCommand(filename) {
71
418
  const config = getDefaultConfig();
72
419
  const sanitizedFilename = sanitizeFilename(filename);
73
420
  const rulesDir = config.aiRulesDir;
74
- const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
75
- await mkdir(rulesDir, { recursive: true });
421
+ const filePath = import_node_path.default.join(rulesDir, `${sanitizedFilename}.md`);
422
+ await (0, import_promises.mkdir)(rulesDir, { recursive: true });
76
423
  const template = generateRuleTemplate(sanitizedFilename);
77
- await writeFile(filePath, template, "utf8");
424
+ await (0, import_promises.writeFile)(filePath, template, "utf8");
78
425
  console.log(`\u2705 Created rule file: ${filePath}`);
79
426
  console.log(`\u{1F4DD} Edit the file to customize your rules.`);
80
427
  } catch (error) {
@@ -86,21 +433,47 @@ async function addCommand(filename) {
86
433
  }
87
434
 
88
435
  // src/generators/rules/claudecode.ts
89
- import { join as join3 } from "path";
436
+ var import_node_path5 = require("path");
90
437
 
91
438
  // src/utils/file.ts
92
- import { mkdir as mkdir2, readdir, readFile, rm, stat, writeFile as writeFile2 } from "fs/promises";
93
- import { dirname, join as join2 } from "path";
439
+ var import_promises3 = require("fs/promises");
440
+ var import_node_path4 = require("path");
441
+
442
+ // src/utils/file-ops.ts
443
+ var import_promises2 = require("fs/promises");
444
+ var import_node_path2 = require("path");
445
+ async function ensureDir(dirPath) {
446
+ try {
447
+ await (0, import_promises2.stat)(dirPath);
448
+ } catch {
449
+ await (0, import_promises2.mkdir)(dirPath, { recursive: true });
450
+ }
451
+ }
452
+ async function readFileContent(filepath) {
453
+ return (0, import_promises2.readFile)(filepath, "utf-8");
454
+ }
455
+ async function writeFileContent(filepath, content) {
456
+ await ensureDir((0, import_node_path2.dirname)(filepath));
457
+ await (0, import_promises2.writeFile)(filepath, content, "utf-8");
458
+ }
459
+ async function fileExists(filepath) {
460
+ try {
461
+ await (0, import_promises2.stat)(filepath);
462
+ return true;
463
+ } catch {
464
+ return false;
465
+ }
466
+ }
94
467
 
95
468
  // src/utils/ignore.ts
96
- import { join } from "path";
97
- import micromatch from "micromatch";
469
+ var import_node_path3 = require("path");
470
+ var import_micromatch = __toESM(require("micromatch"), 1);
98
471
  var cachedIgnorePatterns = null;
99
472
  async function loadIgnorePatterns(baseDir = process.cwd()) {
100
473
  if (cachedIgnorePatterns) {
101
474
  return cachedIgnorePatterns;
102
475
  }
103
- const ignorePath = join(baseDir, ".rulesyncignore");
476
+ const ignorePath = (0, import_node_path3.join)(baseDir, ".rulesyncignore");
104
477
  if (!await fileExists(ignorePath)) {
105
478
  cachedIgnorePatterns = { patterns: [] };
106
479
  return cachedIgnorePatterns;
@@ -125,12 +498,12 @@ function isFileIgnored(filepath, ignorePatterns) {
125
498
  }
126
499
  const negationPatterns = ignorePatterns.filter((p) => p.startsWith("!"));
127
500
  const positivePatterns = ignorePatterns.filter((p) => !p.startsWith("!"));
128
- const isIgnored = positivePatterns.length > 0 && micromatch.isMatch(filepath, positivePatterns, {
501
+ const isIgnored = positivePatterns.length > 0 && import_micromatch.default.isMatch(filepath, positivePatterns, {
129
502
  dot: true
130
503
  });
131
504
  if (isIgnored && negationPatterns.length > 0) {
132
505
  const negationPatternsWithoutPrefix = negationPatterns.map((p) => p.substring(1));
133
- return !micromatch.isMatch(filepath, negationPatternsWithoutPrefix, {
506
+ return !import_micromatch.default.isMatch(filepath, negationPatternsWithoutPrefix, {
134
507
  dot: true
135
508
  });
136
509
  }
@@ -144,24 +517,10 @@ function filterIgnoredFiles(files, ignorePatterns) {
144
517
  }
145
518
 
146
519
  // src/utils/file.ts
147
- async function ensureDir(dirPath) {
148
- try {
149
- await stat(dirPath);
150
- } catch {
151
- await mkdir2(dirPath, { recursive: true });
152
- }
153
- }
154
- async function readFileContent(filepath) {
155
- return readFile(filepath, "utf-8");
156
- }
157
- async function writeFileContent(filepath, content) {
158
- await ensureDir(dirname(filepath));
159
- await writeFile2(filepath, content, "utf-8");
160
- }
161
520
  async function findFiles(dir, extension = ".md", ignorePatterns) {
162
521
  try {
163
- const files = await readdir(dir);
164
- const filtered = files.filter((file) => file.endsWith(extension)).map((file) => join2(dir, file));
522
+ const files = await (0, import_promises3.readdir)(dir);
523
+ const filtered = files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path4.join)(dir, file));
165
524
  if (ignorePatterns && ignorePatterns.length > 0) {
166
525
  return filterIgnoredFiles(filtered, ignorePatterns);
167
526
  }
@@ -170,14 +529,6 @@ async function findFiles(dir, extension = ".md", ignorePatterns) {
170
529
  return [];
171
530
  }
172
531
  }
173
- async function fileExists(filepath) {
174
- try {
175
- await stat(filepath);
176
- return true;
177
- } catch {
178
- return false;
179
- }
180
- }
181
532
  async function removeDirectory(dirPath) {
182
533
  const dangerousPaths = [".", "/", "~", "src", "node_modules"];
183
534
  if (dangerousPaths.includes(dirPath) || dirPath === "") {
@@ -186,7 +537,7 @@ async function removeDirectory(dirPath) {
186
537
  }
187
538
  try {
188
539
  if (await fileExists(dirPath)) {
189
- await rm(dirPath, { recursive: true, force: true });
540
+ await (0, import_promises3.rm)(dirPath, { recursive: true, force: true });
190
541
  }
191
542
  } catch (error) {
192
543
  console.warn(`Failed to remove directory ${dirPath}:`, error);
@@ -195,7 +546,7 @@ async function removeDirectory(dirPath) {
195
546
  async function removeFile(filepath) {
196
547
  try {
197
548
  if (await fileExists(filepath)) {
198
- await rm(filepath);
549
+ await (0, import_promises3.rm)(filepath);
199
550
  }
200
551
  } catch (error) {
201
552
  console.warn(`Failed to remove file ${filepath}:`, error);
@@ -218,23 +569,23 @@ async function generateClaudecodeConfig(rules, config, baseDir) {
218
569
  const rootRules = rules.filter((r) => r.frontmatter.root === true);
219
570
  const detailRules = rules.filter((r) => r.frontmatter.root === false);
220
571
  const claudeMdContent = generateClaudeMarkdown(rootRules, detailRules);
221
- const claudeOutputDir = baseDir ? join3(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
572
+ const claudeOutputDir = baseDir ? (0, import_node_path5.join)(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
222
573
  outputs.push({
223
574
  tool: "claudecode",
224
- filepath: join3(claudeOutputDir, "CLAUDE.md"),
575
+ filepath: (0, import_node_path5.join)(claudeOutputDir, "CLAUDE.md"),
225
576
  content: claudeMdContent
226
577
  });
227
578
  for (const rule of detailRules) {
228
579
  const memoryContent = generateMemoryFile(rule);
229
580
  outputs.push({
230
581
  tool: "claudecode",
231
- filepath: join3(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
582
+ filepath: (0, import_node_path5.join)(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
232
583
  content: memoryContent
233
584
  });
234
585
  }
235
586
  const ignorePatterns = await loadIgnorePatterns(baseDir);
236
587
  if (ignorePatterns.patterns.length > 0) {
237
- const settingsPath = baseDir ? join3(baseDir, ".claude", "settings.json") : join3(".claude", "settings.json");
588
+ const settingsPath = baseDir ? (0, import_node_path5.join)(baseDir, ".claude", "settings.json") : (0, import_node_path5.join)(".claude", "settings.json");
238
589
  await updateClaudeSettings(settingsPath, ignorePatterns.patterns);
239
590
  }
240
591
  return outputs;
@@ -271,39 +622,46 @@ async function updateClaudeSettings(settingsPath, ignorePatterns) {
271
622
  try {
272
623
  const content = await readFileContent(settingsPath);
273
624
  settings = JSON.parse(content);
274
- } catch (_error) {
625
+ } catch {
275
626
  console.warn(`Failed to parse existing ${settingsPath}, creating new settings`);
276
627
  settings = {};
277
628
  }
278
629
  }
279
- if (!settings.permissions) {
280
- settings.permissions = {};
630
+ if (typeof settings !== "object" || settings === null) {
631
+ settings = {};
632
+ }
633
+ const settingsObj = settings;
634
+ if (!settingsObj.permissions || typeof settingsObj.permissions !== "object" || settingsObj.permissions === null) {
635
+ settingsObj.permissions = {};
281
636
  }
282
- if (!Array.isArray(settings.permissions.deny)) {
283
- settings.permissions.deny = [];
637
+ const permissions = settingsObj.permissions;
638
+ if (!Array.isArray(permissions.deny)) {
639
+ permissions.deny = [];
284
640
  }
285
641
  const readDenyRules = ignorePatterns.map((pattern) => `Read(${pattern})`);
286
- settings.permissions.deny = settings.permissions.deny.filter((rule) => {
642
+ const denyArray = permissions.deny;
643
+ const filteredDeny = denyArray.filter((rule) => {
644
+ if (typeof rule !== "string") return false;
287
645
  if (!rule.startsWith("Read(")) return true;
288
646
  const match = rule.match(/^Read\((.*)\)$/);
289
647
  if (!match) return true;
290
648
  return !ignorePatterns.includes(match[1] ?? "");
291
649
  });
292
- settings.permissions.deny.push(...readDenyRules);
293
- settings.permissions.deny = [...new Set(settings.permissions.deny)];
294
- const jsonContent = JSON.stringify(settings, null, 2);
650
+ filteredDeny.push(...readDenyRules);
651
+ permissions.deny = [...new Set(filteredDeny)];
652
+ const jsonContent = JSON.stringify(settingsObj, null, 2);
295
653
  await writeFileContent(settingsPath, jsonContent);
296
654
  console.log(`\u2705 Updated Claude Code settings: ${settingsPath}`);
297
655
  }
298
656
 
299
657
  // src/generators/rules/cline.ts
300
- import { join as join4 } from "path";
658
+ var import_node_path6 = require("path");
301
659
  async function generateClineConfig(rules, config, baseDir) {
302
660
  const outputs = [];
303
661
  for (const rule of rules) {
304
662
  const content = generateClineMarkdown(rule);
305
- const outputDir = baseDir ? join4(baseDir, config.outputPaths.cline) : config.outputPaths.cline;
306
- const filepath = join4(outputDir, `${rule.filename}.md`);
663
+ const outputDir = baseDir ? (0, import_node_path6.join)(baseDir, config.outputPaths.cline) : config.outputPaths.cline;
664
+ const filepath = (0, import_node_path6.join)(outputDir, `${rule.filename}.md`);
307
665
  outputs.push({
308
666
  tool: "cline",
309
667
  filepath,
@@ -312,7 +670,7 @@ async function generateClineConfig(rules, config, baseDir) {
312
670
  }
313
671
  const ignorePatterns = await loadIgnorePatterns(baseDir);
314
672
  if (ignorePatterns.patterns.length > 0) {
315
- const clineIgnorePath = baseDir ? join4(baseDir, ".clineignore") : ".clineignore";
673
+ const clineIgnorePath = baseDir ? (0, import_node_path6.join)(baseDir, ".clineignore") : ".clineignore";
316
674
  const clineIgnoreContent = generateClineIgnore(ignorePatterns.patterns);
317
675
  outputs.push({
318
676
  tool: "cline",
@@ -336,14 +694,14 @@ function generateClineIgnore(patterns) {
336
694
  }
337
695
 
338
696
  // src/generators/rules/copilot.ts
339
- import { join as join5 } from "path";
697
+ var import_node_path7 = require("path");
340
698
  async function generateCopilotConfig(rules, config, baseDir) {
341
699
  const outputs = [];
342
700
  for (const rule of rules) {
343
701
  const content = generateCopilotMarkdown(rule);
344
702
  const baseFilename = rule.filename.replace(/\.md$/, "");
345
- const outputDir = baseDir ? join5(baseDir, config.outputPaths.copilot) : config.outputPaths.copilot;
346
- const filepath = join5(outputDir, `${baseFilename}.instructions.md`);
703
+ const outputDir = baseDir ? (0, import_node_path7.join)(baseDir, config.outputPaths.copilot) : config.outputPaths.copilot;
704
+ const filepath = (0, import_node_path7.join)(outputDir, `${baseFilename}.instructions.md`);
347
705
  outputs.push({
348
706
  tool: "copilot",
349
707
  filepath,
@@ -352,7 +710,7 @@ async function generateCopilotConfig(rules, config, baseDir) {
352
710
  }
353
711
  const ignorePatterns = await loadIgnorePatterns(baseDir);
354
712
  if (ignorePatterns.patterns.length > 0) {
355
- const copilotIgnorePath = baseDir ? join5(baseDir, ".copilotignore") : ".copilotignore";
713
+ const copilotIgnorePath = baseDir ? (0, import_node_path7.join)(baseDir, ".copilotignore") : ".copilotignore";
356
714
  const copilotIgnoreContent = generateCopilotIgnore(ignorePatterns.patterns);
357
715
  outputs.push({
358
716
  tool: "copilot",
@@ -388,13 +746,13 @@ function generateCopilotIgnore(patterns) {
388
746
  }
389
747
 
390
748
  // src/generators/rules/cursor.ts
391
- import { join as join6 } from "path";
749
+ var import_node_path8 = require("path");
392
750
  async function generateCursorConfig(rules, config, baseDir) {
393
751
  const outputs = [];
394
752
  for (const rule of rules) {
395
753
  const content = generateCursorMarkdown(rule);
396
- const outputDir = baseDir ? join6(baseDir, config.outputPaths.cursor) : config.outputPaths.cursor;
397
- const filepath = join6(outputDir, `${rule.filename}.mdc`);
754
+ const outputDir = baseDir ? (0, import_node_path8.join)(baseDir, config.outputPaths.cursor) : config.outputPaths.cursor;
755
+ const filepath = (0, import_node_path8.join)(outputDir, `${rule.filename}.mdc`);
398
756
  outputs.push({
399
757
  tool: "cursor",
400
758
  filepath,
@@ -403,7 +761,7 @@ async function generateCursorConfig(rules, config, baseDir) {
403
761
  }
404
762
  const ignorePatterns = await loadIgnorePatterns(baseDir);
405
763
  if (ignorePatterns.patterns.length > 0) {
406
- const cursorIgnorePath = baseDir ? join6(baseDir, ".cursorignore") : ".cursorignore";
764
+ const cursorIgnorePath = baseDir ? (0, import_node_path8.join)(baseDir, ".cursorignore") : ".cursorignore";
407
765
  const cursorIgnoreContent = generateCursorIgnore(ignorePatterns.patterns);
408
766
  outputs.push({
409
767
  tool: "cursor",
@@ -444,15 +802,15 @@ function generateCursorIgnore(patterns) {
444
802
  }
445
803
 
446
804
  // src/generators/rules/geminicli.ts
447
- import { join as join7 } from "path";
805
+ var import_node_path9 = require("path");
448
806
  async function generateGeminiConfig(rules, config, baseDir) {
449
807
  const outputs = [];
450
808
  const rootRule = rules.find((rule) => rule.frontmatter.root === true);
451
809
  const memoryRules = rules.filter((rule) => rule.frontmatter.root === false);
452
810
  for (const rule of memoryRules) {
453
811
  const content = generateGeminiMemoryMarkdown(rule);
454
- const outputDir = baseDir ? join7(baseDir, config.outputPaths.geminicli) : config.outputPaths.geminicli;
455
- const filepath = join7(outputDir, `${rule.filename}.md`);
812
+ const outputDir = baseDir ? (0, import_node_path9.join)(baseDir, config.outputPaths.geminicli) : config.outputPaths.geminicli;
813
+ const filepath = (0, import_node_path9.join)(outputDir, `${rule.filename}.md`);
456
814
  outputs.push({
457
815
  tool: "geminicli",
458
816
  filepath,
@@ -460,7 +818,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
460
818
  });
461
819
  }
462
820
  const rootContent = generateGeminiRootMarkdown(rootRule, memoryRules, baseDir);
463
- const rootFilepath = baseDir ? join7(baseDir, "GEMINI.md") : "GEMINI.md";
821
+ const rootFilepath = baseDir ? (0, import_node_path9.join)(baseDir, "GEMINI.md") : "GEMINI.md";
464
822
  outputs.push({
465
823
  tool: "geminicli",
466
824
  filepath: rootFilepath,
@@ -468,7 +826,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
468
826
  });
469
827
  const ignorePatterns = await loadIgnorePatterns(baseDir);
470
828
  if (ignorePatterns.patterns.length > 0) {
471
- const aiexcludePath = baseDir ? join7(baseDir, ".aiexclude") : ".aiexclude";
829
+ const aiexcludePath = baseDir ? (0, import_node_path9.join)(baseDir, ".aiexclude") : ".aiexclude";
472
830
  const aiexcludeContent = generateAiexclude(ignorePatterns.patterns);
473
831
  outputs.push({
474
832
  tool: "geminicli",
@@ -516,13 +874,13 @@ function generateAiexclude(patterns) {
516
874
  }
517
875
 
518
876
  // src/generators/rules/roo.ts
519
- import { join as join8 } from "path";
877
+ var import_node_path10 = require("path");
520
878
  async function generateRooConfig(rules, config, baseDir) {
521
879
  const outputs = [];
522
880
  for (const rule of rules) {
523
881
  const content = generateRooMarkdown(rule);
524
- const outputDir = baseDir ? join8(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
525
- const filepath = join8(outputDir, `${rule.filename}.md`);
882
+ const outputDir = baseDir ? (0, import_node_path10.join)(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
883
+ const filepath = (0, import_node_path10.join)(outputDir, `${rule.filename}.md`);
526
884
  outputs.push({
527
885
  tool: "roo",
528
886
  filepath,
@@ -531,7 +889,7 @@ async function generateRooConfig(rules, config, baseDir) {
531
889
  }
532
890
  const ignorePatterns = await loadIgnorePatterns(baseDir);
533
891
  if (ignorePatterns.patterns.length > 0) {
534
- const rooIgnorePath = baseDir ? join8(baseDir, ".rooignore") : ".rooignore";
892
+ const rooIgnorePath = baseDir ? (0, import_node_path10.join)(baseDir, ".rooignore") : ".rooignore";
535
893
  const rooIgnoreContent = generateRooIgnore(ignorePatterns.patterns);
536
894
  outputs.push({
537
895
  tool: "roo",
@@ -604,8 +962,8 @@ async function generateForTool(tool, rules, config, baseDir) {
604
962
  }
605
963
 
606
964
  // src/core/parser.ts
607
- import { basename } from "path";
608
- import matter from "gray-matter";
965
+ var import_node_path11 = require("path");
966
+ var import_gray_matter = __toESM(require("gray-matter"), 1);
609
967
  async function parseRulesFromDirectory(aiRulesDir) {
610
968
  const ignorePatterns = await loadIgnorePatterns();
611
969
  const ruleFiles = await findFiles(aiRulesDir, ".md", ignorePatterns.patterns);
@@ -638,10 +996,10 @@ ${errors.join("\n")}`);
638
996
  }
639
997
  async function parseRuleFile(filepath) {
640
998
  const content = await readFileContent(filepath);
641
- const parsed = matter(content);
999
+ const parsed = (0, import_gray_matter.default)(content);
642
1000
  validateFrontmatter(parsed.data, filepath);
643
1001
  const frontmatter = parsed.data;
644
- const filename = basename(filepath, ".md");
1002
+ const filename = (0, import_node_path11.basename)(filepath, ".md");
645
1003
  return {
646
1004
  frontmatter,
647
1005
  content: parsed.content,
@@ -770,19 +1128,27 @@ async function validateRule(rule) {
770
1128
  }
771
1129
 
772
1130
  // src/core/mcp-generator.ts
773
- import os from "os";
774
- import path3 from "path";
1131
+ var import_node_os = __toESM(require("os"), 1);
1132
+ var import_node_path13 = __toESM(require("path"), 1);
1133
+
1134
+ // src/generators/mcp/index.ts
1135
+ init_claude();
1136
+ init_cline();
1137
+ init_copilot();
1138
+ init_cursor();
1139
+ init_geminicli();
1140
+ init_roo();
775
1141
 
776
1142
  // src/core/mcp-parser.ts
777
- import fs from "fs";
778
- import path2 from "path";
1143
+ var import_node_fs = __toESM(require("fs"), 1);
1144
+ var import_node_path12 = __toESM(require("path"), 1);
779
1145
  function parseMcpConfig(projectRoot) {
780
- const mcpPath = path2.join(projectRoot, ".rulesync", ".mcp.json");
781
- if (!fs.existsSync(mcpPath)) {
1146
+ const mcpPath = import_node_path12.default.join(projectRoot, ".rulesync", ".mcp.json");
1147
+ if (!import_node_fs.default.existsSync(mcpPath)) {
782
1148
  return null;
783
1149
  }
784
1150
  try {
785
- const content = fs.readFileSync(mcpPath, "utf-8");
1151
+ const content = import_node_fs.default.readFileSync(mcpPath, "utf-8");
786
1152
  const rawConfig = JSON.parse(content);
787
1153
  if (rawConfig.servers && !rawConfig.mcpServers) {
788
1154
  rawConfig.mcpServers = rawConfig.servers;
@@ -813,32 +1179,32 @@ async function generateMcpConfigs(projectRoot, baseDir) {
813
1179
  const generators = [
814
1180
  {
815
1181
  tool: "claude-project",
816
- path: path3.join(targetRoot, ".mcp.json"),
1182
+ path: import_node_path13.default.join(targetRoot, ".mcp.json"),
817
1183
  generate: () => generateClaudeMcp(config, "project")
818
1184
  },
819
1185
  {
820
1186
  tool: "copilot-editor",
821
- path: path3.join(targetRoot, ".vscode", "mcp.json"),
1187
+ path: import_node_path13.default.join(targetRoot, ".vscode", "mcp.json"),
822
1188
  generate: () => generateCopilotMcp(config, "editor")
823
1189
  },
824
1190
  {
825
1191
  tool: "cursor-project",
826
- path: path3.join(targetRoot, ".cursor", "mcp.json"),
1192
+ path: import_node_path13.default.join(targetRoot, ".cursor", "mcp.json"),
827
1193
  generate: () => generateCursorMcp(config, "project")
828
1194
  },
829
1195
  {
830
1196
  tool: "cline-project",
831
- path: path3.join(targetRoot, ".cline", "mcp.json"),
1197
+ path: import_node_path13.default.join(targetRoot, ".cline", "mcp.json"),
832
1198
  generate: () => generateClineMcp(config, "project")
833
1199
  },
834
1200
  {
835
1201
  tool: "gemini-project",
836
- path: path3.join(targetRoot, ".gemini", "settings.json"),
1202
+ path: import_node_path13.default.join(targetRoot, ".gemini", "settings.json"),
837
1203
  generate: () => generateGeminiCliMcp(config, "project")
838
1204
  },
839
1205
  {
840
1206
  tool: "roo-project",
841
- path: path3.join(targetRoot, ".roo", "mcp.json"),
1207
+ path: import_node_path13.default.join(targetRoot, ".roo", "mcp.json"),
842
1208
  generate: () => generateRooMcp(config, "project")
843
1209
  }
844
1210
  ];
@@ -846,17 +1212,17 @@ async function generateMcpConfigs(projectRoot, baseDir) {
846
1212
  generators.push(
847
1213
  {
848
1214
  tool: "claude-global",
849
- path: path3.join(os.homedir(), ".claude", "settings.json"),
1215
+ path: import_node_path13.default.join(import_node_os.default.homedir(), ".claude", "settings.json"),
850
1216
  generate: () => generateClaudeMcp(config, "global")
851
1217
  },
852
1218
  {
853
1219
  tool: "cursor-global",
854
- path: path3.join(os.homedir(), ".cursor", "mcp.json"),
1220
+ path: import_node_path13.default.join(import_node_os.default.homedir(), ".cursor", "mcp.json"),
855
1221
  generate: () => generateCursorMcp(config, "global")
856
1222
  },
857
1223
  {
858
1224
  tool: "gemini-global",
859
- path: path3.join(os.homedir(), ".gemini", "settings.json"),
1225
+ path: import_node_path13.default.join(import_node_os.default.homedir(), ".gemini", "settings.json"),
860
1226
  generate: () => generateGeminiCliMcp(config, "global")
861
1227
  }
862
1228
  );
@@ -1014,10 +1380,10 @@ Generating configurations for base directory: ${baseDir}`);
1014
1380
  }
1015
1381
 
1016
1382
  // src/cli/commands/gitignore.ts
1017
- import { existsSync, readFileSync, writeFileSync } from "fs";
1018
- import { join as join9 } from "path";
1383
+ var import_node_fs2 = require("fs");
1384
+ var import_node_path14 = require("path");
1019
1385
  var gitignoreCommand = async () => {
1020
- const gitignorePath = join9(process.cwd(), ".gitignore");
1386
+ const gitignorePath = (0, import_node_path14.join)(process.cwd(), ".gitignore");
1021
1387
  const rulesFilesToIgnore = [
1022
1388
  "# Generated by rulesync - AI tool configuration files",
1023
1389
  "**/.github/copilot-instructions.md",
@@ -1035,6 +1401,7 @@ var gitignoreCommand = async () => {
1035
1401
  "**/.gemini/memories/",
1036
1402
  "**/.aiexclude",
1037
1403
  "**/.mcp.json",
1404
+ "!.rulesync/.mcp.json",
1038
1405
  "**/.cursor/mcp.json",
1039
1406
  "**/.cline/mcp.json",
1040
1407
  "**/.vscode/mcp.json",
@@ -1042,8 +1409,8 @@ var gitignoreCommand = async () => {
1042
1409
  "**/.roo/mcp.json"
1043
1410
  ];
1044
1411
  let gitignoreContent = "";
1045
- if (existsSync(gitignorePath)) {
1046
- gitignoreContent = readFileSync(gitignorePath, "utf-8");
1412
+ if ((0, import_node_fs2.existsSync)(gitignorePath)) {
1413
+ gitignoreContent = (0, import_node_fs2.readFileSync)(gitignorePath, "utf-8");
1047
1414
  }
1048
1415
  const linesToAdd = [];
1049
1416
  for (const rule of rulesFilesToIgnore) {
@@ -1060,7 +1427,7 @@ var gitignoreCommand = async () => {
1060
1427
  ${linesToAdd.join("\n")}
1061
1428
  ` : `${linesToAdd.join("\n")}
1062
1429
  `;
1063
- writeFileSync(gitignorePath, newContent);
1430
+ (0, import_node_fs2.writeFileSync)(gitignorePath, newContent);
1064
1431
  console.log(`\u2705 .gitignore\u306B${linesToAdd.length}\u500B\u306E\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0\u3057\u307E\u3057\u305F:`);
1065
1432
  for (const line of linesToAdd) {
1066
1433
  if (!line.startsWith("#")) {
@@ -1070,17 +1437,17 @@ ${linesToAdd.join("\n")}
1070
1437
  };
1071
1438
 
1072
1439
  // src/core/importer.ts
1073
- import { join as join16 } from "path";
1074
- import matter4 from "gray-matter";
1440
+ var import_node_path21 = require("path");
1441
+ var import_gray_matter4 = __toESM(require("gray-matter"), 1);
1075
1442
 
1076
1443
  // src/parsers/claudecode.ts
1077
- import { basename as basename2, join as join10 } from "path";
1444
+ var import_node_path15 = require("path");
1078
1445
  async function parseClaudeConfiguration(baseDir = process.cwd()) {
1079
1446
  const errors = [];
1080
1447
  const rules = [];
1081
1448
  let ignorePatterns;
1082
1449
  let mcpServers;
1083
- const claudeFilePath = join10(baseDir, "CLAUDE.md");
1450
+ const claudeFilePath = (0, import_node_path15.join)(baseDir, "CLAUDE.md");
1084
1451
  if (!await fileExists(claudeFilePath)) {
1085
1452
  errors.push("CLAUDE.md file not found");
1086
1453
  return { rules, errors };
@@ -1091,12 +1458,12 @@ async function parseClaudeConfiguration(baseDir = process.cwd()) {
1091
1458
  if (mainRule) {
1092
1459
  rules.push(mainRule);
1093
1460
  }
1094
- const memoryDir = join10(baseDir, ".claude", "memories");
1461
+ const memoryDir = (0, import_node_path15.join)(baseDir, ".claude", "memories");
1095
1462
  if (await fileExists(memoryDir)) {
1096
1463
  const memoryRules = await parseClaudeMemoryFiles(memoryDir);
1097
1464
  rules.push(...memoryRules);
1098
1465
  }
1099
- const settingsPath = join10(baseDir, ".claude", "settings.json");
1466
+ const settingsPath = (0, import_node_path15.join)(baseDir, ".claude", "settings.json");
1100
1467
  if (await fileExists(settingsPath)) {
1101
1468
  const settingsResult = await parseClaudeSettings(settingsPath);
1102
1469
  if (settingsResult.ignorePatterns) {
@@ -1153,10 +1520,10 @@ async function parseClaudeMemoryFiles(memoryDir) {
1153
1520
  const files = await readdir2(memoryDir);
1154
1521
  for (const file of files) {
1155
1522
  if (file.endsWith(".md")) {
1156
- const filePath = join10(memoryDir, file);
1523
+ const filePath = (0, import_node_path15.join)(memoryDir, file);
1157
1524
  const content = await readFileContent(filePath);
1158
1525
  if (content.trim()) {
1159
- const filename = basename2(file, ".md");
1526
+ const filename = (0, import_node_path15.basename)(file, ".md");
1160
1527
  const frontmatter = {
1161
1528
  root: false,
1162
1529
  targets: ["claudecode"],
@@ -1172,7 +1539,7 @@ async function parseClaudeMemoryFiles(memoryDir) {
1172
1539
  }
1173
1540
  }
1174
1541
  }
1175
- } catch (_error) {
1542
+ } catch {
1176
1543
  }
1177
1544
  return rules;
1178
1545
  }
@@ -1183,17 +1550,25 @@ async function parseClaudeSettings(settingsPath) {
1183
1550
  try {
1184
1551
  const content = await readFileContent(settingsPath);
1185
1552
  const settings = JSON.parse(content);
1186
- if (settings.permissions?.deny) {
1187
- const readPatterns = settings.permissions.deny.filter((rule) => rule.startsWith("Read(") && rule.endsWith(")")).map((rule) => {
1188
- const match = rule.match(/^Read\((.+)\)$/);
1189
- return match ? match[1] : null;
1190
- }).filter((pattern) => pattern !== null);
1191
- if (readPatterns.length > 0) {
1192
- ignorePatterns = readPatterns;
1553
+ if (typeof settings === "object" && settings !== null && "permissions" in settings) {
1554
+ const permissions = settings.permissions;
1555
+ if (permissions && "deny" in permissions && Array.isArray(permissions.deny)) {
1556
+ const readPatterns = permissions.deny.filter(
1557
+ (rule) => typeof rule === "string" && rule.startsWith("Read(") && rule.endsWith(")")
1558
+ ).map((rule) => {
1559
+ const match = rule.match(/^Read\((.+)\)$/);
1560
+ return match ? match[1] : null;
1561
+ }).filter((pattern) => pattern !== null);
1562
+ if (readPatterns.length > 0) {
1563
+ ignorePatterns = readPatterns;
1564
+ }
1193
1565
  }
1194
1566
  }
1195
- if (settings.mcpServers && Object.keys(settings.mcpServers).length > 0) {
1196
- mcpServers = settings.mcpServers;
1567
+ if (typeof settings === "object" && settings !== null && "mcpServers" in settings) {
1568
+ const servers = settings.mcpServers;
1569
+ if (servers && typeof servers === "object" && Object.keys(servers).length > 0) {
1570
+ mcpServers = servers;
1571
+ }
1197
1572
  }
1198
1573
  } catch (error) {
1199
1574
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -1207,11 +1582,11 @@ async function parseClaudeSettings(settingsPath) {
1207
1582
  }
1208
1583
 
1209
1584
  // src/parsers/cline.ts
1210
- import { join as join11 } from "path";
1585
+ var import_node_path16 = require("path");
1211
1586
  async function parseClineConfiguration(baseDir = process.cwd()) {
1212
1587
  const errors = [];
1213
1588
  const rules = [];
1214
- const clineFilePath = join11(baseDir, ".cline", "instructions.md");
1589
+ const clineFilePath = (0, import_node_path16.join)(baseDir, ".cline", "instructions.md");
1215
1590
  if (await fileExists(clineFilePath)) {
1216
1591
  try {
1217
1592
  const content = await readFileContent(clineFilePath);
@@ -1234,14 +1609,14 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1234
1609
  errors.push(`Failed to parse .cline/instructions.md: ${errorMessage}`);
1235
1610
  }
1236
1611
  }
1237
- const clinerulesDirPath = join11(baseDir, ".clinerules");
1612
+ const clinerulesDirPath = (0, import_node_path16.join)(baseDir, ".clinerules");
1238
1613
  if (await fileExists(clinerulesDirPath)) {
1239
1614
  try {
1240
1615
  const { readdir: readdir2 } = await import("fs/promises");
1241
1616
  const files = await readdir2(clinerulesDirPath);
1242
1617
  for (const file of files) {
1243
1618
  if (file.endsWith(".md")) {
1244
- const filePath = join11(clinerulesDirPath, file);
1619
+ const filePath = (0, import_node_path16.join)(clinerulesDirPath, file);
1245
1620
  try {
1246
1621
  const content = await readFileContent(filePath);
1247
1622
  if (content.trim()) {
@@ -1277,16 +1652,16 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1277
1652
  }
1278
1653
 
1279
1654
  // src/parsers/copilot.ts
1280
- import { basename as basename3, join as join12 } from "path";
1281
- import matter2 from "gray-matter";
1655
+ var import_node_path17 = require("path");
1656
+ var import_gray_matter2 = __toESM(require("gray-matter"), 1);
1282
1657
  async function parseCopilotConfiguration(baseDir = process.cwd()) {
1283
1658
  const errors = [];
1284
1659
  const rules = [];
1285
- const copilotFilePath = join12(baseDir, ".github", "copilot-instructions.md");
1660
+ const copilotFilePath = (0, import_node_path17.join)(baseDir, ".github", "copilot-instructions.md");
1286
1661
  if (await fileExists(copilotFilePath)) {
1287
1662
  try {
1288
1663
  const rawContent = await readFileContent(copilotFilePath);
1289
- const parsed = matter2(rawContent);
1664
+ const parsed = (0, import_gray_matter2.default)(rawContent);
1290
1665
  const content = parsed.content.trim();
1291
1666
  if (content) {
1292
1667
  const frontmatter = {
@@ -1307,19 +1682,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1307
1682
  errors.push(`Failed to parse copilot-instructions.md: ${errorMessage}`);
1308
1683
  }
1309
1684
  }
1310
- const instructionsDir = join12(baseDir, ".github", "instructions");
1685
+ const instructionsDir = (0, import_node_path17.join)(baseDir, ".github", "instructions");
1311
1686
  if (await fileExists(instructionsDir)) {
1312
1687
  try {
1313
1688
  const { readdir: readdir2 } = await import("fs/promises");
1314
1689
  const files = await readdir2(instructionsDir);
1315
1690
  for (const file of files) {
1316
1691
  if (file.endsWith(".instructions.md")) {
1317
- const filePath = join12(instructionsDir, file);
1692
+ const filePath = (0, import_node_path17.join)(instructionsDir, file);
1318
1693
  const rawContent = await readFileContent(filePath);
1319
- const parsed = matter2(rawContent);
1694
+ const parsed = (0, import_gray_matter2.default)(rawContent);
1320
1695
  const content = parsed.content.trim();
1321
1696
  if (content) {
1322
- const filename = basename3(file, ".instructions.md");
1697
+ const filename = (0, import_node_path17.basename)(file, ".instructions.md");
1323
1698
  const frontmatter = {
1324
1699
  root: false,
1325
1700
  targets: ["copilot"],
@@ -1349,19 +1724,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1349
1724
  }
1350
1725
 
1351
1726
  // src/parsers/cursor.ts
1352
- import { basename as basename4, join as join13 } from "path";
1353
- import matter3 from "gray-matter";
1354
- import yaml from "js-yaml";
1727
+ var import_node_path18 = require("path");
1728
+ var import_gray_matter3 = __toESM(require("gray-matter"), 1);
1729
+ var import_js_yaml = require("js-yaml");
1355
1730
  var customMatterOptions = {
1356
1731
  engines: {
1357
1732
  yaml: {
1358
1733
  parse: (str) => {
1359
1734
  try {
1360
1735
  const preprocessed = str.replace(/^(\s*globs:\s*)\*\s*$/gm, '$1"*"');
1361
- return yaml.load(preprocessed, { schema: yaml.DEFAULT_SCHEMA });
1736
+ return (0, import_js_yaml.load)(preprocessed, { schema: import_js_yaml.DEFAULT_SCHEMA });
1362
1737
  } catch (error) {
1363
1738
  try {
1364
- return yaml.load(str, { schema: yaml.FAILSAFE_SCHEMA });
1739
+ return (0, import_js_yaml.load)(str, { schema: import_js_yaml.FAILSAFE_SCHEMA });
1365
1740
  } catch {
1366
1741
  throw error;
1367
1742
  }
@@ -1375,11 +1750,11 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1375
1750
  const rules = [];
1376
1751
  let ignorePatterns;
1377
1752
  let mcpServers;
1378
- const cursorFilePath = join13(baseDir, ".cursorrules");
1753
+ const cursorFilePath = (0, import_node_path18.join)(baseDir, ".cursorrules");
1379
1754
  if (await fileExists(cursorFilePath)) {
1380
1755
  try {
1381
1756
  const rawContent = await readFileContent(cursorFilePath);
1382
- const parsed = matter3(rawContent, customMatterOptions);
1757
+ const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
1383
1758
  const content = parsed.content.trim();
1384
1759
  if (content) {
1385
1760
  const frontmatter = {
@@ -1400,20 +1775,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1400
1775
  errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
1401
1776
  }
1402
1777
  }
1403
- const cursorRulesDir = join13(baseDir, ".cursor", "rules");
1778
+ const cursorRulesDir = (0, import_node_path18.join)(baseDir, ".cursor", "rules");
1404
1779
  if (await fileExists(cursorRulesDir)) {
1405
1780
  try {
1406
1781
  const { readdir: readdir2 } = await import("fs/promises");
1407
1782
  const files = await readdir2(cursorRulesDir);
1408
1783
  for (const file of files) {
1409
1784
  if (file.endsWith(".mdc")) {
1410
- const filePath = join13(cursorRulesDir, file);
1785
+ const filePath = (0, import_node_path18.join)(cursorRulesDir, file);
1411
1786
  try {
1412
1787
  const rawContent = await readFileContent(filePath);
1413
- const parsed = matter3(rawContent, customMatterOptions);
1788
+ const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
1414
1789
  const content = parsed.content.trim();
1415
1790
  if (content) {
1416
- const filename = basename4(file, ".mdc");
1791
+ const filename = (0, import_node_path18.basename)(file, ".mdc");
1417
1792
  const frontmatter = {
1418
1793
  root: false,
1419
1794
  targets: ["cursor"],
@@ -1441,7 +1816,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1441
1816
  if (rules.length === 0) {
1442
1817
  errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
1443
1818
  }
1444
- const cursorIgnorePath = join13(baseDir, ".cursorignore");
1819
+ const cursorIgnorePath = (0, import_node_path18.join)(baseDir, ".cursorignore");
1445
1820
  if (await fileExists(cursorIgnorePath)) {
1446
1821
  try {
1447
1822
  const content = await readFileContent(cursorIgnorePath);
@@ -1454,7 +1829,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1454
1829
  errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
1455
1830
  }
1456
1831
  }
1457
- const cursorMcpPath = join13(baseDir, ".cursor", "mcp.json");
1832
+ const cursorMcpPath = (0, import_node_path18.join)(baseDir, ".cursor", "mcp.json");
1458
1833
  if (await fileExists(cursorMcpPath)) {
1459
1834
  try {
1460
1835
  const content = await readFileContent(cursorMcpPath);
@@ -1476,13 +1851,13 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1476
1851
  }
1477
1852
 
1478
1853
  // src/parsers/geminicli.ts
1479
- import { basename as basename5, join as join14 } from "path";
1854
+ var import_node_path19 = require("path");
1480
1855
  async function parseGeminiConfiguration(baseDir = process.cwd()) {
1481
1856
  const errors = [];
1482
1857
  const rules = [];
1483
1858
  let ignorePatterns;
1484
1859
  let mcpServers;
1485
- const geminiFilePath = join14(baseDir, "GEMINI.md");
1860
+ const geminiFilePath = (0, import_node_path19.join)(baseDir, "GEMINI.md");
1486
1861
  if (!await fileExists(geminiFilePath)) {
1487
1862
  errors.push("GEMINI.md file not found");
1488
1863
  return { rules, errors };
@@ -1493,12 +1868,12 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1493
1868
  if (mainRule) {
1494
1869
  rules.push(mainRule);
1495
1870
  }
1496
- const memoryDir = join14(baseDir, ".gemini", "memories");
1871
+ const memoryDir = (0, import_node_path19.join)(baseDir, ".gemini", "memories");
1497
1872
  if (await fileExists(memoryDir)) {
1498
1873
  const memoryRules = await parseGeminiMemoryFiles(memoryDir);
1499
1874
  rules.push(...memoryRules);
1500
1875
  }
1501
- const settingsPath = join14(baseDir, ".gemini", "settings.json");
1876
+ const settingsPath = (0, import_node_path19.join)(baseDir, ".gemini", "settings.json");
1502
1877
  if (await fileExists(settingsPath)) {
1503
1878
  const settingsResult = await parseGeminiSettings(settingsPath);
1504
1879
  if (settingsResult.ignorePatterns) {
@@ -1509,7 +1884,7 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1509
1884
  }
1510
1885
  errors.push(...settingsResult.errors);
1511
1886
  }
1512
- const aiexcludePath = join14(baseDir, ".aiexclude");
1887
+ const aiexcludePath = (0, import_node_path19.join)(baseDir, ".aiexclude");
1513
1888
  if (await fileExists(aiexcludePath)) {
1514
1889
  const aiexcludePatterns = await parseAiexclude(aiexcludePath);
1515
1890
  if (aiexcludePatterns.length > 0) {
@@ -1562,10 +1937,10 @@ async function parseGeminiMemoryFiles(memoryDir) {
1562
1937
  const files = await readdir2(memoryDir);
1563
1938
  for (const file of files) {
1564
1939
  if (file.endsWith(".md")) {
1565
- const filePath = join14(memoryDir, file);
1940
+ const filePath = (0, import_node_path19.join)(memoryDir, file);
1566
1941
  const content = await readFileContent(filePath);
1567
1942
  if (content.trim()) {
1568
- const filename = basename5(file, ".md");
1943
+ const filename = (0, import_node_path19.basename)(file, ".md");
1569
1944
  const frontmatter = {
1570
1945
  root: false,
1571
1946
  targets: ["geminicli"],
@@ -1581,7 +1956,7 @@ async function parseGeminiMemoryFiles(memoryDir) {
1581
1956
  }
1582
1957
  }
1583
1958
  }
1584
- } catch (_error) {
1959
+ } catch {
1585
1960
  }
1586
1961
  return rules;
1587
1962
  }
@@ -1608,17 +1983,17 @@ async function parseAiexclude(aiexcludePath) {
1608
1983
  const content = await readFileContent(aiexcludePath);
1609
1984
  const patterns = content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
1610
1985
  return patterns;
1611
- } catch (_error) {
1986
+ } catch {
1612
1987
  return [];
1613
1988
  }
1614
1989
  }
1615
1990
 
1616
1991
  // src/parsers/roo.ts
1617
- import { join as join15 } from "path";
1992
+ var import_node_path20 = require("path");
1618
1993
  async function parseRooConfiguration(baseDir = process.cwd()) {
1619
1994
  const errors = [];
1620
1995
  const rules = [];
1621
- const rooFilePath = join15(baseDir, ".roo", "instructions.md");
1996
+ const rooFilePath = (0, import_node_path20.join)(baseDir, ".roo", "instructions.md");
1622
1997
  if (await fileExists(rooFilePath)) {
1623
1998
  try {
1624
1999
  const content = await readFileContent(rooFilePath);
@@ -1641,14 +2016,14 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
1641
2016
  errors.push(`Failed to parse .roo/instructions.md: ${errorMessage}`);
1642
2017
  }
1643
2018
  }
1644
- const rooRulesDir = join15(baseDir, ".roo", "rules");
2019
+ const rooRulesDir = (0, import_node_path20.join)(baseDir, ".roo", "rules");
1645
2020
  if (await fileExists(rooRulesDir)) {
1646
2021
  try {
1647
2022
  const { readdir: readdir2 } = await import("fs/promises");
1648
2023
  const files = await readdir2(rooRulesDir);
1649
2024
  for (const file of files) {
1650
2025
  if (file.endsWith(".md")) {
1651
- const filePath = join15(rooRulesDir, file);
2026
+ const filePath = (0, import_node_path20.join)(rooRulesDir, file);
1652
2027
  try {
1653
2028
  const content = await readFileContent(filePath);
1654
2029
  if (content.trim()) {
@@ -1749,7 +2124,7 @@ async function importConfiguration(options) {
1749
2124
  if (rules.length === 0 && !ignorePatterns && !mcpServers) {
1750
2125
  return { success: false, rulesCreated: 0, errors };
1751
2126
  }
1752
- const rulesDirPath = join16(baseDir, rulesDir);
2127
+ const rulesDirPath = (0, import_node_path21.join)(baseDir, rulesDir);
1753
2128
  try {
1754
2129
  const { mkdir: mkdir3 } = await import("fs/promises");
1755
2130
  await mkdir3(rulesDirPath, { recursive: true });
@@ -1763,7 +2138,7 @@ async function importConfiguration(options) {
1763
2138
  try {
1764
2139
  const baseFilename = `${tool}__${rule.filename}`;
1765
2140
  const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
1766
- const filePath = join16(rulesDirPath, `${filename}.md`);
2141
+ const filePath = (0, import_node_path21.join)(rulesDirPath, `${filename}.md`);
1767
2142
  const content = generateRuleFileContent(rule);
1768
2143
  await writeFileContent(filePath, content);
1769
2144
  rulesCreated++;
@@ -1778,7 +2153,7 @@ async function importConfiguration(options) {
1778
2153
  let ignoreFileCreated = false;
1779
2154
  if (ignorePatterns && ignorePatterns.length > 0) {
1780
2155
  try {
1781
- const rulesyncignorePath = join16(baseDir, ".rulesyncignore");
2156
+ const rulesyncignorePath = (0, import_node_path21.join)(baseDir, ".rulesyncignore");
1782
2157
  const ignoreContent = `${ignorePatterns.join("\n")}
1783
2158
  `;
1784
2159
  await writeFileContent(rulesyncignorePath, ignoreContent);
@@ -1794,7 +2169,7 @@ async function importConfiguration(options) {
1794
2169
  let mcpFileCreated = false;
1795
2170
  if (mcpServers && Object.keys(mcpServers).length > 0) {
1796
2171
  try {
1797
- const mcpPath = join16(baseDir, rulesDir, ".mcp.json");
2172
+ const mcpPath = (0, import_node_path21.join)(baseDir, rulesDir, ".mcp.json");
1798
2173
  const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
1799
2174
  `;
1800
2175
  await writeFileContent(mcpPath, mcpContent);
@@ -1816,13 +2191,13 @@ async function importConfiguration(options) {
1816
2191
  };
1817
2192
  }
1818
2193
  function generateRuleFileContent(rule) {
1819
- const frontmatter = matter4.stringify("", rule.frontmatter);
2194
+ const frontmatter = import_gray_matter4.default.stringify("", rule.frontmatter);
1820
2195
  return frontmatter + rule.content;
1821
2196
  }
1822
2197
  async function generateUniqueFilename(rulesDir, baseFilename) {
1823
2198
  let filename = baseFilename;
1824
2199
  let counter = 1;
1825
- while (await fileExists(join16(rulesDir, `${filename}.md`))) {
2200
+ while (await fileExists((0, import_node_path21.join)(rulesDir, `${filename}.md`))) {
1826
2201
  filename = `${baseFilename}-${counter}`;
1827
2202
  counter++;
1828
2203
  }
@@ -1887,7 +2262,7 @@ async function importCommand(options = {}) {
1887
2262
  }
1888
2263
 
1889
2264
  // src/cli/commands/init.ts
1890
- import { join as join17 } from "path";
2265
+ var import_node_path22 = require("path");
1891
2266
  async function initCommand() {
1892
2267
  const aiRulesDir = ".rulesync";
1893
2268
  console.log("Initializing rulesync...");
@@ -2017,7 +2392,7 @@ globs: ["src/api/**/*.ts", "src/services/**/*.ts", "src/models/**/*.ts"]
2017
2392
  }
2018
2393
  ];
2019
2394
  for (const file of sampleFiles) {
2020
- const filepath = join17(aiRulesDir, file.filename);
2395
+ const filepath = (0, import_node_path22.join)(aiRulesDir, file.filename);
2021
2396
  if (!await fileExists(filepath)) {
2022
2397
  await writeFileContent(filepath, file.content);
2023
2398
  console.log(`Created ${filepath}`);
@@ -2119,13 +2494,13 @@ async function validateCommand() {
2119
2494
  }
2120
2495
 
2121
2496
  // src/cli/commands/watch.ts
2122
- import chokidar from "chokidar";
2497
+ var import_chokidar = require("chokidar");
2123
2498
  async function watchCommand() {
2124
2499
  const config = getDefaultConfig();
2125
2500
  console.log("\u{1F440} Watching for changes in .rulesync directory...");
2126
2501
  console.log("Press Ctrl+C to stop watching");
2127
2502
  await generateCommand({ verbose: false });
2128
- const watcher = chokidar.watch(`${config.aiRulesDir}/**/*.md`, {
2503
+ const watcher = (0, import_chokidar.watch)(`${config.aiRulesDir}/**/*.md`, {
2129
2504
  ignoreInitial: true,
2130
2505
  persistent: true
2131
2506
  });
@@ -2159,8 +2534,8 @@ async function watchCommand() {
2159
2534
  }
2160
2535
 
2161
2536
  // src/cli/index.ts
2162
- var program = new Command();
2163
- program.name("rulesync").description("Unified AI rules management CLI tool").version("0.36.0");
2537
+ var program = new import_commander.Command();
2538
+ program.name("rulesync").description("Unified AI rules management CLI tool").version("0.38.0");
2164
2539
  program.command("init").description("Initialize rulesync in current directory").action(initCommand);
2165
2540
  program.command("add <filename>").description("Add a new rule file").action(addCommand);
2166
2541
  program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);