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.
package/dist/index.js CHANGED
@@ -1,338 +1,30 @@
1
1
  #!/usr/bin/env node
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/generators/mcp/claude.ts
30
- function generateClaudeMcp(config, _target) {
31
- const claudeSettings = {
32
- mcpServers: {}
33
- };
34
- const shouldInclude = (server) => {
35
- if (!server.rulesyncTargets || server.rulesyncTargets.length === 0) {
36
- return true;
37
- }
38
- if (server.rulesyncTargets.length === 1 && server.rulesyncTargets[0] === "*") {
39
- return true;
40
- }
41
- return server.rulesyncTargets.includes("claude");
42
- };
43
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
44
- if (!shouldInclude(server)) continue;
45
- const claudeServer = {};
46
- if (server.command) {
47
- claudeServer.command = server.command;
48
- if (server.args) claudeServer.args = server.args;
49
- } else if (server.url || server.httpUrl) {
50
- const url = server.httpUrl || server.url;
51
- if (url) {
52
- claudeServer.url = url;
53
- }
54
- if (server.httpUrl) {
55
- claudeServer.transport = "http";
56
- } else if (server.transport === "sse") {
57
- claudeServer.transport = "sse";
58
- }
59
- }
60
- if (server.env) {
61
- claudeServer.env = server.env;
62
- }
63
- claudeSettings.mcpServers[serverName] = claudeServer;
64
- }
65
- return JSON.stringify(claudeSettings, null, 2);
66
- }
67
- var init_claude = __esm({
68
- "src/generators/mcp/claude.ts"() {
69
- "use strict";
70
- }
71
- });
72
-
73
- // src/generators/mcp/cline.ts
74
- function generateClineMcp(config, _target) {
75
- const clineConfig = {
76
- mcpServers: {}
77
- };
78
- const shouldInclude = (server) => {
79
- const targets = server.rulesyncTargets;
80
- if (!targets || targets.length === 0) return true;
81
- if (targets.length === 1 && targets[0] === "*") return true;
82
- return targets.includes("cline");
83
- };
84
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
85
- if (!shouldInclude(server)) continue;
86
- const clineServer = {};
87
- if (server.command) {
88
- clineServer.command = server.command;
89
- if (server.args) clineServer.args = server.args;
90
- } else if (server.url) {
91
- clineServer.url = server.url;
92
- }
93
- if (server.env) {
94
- clineServer.env = server.env;
95
- }
96
- if (server.disabled !== void 0) {
97
- clineServer.disabled = server.disabled;
98
- }
99
- if (server.alwaysAllow) {
100
- clineServer.alwaysAllow = server.alwaysAllow;
101
- }
102
- if (server.networkTimeout !== void 0) {
103
- clineServer.networkTimeout = server.networkTimeout;
104
- }
105
- clineConfig.mcpServers[serverName] = clineServer;
106
- }
107
- return JSON.stringify(clineConfig, null, 2);
108
- }
109
- var init_cline = __esm({
110
- "src/generators/mcp/cline.ts"() {
111
- "use strict";
112
- }
113
- });
114
-
115
- // src/generators/mcp/copilot.ts
116
- function generateCopilotMcp(config, target) {
117
- const shouldInclude = (server) => {
118
- const targets = server.rulesyncTargets;
119
- if (!targets || targets.length === 0) return true;
120
- if (targets.length === 1 && targets[0] === "*") return true;
121
- return targets.includes("copilot");
122
- };
123
- const servers = {};
124
- const inputs = [];
125
- const inputMap = /* @__PURE__ */ new Map();
126
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
127
- if (!shouldInclude(server)) continue;
128
- const copilotServer = {};
129
- if (server.command) {
130
- copilotServer.command = server.command;
131
- if (server.args) copilotServer.args = server.args;
132
- } else if (server.url || server.httpUrl) {
133
- const url = server.httpUrl || server.url;
134
- if (url) {
135
- copilotServer.url = url;
136
- }
137
- }
138
- if (server.env) {
139
- copilotServer.env = {};
140
- for (const [key, value] of Object.entries(server.env)) {
141
- if (target === "editor" && value.includes("SECRET")) {
142
- const inputId = `${serverName}_${key}`;
143
- inputMap.set(inputId, value);
144
- copilotServer.env[key] = `\${input:${inputId}}`;
145
- inputs.push({
146
- id: inputId,
147
- type: "password",
148
- description: `${key} for ${serverName}`
149
- });
150
- } else {
151
- copilotServer.env[key] = value;
152
- }
153
- }
154
- }
155
- if (server.tools) {
156
- copilotServer.tools = server.tools;
157
- } else if (server.alwaysAllow) {
158
- copilotServer.tools = server.alwaysAllow;
159
- }
160
- servers[serverName] = copilotServer;
161
- }
162
- if (target === "codingAgent") {
163
- const config2 = { mcpServers: servers };
164
- return JSON.stringify(config2, null, 2);
165
- } else {
166
- const config2 = { servers };
167
- if (inputs.length > 0) {
168
- config2.inputs = inputs;
169
- }
170
- return JSON.stringify(config2, null, 2);
171
- }
172
- }
173
- var init_copilot = __esm({
174
- "src/generators/mcp/copilot.ts"() {
175
- "use strict";
176
- }
177
- });
178
-
179
- // src/generators/mcp/cursor.ts
180
- function generateCursorMcp(config, _target) {
181
- const cursorConfig = {
182
- mcpServers: {}
183
- };
184
- const shouldInclude = (server) => {
185
- const targets = server.rulesyncTargets;
186
- if (!targets || targets.length === 0) return true;
187
- if (targets.length === 1 && targets[0] === "*") return true;
188
- return targets.includes("cursor");
189
- };
190
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
191
- if (!shouldInclude(server)) continue;
192
- const cursorServer = {};
193
- if (server.command) {
194
- cursorServer.command = server.command;
195
- if (server.args) cursorServer.args = server.args;
196
- } else if (server.url || server.httpUrl) {
197
- const url = server.httpUrl || server.url;
198
- if (url) {
199
- cursorServer.url = url;
200
- }
201
- if (server.httpUrl || server.transport === "http") {
202
- cursorServer.type = "streamable-http";
203
- } else if (server.transport === "sse" || server.type === "sse") {
204
- cursorServer.type = "sse";
205
- }
206
- }
207
- if (server.env) {
208
- cursorServer.env = server.env;
209
- }
210
- if (server.cwd) {
211
- cursorServer.cwd = server.cwd;
212
- }
213
- cursorConfig.mcpServers[serverName] = cursorServer;
214
- }
215
- return JSON.stringify(cursorConfig, null, 2);
216
- }
217
- var init_cursor = __esm({
218
- "src/generators/mcp/cursor.ts"() {
219
- "use strict";
220
- }
221
- });
222
-
223
- // src/generators/mcp/geminicli.ts
224
- function generateGeminiCliMcp(config, _target) {
225
- const geminiSettings = {
226
- mcpServers: {}
227
- };
228
- const shouldInclude = (server) => {
229
- const targets = server.rulesyncTargets;
230
- if (!targets || targets.length === 0) return true;
231
- if (targets.length === 1 && targets[0] === "*") return true;
232
- return targets.includes("geminicli");
233
- };
234
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
235
- if (!shouldInclude(server)) continue;
236
- const geminiServer = {};
237
- if (server.command) {
238
- geminiServer.command = server.command;
239
- if (server.args) geminiServer.args = server.args;
240
- } else if (server.url || server.httpUrl) {
241
- if (server.httpUrl) {
242
- geminiServer.httpUrl = server.httpUrl;
243
- } else if (server.url) {
244
- geminiServer.url = server.url;
245
- }
246
- }
247
- if (server.env) {
248
- geminiServer.env = {};
249
- for (const [key, value] of Object.entries(server.env)) {
250
- if (value.startsWith("${") && value.endsWith("}")) {
251
- geminiServer.env[key] = value;
252
- } else {
253
- geminiServer.env[key] = `\${${value}}`;
254
- }
255
- }
256
- }
257
- if (server.timeout !== void 0) {
258
- geminiServer.timeout = server.timeout;
259
- }
260
- if (server.trust !== void 0) {
261
- geminiServer.trust = server.trust;
262
- }
263
- geminiSettings.mcpServers[serverName] = geminiServer;
264
- }
265
- return JSON.stringify(geminiSettings, null, 2);
266
- }
267
- var init_geminicli = __esm({
268
- "src/generators/mcp/geminicli.ts"() {
269
- "use strict";
270
- }
271
- });
272
-
273
- // src/generators/mcp/roo.ts
274
- function generateRooMcp(config, _target) {
275
- const rooConfig = {
276
- mcpServers: {}
277
- };
278
- const shouldInclude = (server) => {
279
- const targets = server.rulesyncTargets;
280
- if (!targets || targets.length === 0) return true;
281
- if (targets.length === 1 && targets[0] === "*") return true;
282
- return targets.includes("roo");
283
- };
284
- for (const [serverName, server] of Object.entries(config.mcpServers)) {
285
- if (!shouldInclude(server)) continue;
286
- const rooServer = {};
287
- if (server.command) {
288
- rooServer.command = server.command;
289
- if (server.args) rooServer.args = server.args;
290
- } else if (server.url || server.httpUrl) {
291
- const url = server.httpUrl || server.url;
292
- if (url) {
293
- rooServer.url = url;
294
- }
295
- if (server.httpUrl || server.transport === "http") {
296
- rooServer.type = "streamable-http";
297
- } else if (server.transport === "sse" || server.type === "sse") {
298
- rooServer.type = "sse";
299
- }
300
- }
301
- if (server.env) {
302
- rooServer.env = {};
303
- for (const [key, value] of Object.entries(server.env)) {
304
- if (value.startsWith("${env:") && value.endsWith("}")) {
305
- rooServer.env[key] = value;
306
- } else {
307
- rooServer.env[key] = `\${env:${value}}`;
308
- }
309
- }
310
- }
311
- if (server.disabled !== void 0) {
312
- rooServer.disabled = server.disabled;
313
- }
314
- if (server.alwaysAllow) {
315
- rooServer.alwaysAllow = server.alwaysAllow;
316
- }
317
- if (server.networkTimeout !== void 0) {
318
- rooServer.networkTimeout = Math.max(3e4, Math.min(3e5, server.networkTimeout));
319
- }
320
- rooConfig.mcpServers[serverName] = rooServer;
321
- }
322
- return JSON.stringify(rooConfig, null, 2);
323
- }
324
- var init_roo = __esm({
325
- "src/generators/mcp/roo.ts"() {
326
- "use strict";
327
- }
328
- });
2
+ import {
3
+ generateClaudeMcp
4
+ } from "./chunk-LQDXGEGC.js";
5
+ import {
6
+ generateClineMcp
7
+ } from "./chunk-XERXHVPP.js";
8
+ import {
9
+ generateCopilotMcp
10
+ } from "./chunk-BEJD7I74.js";
11
+ import {
12
+ generateCursorMcp
13
+ } from "./chunk-VZMUQVX4.js";
14
+ import {
15
+ generateGeminiCliMcp
16
+ } from "./chunk-HOVR7QDA.js";
17
+ import {
18
+ generateRooMcp
19
+ } from "./chunk-SPMMXF7R.js";
20
+ import "./chunk-AWKMUY5R.js";
329
21
 
330
22
  // src/cli/index.ts
331
- var import_commander = require("commander");
23
+ import { Command } from "commander";
332
24
 
333
25
  // src/cli/commands/add.ts
334
- var import_promises = require("fs/promises");
335
- var import_node_path = __toESM(require("path"));
26
+ import { mkdir, writeFile } from "fs/promises";
27
+ import path from "path";
336
28
 
337
29
  // src/utils/config.ts
338
30
  function getDefaultConfig() {
@@ -380,10 +72,10 @@ async function addCommand(filename) {
380
72
  const config = getDefaultConfig();
381
73
  const sanitizedFilename = sanitizeFilename(filename);
382
74
  const rulesDir = config.aiRulesDir;
383
- const filePath = import_node_path.default.join(rulesDir, `${sanitizedFilename}.md`);
384
- await (0, import_promises.mkdir)(rulesDir, { recursive: true });
75
+ const filePath = path.join(rulesDir, `${sanitizedFilename}.md`);
76
+ await mkdir(rulesDir, { recursive: true });
385
77
  const template = generateRuleTemplate(sanitizedFilename);
386
- await (0, import_promises.writeFile)(filePath, template, "utf8");
78
+ await writeFile(filePath, template, "utf8");
387
79
  console.log(`\u2705 Created rule file: ${filePath}`);
388
80
  console.log(`\u{1F4DD} Edit the file to customize your rules.`);
389
81
  } catch (error) {
@@ -395,21 +87,47 @@ async function addCommand(filename) {
395
87
  }
396
88
 
397
89
  // src/generators/rules/claudecode.ts
398
- var import_node_path4 = require("path");
90
+ import { join as join3 } from "path";
399
91
 
400
92
  // src/utils/file.ts
401
- var import_promises2 = require("fs/promises");
402
- var import_node_path3 = require("path");
93
+ import { readdir, rm } from "fs/promises";
94
+ import { join as join2 } from "path";
95
+
96
+ // src/utils/file-ops.ts
97
+ import { mkdir as mkdir2, readFile, stat, writeFile as writeFile2 } from "fs/promises";
98
+ import { dirname } from "path";
99
+ async function ensureDir(dirPath) {
100
+ try {
101
+ await stat(dirPath);
102
+ } catch {
103
+ await mkdir2(dirPath, { recursive: true });
104
+ }
105
+ }
106
+ async function readFileContent(filepath) {
107
+ return readFile(filepath, "utf-8");
108
+ }
109
+ async function writeFileContent(filepath, content) {
110
+ await ensureDir(dirname(filepath));
111
+ await writeFile2(filepath, content, "utf-8");
112
+ }
113
+ async function fileExists(filepath) {
114
+ try {
115
+ await stat(filepath);
116
+ return true;
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
403
121
 
404
122
  // src/utils/ignore.ts
405
- var import_node_path2 = require("path");
406
- var import_micromatch = __toESM(require("micromatch"));
123
+ import { join } from "path";
124
+ import micromatch from "micromatch";
407
125
  var cachedIgnorePatterns = null;
408
126
  async function loadIgnorePatterns(baseDir = process.cwd()) {
409
127
  if (cachedIgnorePatterns) {
410
128
  return cachedIgnorePatterns;
411
129
  }
412
- const ignorePath = (0, import_node_path2.join)(baseDir, ".rulesyncignore");
130
+ const ignorePath = join(baseDir, ".rulesyncignore");
413
131
  if (!await fileExists(ignorePath)) {
414
132
  cachedIgnorePatterns = { patterns: [] };
415
133
  return cachedIgnorePatterns;
@@ -434,12 +152,12 @@ function isFileIgnored(filepath, ignorePatterns) {
434
152
  }
435
153
  const negationPatterns = ignorePatterns.filter((p) => p.startsWith("!"));
436
154
  const positivePatterns = ignorePatterns.filter((p) => !p.startsWith("!"));
437
- const isIgnored = positivePatterns.length > 0 && import_micromatch.default.isMatch(filepath, positivePatterns, {
155
+ const isIgnored = positivePatterns.length > 0 && micromatch.isMatch(filepath, positivePatterns, {
438
156
  dot: true
439
157
  });
440
158
  if (isIgnored && negationPatterns.length > 0) {
441
159
  const negationPatternsWithoutPrefix = negationPatterns.map((p) => p.substring(1));
442
- return !import_micromatch.default.isMatch(filepath, negationPatternsWithoutPrefix, {
160
+ return !micromatch.isMatch(filepath, negationPatternsWithoutPrefix, {
443
161
  dot: true
444
162
  });
445
163
  }
@@ -453,24 +171,10 @@ function filterIgnoredFiles(files, ignorePatterns) {
453
171
  }
454
172
 
455
173
  // src/utils/file.ts
456
- async function ensureDir(dirPath) {
457
- try {
458
- await (0, import_promises2.stat)(dirPath);
459
- } catch {
460
- await (0, import_promises2.mkdir)(dirPath, { recursive: true });
461
- }
462
- }
463
- async function readFileContent(filepath) {
464
- return (0, import_promises2.readFile)(filepath, "utf-8");
465
- }
466
- async function writeFileContent(filepath, content) {
467
- await ensureDir((0, import_node_path3.dirname)(filepath));
468
- await (0, import_promises2.writeFile)(filepath, content, "utf-8");
469
- }
470
174
  async function findFiles(dir, extension = ".md", ignorePatterns) {
471
175
  try {
472
- const files = await (0, import_promises2.readdir)(dir);
473
- const filtered = files.filter((file) => file.endsWith(extension)).map((file) => (0, import_node_path3.join)(dir, file));
176
+ const files = await readdir(dir);
177
+ const filtered = files.filter((file) => file.endsWith(extension)).map((file) => join2(dir, file));
474
178
  if (ignorePatterns && ignorePatterns.length > 0) {
475
179
  return filterIgnoredFiles(filtered, ignorePatterns);
476
180
  }
@@ -479,14 +183,6 @@ async function findFiles(dir, extension = ".md", ignorePatterns) {
479
183
  return [];
480
184
  }
481
185
  }
482
- async function fileExists(filepath) {
483
- try {
484
- await (0, import_promises2.stat)(filepath);
485
- return true;
486
- } catch {
487
- return false;
488
- }
489
- }
490
186
  async function removeDirectory(dirPath) {
491
187
  const dangerousPaths = [".", "/", "~", "src", "node_modules"];
492
188
  if (dangerousPaths.includes(dirPath) || dirPath === "") {
@@ -495,7 +191,7 @@ async function removeDirectory(dirPath) {
495
191
  }
496
192
  try {
497
193
  if (await fileExists(dirPath)) {
498
- await (0, import_promises2.rm)(dirPath, { recursive: true, force: true });
194
+ await rm(dirPath, { recursive: true, force: true });
499
195
  }
500
196
  } catch (error) {
501
197
  console.warn(`Failed to remove directory ${dirPath}:`, error);
@@ -504,7 +200,7 @@ async function removeDirectory(dirPath) {
504
200
  async function removeFile(filepath) {
505
201
  try {
506
202
  if (await fileExists(filepath)) {
507
- await (0, import_promises2.rm)(filepath);
203
+ await rm(filepath);
508
204
  }
509
205
  } catch (error) {
510
206
  console.warn(`Failed to remove file ${filepath}:`, error);
@@ -527,23 +223,23 @@ async function generateClaudecodeConfig(rules, config, baseDir) {
527
223
  const rootRules = rules.filter((r) => r.frontmatter.root === true);
528
224
  const detailRules = rules.filter((r) => r.frontmatter.root === false);
529
225
  const claudeMdContent = generateClaudeMarkdown(rootRules, detailRules);
530
- const claudeOutputDir = baseDir ? (0, import_node_path4.join)(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
226
+ const claudeOutputDir = baseDir ? join3(baseDir, config.outputPaths.claudecode) : config.outputPaths.claudecode;
531
227
  outputs.push({
532
228
  tool: "claudecode",
533
- filepath: (0, import_node_path4.join)(claudeOutputDir, "CLAUDE.md"),
229
+ filepath: join3(claudeOutputDir, "CLAUDE.md"),
534
230
  content: claudeMdContent
535
231
  });
536
232
  for (const rule of detailRules) {
537
233
  const memoryContent = generateMemoryFile(rule);
538
234
  outputs.push({
539
235
  tool: "claudecode",
540
- filepath: (0, import_node_path4.join)(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
236
+ filepath: join3(claudeOutputDir, ".claude", "memories", `${rule.filename}.md`),
541
237
  content: memoryContent
542
238
  });
543
239
  }
544
240
  const ignorePatterns = await loadIgnorePatterns(baseDir);
545
241
  if (ignorePatterns.patterns.length > 0) {
546
- const settingsPath = baseDir ? (0, import_node_path4.join)(baseDir, ".claude", "settings.json") : (0, import_node_path4.join)(".claude", "settings.json");
242
+ const settingsPath = baseDir ? join3(baseDir, ".claude", "settings.json") : join3(".claude", "settings.json");
547
243
  await updateClaudeSettings(settingsPath, ignorePatterns.patterns);
548
244
  }
549
245
  return outputs;
@@ -580,39 +276,46 @@ async function updateClaudeSettings(settingsPath, ignorePatterns) {
580
276
  try {
581
277
  const content = await readFileContent(settingsPath);
582
278
  settings = JSON.parse(content);
583
- } catch (_error) {
279
+ } catch {
584
280
  console.warn(`Failed to parse existing ${settingsPath}, creating new settings`);
585
281
  settings = {};
586
282
  }
587
283
  }
588
- if (!settings.permissions) {
589
- settings.permissions = {};
284
+ if (typeof settings !== "object" || settings === null) {
285
+ settings = {};
590
286
  }
591
- if (!Array.isArray(settings.permissions.deny)) {
592
- settings.permissions.deny = [];
287
+ const settingsObj = settings;
288
+ if (!settingsObj.permissions || typeof settingsObj.permissions !== "object" || settingsObj.permissions === null) {
289
+ settingsObj.permissions = {};
290
+ }
291
+ const permissions = settingsObj.permissions;
292
+ if (!Array.isArray(permissions.deny)) {
293
+ permissions.deny = [];
593
294
  }
594
295
  const readDenyRules = ignorePatterns.map((pattern) => `Read(${pattern})`);
595
- settings.permissions.deny = settings.permissions.deny.filter((rule) => {
296
+ const denyArray = permissions.deny;
297
+ const filteredDeny = denyArray.filter((rule) => {
298
+ if (typeof rule !== "string") return false;
596
299
  if (!rule.startsWith("Read(")) return true;
597
300
  const match = rule.match(/^Read\((.*)\)$/);
598
301
  if (!match) return true;
599
302
  return !ignorePatterns.includes(match[1] ?? "");
600
303
  });
601
- settings.permissions.deny.push(...readDenyRules);
602
- settings.permissions.deny = [...new Set(settings.permissions.deny)];
603
- const jsonContent = JSON.stringify(settings, null, 2);
304
+ filteredDeny.push(...readDenyRules);
305
+ permissions.deny = [...new Set(filteredDeny)];
306
+ const jsonContent = JSON.stringify(settingsObj, null, 2);
604
307
  await writeFileContent(settingsPath, jsonContent);
605
308
  console.log(`\u2705 Updated Claude Code settings: ${settingsPath}`);
606
309
  }
607
310
 
608
311
  // src/generators/rules/cline.ts
609
- var import_node_path5 = require("path");
312
+ import { join as join4 } from "path";
610
313
  async function generateClineConfig(rules, config, baseDir) {
611
314
  const outputs = [];
612
315
  for (const rule of rules) {
613
316
  const content = generateClineMarkdown(rule);
614
- const outputDir = baseDir ? (0, import_node_path5.join)(baseDir, config.outputPaths.cline) : config.outputPaths.cline;
615
- const filepath = (0, import_node_path5.join)(outputDir, `${rule.filename}.md`);
317
+ const outputDir = baseDir ? join4(baseDir, config.outputPaths.cline) : config.outputPaths.cline;
318
+ const filepath = join4(outputDir, `${rule.filename}.md`);
616
319
  outputs.push({
617
320
  tool: "cline",
618
321
  filepath,
@@ -621,7 +324,7 @@ async function generateClineConfig(rules, config, baseDir) {
621
324
  }
622
325
  const ignorePatterns = await loadIgnorePatterns(baseDir);
623
326
  if (ignorePatterns.patterns.length > 0) {
624
- const clineIgnorePath = baseDir ? (0, import_node_path5.join)(baseDir, ".clineignore") : ".clineignore";
327
+ const clineIgnorePath = baseDir ? join4(baseDir, ".clineignore") : ".clineignore";
625
328
  const clineIgnoreContent = generateClineIgnore(ignorePatterns.patterns);
626
329
  outputs.push({
627
330
  tool: "cline",
@@ -645,14 +348,14 @@ function generateClineIgnore(patterns) {
645
348
  }
646
349
 
647
350
  // src/generators/rules/copilot.ts
648
- var import_node_path6 = require("path");
351
+ import { join as join5 } from "path";
649
352
  async function generateCopilotConfig(rules, config, baseDir) {
650
353
  const outputs = [];
651
354
  for (const rule of rules) {
652
355
  const content = generateCopilotMarkdown(rule);
653
356
  const baseFilename = rule.filename.replace(/\.md$/, "");
654
- const outputDir = baseDir ? (0, import_node_path6.join)(baseDir, config.outputPaths.copilot) : config.outputPaths.copilot;
655
- const filepath = (0, import_node_path6.join)(outputDir, `${baseFilename}.instructions.md`);
357
+ const outputDir = baseDir ? join5(baseDir, config.outputPaths.copilot) : config.outputPaths.copilot;
358
+ const filepath = join5(outputDir, `${baseFilename}.instructions.md`);
656
359
  outputs.push({
657
360
  tool: "copilot",
658
361
  filepath,
@@ -661,7 +364,7 @@ async function generateCopilotConfig(rules, config, baseDir) {
661
364
  }
662
365
  const ignorePatterns = await loadIgnorePatterns(baseDir);
663
366
  if (ignorePatterns.patterns.length > 0) {
664
- const copilotIgnorePath = baseDir ? (0, import_node_path6.join)(baseDir, ".copilotignore") : ".copilotignore";
367
+ const copilotIgnorePath = baseDir ? join5(baseDir, ".copilotignore") : ".copilotignore";
665
368
  const copilotIgnoreContent = generateCopilotIgnore(ignorePatterns.patterns);
666
369
  outputs.push({
667
370
  tool: "copilot",
@@ -697,13 +400,13 @@ function generateCopilotIgnore(patterns) {
697
400
  }
698
401
 
699
402
  // src/generators/rules/cursor.ts
700
- var import_node_path7 = require("path");
403
+ import { join as join6 } from "path";
701
404
  async function generateCursorConfig(rules, config, baseDir) {
702
405
  const outputs = [];
703
406
  for (const rule of rules) {
704
407
  const content = generateCursorMarkdown(rule);
705
- const outputDir = baseDir ? (0, import_node_path7.join)(baseDir, config.outputPaths.cursor) : config.outputPaths.cursor;
706
- const filepath = (0, import_node_path7.join)(outputDir, `${rule.filename}.mdc`);
408
+ const outputDir = baseDir ? join6(baseDir, config.outputPaths.cursor) : config.outputPaths.cursor;
409
+ const filepath = join6(outputDir, `${rule.filename}.mdc`);
707
410
  outputs.push({
708
411
  tool: "cursor",
709
412
  filepath,
@@ -712,7 +415,7 @@ async function generateCursorConfig(rules, config, baseDir) {
712
415
  }
713
416
  const ignorePatterns = await loadIgnorePatterns(baseDir);
714
417
  if (ignorePatterns.patterns.length > 0) {
715
- const cursorIgnorePath = baseDir ? (0, import_node_path7.join)(baseDir, ".cursorignore") : ".cursorignore";
418
+ const cursorIgnorePath = baseDir ? join6(baseDir, ".cursorignore") : ".cursorignore";
716
419
  const cursorIgnoreContent = generateCursorIgnore(ignorePatterns.patterns);
717
420
  outputs.push({
718
421
  tool: "cursor",
@@ -753,15 +456,15 @@ function generateCursorIgnore(patterns) {
753
456
  }
754
457
 
755
458
  // src/generators/rules/geminicli.ts
756
- var import_node_path8 = require("path");
459
+ import { join as join7 } from "path";
757
460
  async function generateGeminiConfig(rules, config, baseDir) {
758
461
  const outputs = [];
759
462
  const rootRule = rules.find((rule) => rule.frontmatter.root === true);
760
463
  const memoryRules = rules.filter((rule) => rule.frontmatter.root === false);
761
464
  for (const rule of memoryRules) {
762
465
  const content = generateGeminiMemoryMarkdown(rule);
763
- const outputDir = baseDir ? (0, import_node_path8.join)(baseDir, config.outputPaths.geminicli) : config.outputPaths.geminicli;
764
- const filepath = (0, import_node_path8.join)(outputDir, `${rule.filename}.md`);
466
+ const outputDir = baseDir ? join7(baseDir, config.outputPaths.geminicli) : config.outputPaths.geminicli;
467
+ const filepath = join7(outputDir, `${rule.filename}.md`);
765
468
  outputs.push({
766
469
  tool: "geminicli",
767
470
  filepath,
@@ -769,7 +472,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
769
472
  });
770
473
  }
771
474
  const rootContent = generateGeminiRootMarkdown(rootRule, memoryRules, baseDir);
772
- const rootFilepath = baseDir ? (0, import_node_path8.join)(baseDir, "GEMINI.md") : "GEMINI.md";
475
+ const rootFilepath = baseDir ? join7(baseDir, "GEMINI.md") : "GEMINI.md";
773
476
  outputs.push({
774
477
  tool: "geminicli",
775
478
  filepath: rootFilepath,
@@ -777,7 +480,7 @@ async function generateGeminiConfig(rules, config, baseDir) {
777
480
  });
778
481
  const ignorePatterns = await loadIgnorePatterns(baseDir);
779
482
  if (ignorePatterns.patterns.length > 0) {
780
- const aiexcludePath = baseDir ? (0, import_node_path8.join)(baseDir, ".aiexclude") : ".aiexclude";
483
+ const aiexcludePath = baseDir ? join7(baseDir, ".aiexclude") : ".aiexclude";
781
484
  const aiexcludeContent = generateAiexclude(ignorePatterns.patterns);
782
485
  outputs.push({
783
486
  tool: "geminicli",
@@ -825,13 +528,13 @@ function generateAiexclude(patterns) {
825
528
  }
826
529
 
827
530
  // src/generators/rules/roo.ts
828
- var import_node_path9 = require("path");
531
+ import { join as join8 } from "path";
829
532
  async function generateRooConfig(rules, config, baseDir) {
830
533
  const outputs = [];
831
534
  for (const rule of rules) {
832
535
  const content = generateRooMarkdown(rule);
833
- const outputDir = baseDir ? (0, import_node_path9.join)(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
834
- const filepath = (0, import_node_path9.join)(outputDir, `${rule.filename}.md`);
536
+ const outputDir = baseDir ? join8(baseDir, config.outputPaths.roo) : config.outputPaths.roo;
537
+ const filepath = join8(outputDir, `${rule.filename}.md`);
835
538
  outputs.push({
836
539
  tool: "roo",
837
540
  filepath,
@@ -840,7 +543,7 @@ async function generateRooConfig(rules, config, baseDir) {
840
543
  }
841
544
  const ignorePatterns = await loadIgnorePatterns(baseDir);
842
545
  if (ignorePatterns.patterns.length > 0) {
843
- const rooIgnorePath = baseDir ? (0, import_node_path9.join)(baseDir, ".rooignore") : ".rooignore";
546
+ const rooIgnorePath = baseDir ? join8(baseDir, ".rooignore") : ".rooignore";
844
547
  const rooIgnoreContent = generateRooIgnore(ignorePatterns.patterns);
845
548
  outputs.push({
846
549
  tool: "roo",
@@ -913,8 +616,8 @@ async function generateForTool(tool, rules, config, baseDir) {
913
616
  }
914
617
 
915
618
  // src/core/parser.ts
916
- var import_node_path10 = require("path");
917
- var import_gray_matter = __toESM(require("gray-matter"));
619
+ import { basename } from "path";
620
+ import matter from "gray-matter";
918
621
  async function parseRulesFromDirectory(aiRulesDir) {
919
622
  const ignorePatterns = await loadIgnorePatterns();
920
623
  const ruleFiles = await findFiles(aiRulesDir, ".md", ignorePatterns.patterns);
@@ -947,10 +650,10 @@ ${errors.join("\n")}`);
947
650
  }
948
651
  async function parseRuleFile(filepath) {
949
652
  const content = await readFileContent(filepath);
950
- const parsed = (0, import_gray_matter.default)(content);
653
+ const parsed = matter(content);
951
654
  validateFrontmatter(parsed.data, filepath);
952
655
  const frontmatter = parsed.data;
953
- const filename = (0, import_node_path10.basename)(filepath, ".md");
656
+ const filename = basename(filepath, ".md");
954
657
  return {
955
658
  frontmatter,
956
659
  content: parsed.content,
@@ -1079,27 +782,19 @@ async function validateRule(rule) {
1079
782
  }
1080
783
 
1081
784
  // src/core/mcp-generator.ts
1082
- var import_node_os = __toESM(require("os"));
1083
- var import_node_path12 = __toESM(require("path"));
1084
-
1085
- // src/generators/mcp/index.ts
1086
- init_claude();
1087
- init_cline();
1088
- init_copilot();
1089
- init_cursor();
1090
- init_geminicli();
1091
- init_roo();
785
+ import os from "os";
786
+ import path3 from "path";
1092
787
 
1093
788
  // src/core/mcp-parser.ts
1094
- var import_node_fs = __toESM(require("fs"));
1095
- var import_node_path11 = __toESM(require("path"));
789
+ import fs from "fs";
790
+ import path2 from "path";
1096
791
  function parseMcpConfig(projectRoot) {
1097
- const mcpPath = import_node_path11.default.join(projectRoot, ".rulesync", ".mcp.json");
1098
- if (!import_node_fs.default.existsSync(mcpPath)) {
792
+ const mcpPath = path2.join(projectRoot, ".rulesync", ".mcp.json");
793
+ if (!fs.existsSync(mcpPath)) {
1099
794
  return null;
1100
795
  }
1101
796
  try {
1102
- const content = import_node_fs.default.readFileSync(mcpPath, "utf-8");
797
+ const content = fs.readFileSync(mcpPath, "utf-8");
1103
798
  const rawConfig = JSON.parse(content);
1104
799
  if (rawConfig.servers && !rawConfig.mcpServers) {
1105
800
  rawConfig.mcpServers = rawConfig.servers;
@@ -1130,32 +825,32 @@ async function generateMcpConfigs(projectRoot, baseDir) {
1130
825
  const generators = [
1131
826
  {
1132
827
  tool: "claude-project",
1133
- path: import_node_path12.default.join(targetRoot, ".mcp.json"),
828
+ path: path3.join(targetRoot, ".mcp.json"),
1134
829
  generate: () => generateClaudeMcp(config, "project")
1135
830
  },
1136
831
  {
1137
832
  tool: "copilot-editor",
1138
- path: import_node_path12.default.join(targetRoot, ".vscode", "mcp.json"),
833
+ path: path3.join(targetRoot, ".vscode", "mcp.json"),
1139
834
  generate: () => generateCopilotMcp(config, "editor")
1140
835
  },
1141
836
  {
1142
837
  tool: "cursor-project",
1143
- path: import_node_path12.default.join(targetRoot, ".cursor", "mcp.json"),
838
+ path: path3.join(targetRoot, ".cursor", "mcp.json"),
1144
839
  generate: () => generateCursorMcp(config, "project")
1145
840
  },
1146
841
  {
1147
842
  tool: "cline-project",
1148
- path: import_node_path12.default.join(targetRoot, ".cline", "mcp.json"),
843
+ path: path3.join(targetRoot, ".cline", "mcp.json"),
1149
844
  generate: () => generateClineMcp(config, "project")
1150
845
  },
1151
846
  {
1152
847
  tool: "gemini-project",
1153
- path: import_node_path12.default.join(targetRoot, ".gemini", "settings.json"),
848
+ path: path3.join(targetRoot, ".gemini", "settings.json"),
1154
849
  generate: () => generateGeminiCliMcp(config, "project")
1155
850
  },
1156
851
  {
1157
852
  tool: "roo-project",
1158
- path: import_node_path12.default.join(targetRoot, ".roo", "mcp.json"),
853
+ path: path3.join(targetRoot, ".roo", "mcp.json"),
1159
854
  generate: () => generateRooMcp(config, "project")
1160
855
  }
1161
856
  ];
@@ -1163,17 +858,17 @@ async function generateMcpConfigs(projectRoot, baseDir) {
1163
858
  generators.push(
1164
859
  {
1165
860
  tool: "claude-global",
1166
- path: import_node_path12.default.join(import_node_os.default.homedir(), ".claude", "settings.json"),
861
+ path: path3.join(os.homedir(), ".claude", "settings.json"),
1167
862
  generate: () => generateClaudeMcp(config, "global")
1168
863
  },
1169
864
  {
1170
865
  tool: "cursor-global",
1171
- path: import_node_path12.default.join(import_node_os.default.homedir(), ".cursor", "mcp.json"),
866
+ path: path3.join(os.homedir(), ".cursor", "mcp.json"),
1172
867
  generate: () => generateCursorMcp(config, "global")
1173
868
  },
1174
869
  {
1175
870
  tool: "gemini-global",
1176
- path: import_node_path12.default.join(import_node_os.default.homedir(), ".gemini", "settings.json"),
871
+ path: path3.join(os.homedir(), ".gemini", "settings.json"),
1177
872
  generate: () => generateGeminiCliMcp(config, "global")
1178
873
  }
1179
874
  );
@@ -1331,10 +1026,10 @@ Generating configurations for base directory: ${baseDir}`);
1331
1026
  }
1332
1027
 
1333
1028
  // src/cli/commands/gitignore.ts
1334
- var import_node_fs2 = require("fs");
1335
- var import_node_path13 = require("path");
1029
+ import { existsSync, readFileSync, writeFileSync } from "fs";
1030
+ import { join as join9 } from "path";
1336
1031
  var gitignoreCommand = async () => {
1337
- const gitignorePath = (0, import_node_path13.join)(process.cwd(), ".gitignore");
1032
+ const gitignorePath = join9(process.cwd(), ".gitignore");
1338
1033
  const rulesFilesToIgnore = [
1339
1034
  "# Generated by rulesync - AI tool configuration files",
1340
1035
  "**/.github/copilot-instructions.md",
@@ -1352,6 +1047,7 @@ var gitignoreCommand = async () => {
1352
1047
  "**/.gemini/memories/",
1353
1048
  "**/.aiexclude",
1354
1049
  "**/.mcp.json",
1050
+ "!.rulesync/.mcp.json",
1355
1051
  "**/.cursor/mcp.json",
1356
1052
  "**/.cline/mcp.json",
1357
1053
  "**/.vscode/mcp.json",
@@ -1359,8 +1055,8 @@ var gitignoreCommand = async () => {
1359
1055
  "**/.roo/mcp.json"
1360
1056
  ];
1361
1057
  let gitignoreContent = "";
1362
- if ((0, import_node_fs2.existsSync)(gitignorePath)) {
1363
- gitignoreContent = (0, import_node_fs2.readFileSync)(gitignorePath, "utf-8");
1058
+ if (existsSync(gitignorePath)) {
1059
+ gitignoreContent = readFileSync(gitignorePath, "utf-8");
1364
1060
  }
1365
1061
  const linesToAdd = [];
1366
1062
  for (const rule of rulesFilesToIgnore) {
@@ -1377,7 +1073,7 @@ var gitignoreCommand = async () => {
1377
1073
  ${linesToAdd.join("\n")}
1378
1074
  ` : `${linesToAdd.join("\n")}
1379
1075
  `;
1380
- (0, import_node_fs2.writeFileSync)(gitignorePath, newContent);
1076
+ writeFileSync(gitignorePath, newContent);
1381
1077
  console.log(`\u2705 .gitignore\u306B${linesToAdd.length}\u500B\u306E\u30EB\u30FC\u30EB\u3092\u8FFD\u52A0\u3057\u307E\u3057\u305F:`);
1382
1078
  for (const line of linesToAdd) {
1383
1079
  if (!line.startsWith("#")) {
@@ -1387,17 +1083,17 @@ ${linesToAdd.join("\n")}
1387
1083
  };
1388
1084
 
1389
1085
  // src/core/importer.ts
1390
- var import_node_path20 = require("path");
1391
- var import_gray_matter4 = __toESM(require("gray-matter"));
1086
+ import { join as join16 } from "path";
1087
+ import matter4 from "gray-matter";
1392
1088
 
1393
1089
  // src/parsers/claudecode.ts
1394
- var import_node_path14 = require("path");
1090
+ import { basename as basename2, join as join10 } from "path";
1395
1091
  async function parseClaudeConfiguration(baseDir = process.cwd()) {
1396
1092
  const errors = [];
1397
1093
  const rules = [];
1398
1094
  let ignorePatterns;
1399
1095
  let mcpServers;
1400
- const claudeFilePath = (0, import_node_path14.join)(baseDir, "CLAUDE.md");
1096
+ const claudeFilePath = join10(baseDir, "CLAUDE.md");
1401
1097
  if (!await fileExists(claudeFilePath)) {
1402
1098
  errors.push("CLAUDE.md file not found");
1403
1099
  return { rules, errors };
@@ -1408,12 +1104,12 @@ async function parseClaudeConfiguration(baseDir = process.cwd()) {
1408
1104
  if (mainRule) {
1409
1105
  rules.push(mainRule);
1410
1106
  }
1411
- const memoryDir = (0, import_node_path14.join)(baseDir, ".claude", "memories");
1107
+ const memoryDir = join10(baseDir, ".claude", "memories");
1412
1108
  if (await fileExists(memoryDir)) {
1413
1109
  const memoryRules = await parseClaudeMemoryFiles(memoryDir);
1414
1110
  rules.push(...memoryRules);
1415
1111
  }
1416
- const settingsPath = (0, import_node_path14.join)(baseDir, ".claude", "settings.json");
1112
+ const settingsPath = join10(baseDir, ".claude", "settings.json");
1417
1113
  if (await fileExists(settingsPath)) {
1418
1114
  const settingsResult = await parseClaudeSettings(settingsPath);
1419
1115
  if (settingsResult.ignorePatterns) {
@@ -1470,10 +1166,10 @@ async function parseClaudeMemoryFiles(memoryDir) {
1470
1166
  const files = await readdir2(memoryDir);
1471
1167
  for (const file of files) {
1472
1168
  if (file.endsWith(".md")) {
1473
- const filePath = (0, import_node_path14.join)(memoryDir, file);
1169
+ const filePath = join10(memoryDir, file);
1474
1170
  const content = await readFileContent(filePath);
1475
1171
  if (content.trim()) {
1476
- const filename = (0, import_node_path14.basename)(file, ".md");
1172
+ const filename = basename2(file, ".md");
1477
1173
  const frontmatter = {
1478
1174
  root: false,
1479
1175
  targets: ["claudecode"],
@@ -1489,7 +1185,7 @@ async function parseClaudeMemoryFiles(memoryDir) {
1489
1185
  }
1490
1186
  }
1491
1187
  }
1492
- } catch (_error) {
1188
+ } catch {
1493
1189
  }
1494
1190
  return rules;
1495
1191
  }
@@ -1500,17 +1196,25 @@ async function parseClaudeSettings(settingsPath) {
1500
1196
  try {
1501
1197
  const content = await readFileContent(settingsPath);
1502
1198
  const settings = JSON.parse(content);
1503
- if (settings.permissions?.deny) {
1504
- const readPatterns = settings.permissions.deny.filter((rule) => rule.startsWith("Read(") && rule.endsWith(")")).map((rule) => {
1505
- const match = rule.match(/^Read\((.+)\)$/);
1506
- return match ? match[1] : null;
1507
- }).filter((pattern) => pattern !== null);
1508
- if (readPatterns.length > 0) {
1509
- ignorePatterns = readPatterns;
1199
+ if (typeof settings === "object" && settings !== null && "permissions" in settings) {
1200
+ const permissions = settings.permissions;
1201
+ if (permissions && "deny" in permissions && Array.isArray(permissions.deny)) {
1202
+ const readPatterns = permissions.deny.filter(
1203
+ (rule) => typeof rule === "string" && rule.startsWith("Read(") && rule.endsWith(")")
1204
+ ).map((rule) => {
1205
+ const match = rule.match(/^Read\((.+)\)$/);
1206
+ return match ? match[1] : null;
1207
+ }).filter((pattern) => pattern !== null);
1208
+ if (readPatterns.length > 0) {
1209
+ ignorePatterns = readPatterns;
1210
+ }
1510
1211
  }
1511
1212
  }
1512
- if (settings.mcpServers && Object.keys(settings.mcpServers).length > 0) {
1513
- mcpServers = settings.mcpServers;
1213
+ if (typeof settings === "object" && settings !== null && "mcpServers" in settings) {
1214
+ const servers = settings.mcpServers;
1215
+ if (servers && typeof servers === "object" && Object.keys(servers).length > 0) {
1216
+ mcpServers = servers;
1217
+ }
1514
1218
  }
1515
1219
  } catch (error) {
1516
1220
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -1524,11 +1228,11 @@ async function parseClaudeSettings(settingsPath) {
1524
1228
  }
1525
1229
 
1526
1230
  // src/parsers/cline.ts
1527
- var import_node_path15 = require("path");
1231
+ import { join as join11 } from "path";
1528
1232
  async function parseClineConfiguration(baseDir = process.cwd()) {
1529
1233
  const errors = [];
1530
1234
  const rules = [];
1531
- const clineFilePath = (0, import_node_path15.join)(baseDir, ".cline", "instructions.md");
1235
+ const clineFilePath = join11(baseDir, ".cline", "instructions.md");
1532
1236
  if (await fileExists(clineFilePath)) {
1533
1237
  try {
1534
1238
  const content = await readFileContent(clineFilePath);
@@ -1551,14 +1255,14 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1551
1255
  errors.push(`Failed to parse .cline/instructions.md: ${errorMessage}`);
1552
1256
  }
1553
1257
  }
1554
- const clinerulesDirPath = (0, import_node_path15.join)(baseDir, ".clinerules");
1258
+ const clinerulesDirPath = join11(baseDir, ".clinerules");
1555
1259
  if (await fileExists(clinerulesDirPath)) {
1556
1260
  try {
1557
1261
  const { readdir: readdir2 } = await import("fs/promises");
1558
1262
  const files = await readdir2(clinerulesDirPath);
1559
1263
  for (const file of files) {
1560
1264
  if (file.endsWith(".md")) {
1561
- const filePath = (0, import_node_path15.join)(clinerulesDirPath, file);
1265
+ const filePath = join11(clinerulesDirPath, file);
1562
1266
  try {
1563
1267
  const content = await readFileContent(filePath);
1564
1268
  if (content.trim()) {
@@ -1594,16 +1298,16 @@ async function parseClineConfiguration(baseDir = process.cwd()) {
1594
1298
  }
1595
1299
 
1596
1300
  // src/parsers/copilot.ts
1597
- var import_node_path16 = require("path");
1598
- var import_gray_matter2 = __toESM(require("gray-matter"));
1301
+ import { basename as basename3, join as join12 } from "path";
1302
+ import matter2 from "gray-matter";
1599
1303
  async function parseCopilotConfiguration(baseDir = process.cwd()) {
1600
1304
  const errors = [];
1601
1305
  const rules = [];
1602
- const copilotFilePath = (0, import_node_path16.join)(baseDir, ".github", "copilot-instructions.md");
1306
+ const copilotFilePath = join12(baseDir, ".github", "copilot-instructions.md");
1603
1307
  if (await fileExists(copilotFilePath)) {
1604
1308
  try {
1605
1309
  const rawContent = await readFileContent(copilotFilePath);
1606
- const parsed = (0, import_gray_matter2.default)(rawContent);
1310
+ const parsed = matter2(rawContent);
1607
1311
  const content = parsed.content.trim();
1608
1312
  if (content) {
1609
1313
  const frontmatter = {
@@ -1624,19 +1328,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1624
1328
  errors.push(`Failed to parse copilot-instructions.md: ${errorMessage}`);
1625
1329
  }
1626
1330
  }
1627
- const instructionsDir = (0, import_node_path16.join)(baseDir, ".github", "instructions");
1331
+ const instructionsDir = join12(baseDir, ".github", "instructions");
1628
1332
  if (await fileExists(instructionsDir)) {
1629
1333
  try {
1630
1334
  const { readdir: readdir2 } = await import("fs/promises");
1631
1335
  const files = await readdir2(instructionsDir);
1632
1336
  for (const file of files) {
1633
1337
  if (file.endsWith(".instructions.md")) {
1634
- const filePath = (0, import_node_path16.join)(instructionsDir, file);
1338
+ const filePath = join12(instructionsDir, file);
1635
1339
  const rawContent = await readFileContent(filePath);
1636
- const parsed = (0, import_gray_matter2.default)(rawContent);
1340
+ const parsed = matter2(rawContent);
1637
1341
  const content = parsed.content.trim();
1638
1342
  if (content) {
1639
- const filename = (0, import_node_path16.basename)(file, ".instructions.md");
1343
+ const filename = basename3(file, ".instructions.md");
1640
1344
  const frontmatter = {
1641
1345
  root: false,
1642
1346
  targets: ["copilot"],
@@ -1666,19 +1370,19 @@ async function parseCopilotConfiguration(baseDir = process.cwd()) {
1666
1370
  }
1667
1371
 
1668
1372
  // src/parsers/cursor.ts
1669
- var import_node_path17 = require("path");
1670
- var import_gray_matter3 = __toESM(require("gray-matter"));
1671
- var import_js_yaml = __toESM(require("js-yaml"));
1373
+ import { basename as basename4, join as join13 } from "path";
1374
+ import matter3 from "gray-matter";
1375
+ import { DEFAULT_SCHEMA, FAILSAFE_SCHEMA, load } from "js-yaml";
1672
1376
  var customMatterOptions = {
1673
1377
  engines: {
1674
1378
  yaml: {
1675
1379
  parse: (str) => {
1676
1380
  try {
1677
1381
  const preprocessed = str.replace(/^(\s*globs:\s*)\*\s*$/gm, '$1"*"');
1678
- return import_js_yaml.default.load(preprocessed, { schema: import_js_yaml.default.DEFAULT_SCHEMA });
1382
+ return load(preprocessed, { schema: DEFAULT_SCHEMA });
1679
1383
  } catch (error) {
1680
1384
  try {
1681
- return import_js_yaml.default.load(str, { schema: import_js_yaml.default.FAILSAFE_SCHEMA });
1385
+ return load(str, { schema: FAILSAFE_SCHEMA });
1682
1386
  } catch {
1683
1387
  throw error;
1684
1388
  }
@@ -1692,11 +1396,11 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1692
1396
  const rules = [];
1693
1397
  let ignorePatterns;
1694
1398
  let mcpServers;
1695
- const cursorFilePath = (0, import_node_path17.join)(baseDir, ".cursorrules");
1399
+ const cursorFilePath = join13(baseDir, ".cursorrules");
1696
1400
  if (await fileExists(cursorFilePath)) {
1697
1401
  try {
1698
1402
  const rawContent = await readFileContent(cursorFilePath);
1699
- const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
1403
+ const parsed = matter3(rawContent, customMatterOptions);
1700
1404
  const content = parsed.content.trim();
1701
1405
  if (content) {
1702
1406
  const frontmatter = {
@@ -1717,20 +1421,20 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1717
1421
  errors.push(`Failed to parse .cursorrules file: ${errorMessage}`);
1718
1422
  }
1719
1423
  }
1720
- const cursorRulesDir = (0, import_node_path17.join)(baseDir, ".cursor", "rules");
1424
+ const cursorRulesDir = join13(baseDir, ".cursor", "rules");
1721
1425
  if (await fileExists(cursorRulesDir)) {
1722
1426
  try {
1723
1427
  const { readdir: readdir2 } = await import("fs/promises");
1724
1428
  const files = await readdir2(cursorRulesDir);
1725
1429
  for (const file of files) {
1726
1430
  if (file.endsWith(".mdc")) {
1727
- const filePath = (0, import_node_path17.join)(cursorRulesDir, file);
1431
+ const filePath = join13(cursorRulesDir, file);
1728
1432
  try {
1729
1433
  const rawContent = await readFileContent(filePath);
1730
- const parsed = (0, import_gray_matter3.default)(rawContent, customMatterOptions);
1434
+ const parsed = matter3(rawContent, customMatterOptions);
1731
1435
  const content = parsed.content.trim();
1732
1436
  if (content) {
1733
- const filename = (0, import_node_path17.basename)(file, ".mdc");
1437
+ const filename = basename4(file, ".mdc");
1734
1438
  const frontmatter = {
1735
1439
  root: false,
1736
1440
  targets: ["cursor"],
@@ -1758,7 +1462,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1758
1462
  if (rules.length === 0) {
1759
1463
  errors.push("No Cursor configuration files found (.cursorrules or .cursor/rules/*.mdc)");
1760
1464
  }
1761
- const cursorIgnorePath = (0, import_node_path17.join)(baseDir, ".cursorignore");
1465
+ const cursorIgnorePath = join13(baseDir, ".cursorignore");
1762
1466
  if (await fileExists(cursorIgnorePath)) {
1763
1467
  try {
1764
1468
  const content = await readFileContent(cursorIgnorePath);
@@ -1771,7 +1475,7 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1771
1475
  errors.push(`Failed to parse .cursorignore: ${errorMessage}`);
1772
1476
  }
1773
1477
  }
1774
- const cursorMcpPath = (0, import_node_path17.join)(baseDir, ".cursor", "mcp.json");
1478
+ const cursorMcpPath = join13(baseDir, ".cursor", "mcp.json");
1775
1479
  if (await fileExists(cursorMcpPath)) {
1776
1480
  try {
1777
1481
  const content = await readFileContent(cursorMcpPath);
@@ -1793,13 +1497,13 @@ async function parseCursorConfiguration(baseDir = process.cwd()) {
1793
1497
  }
1794
1498
 
1795
1499
  // src/parsers/geminicli.ts
1796
- var import_node_path18 = require("path");
1500
+ import { basename as basename5, join as join14 } from "path";
1797
1501
  async function parseGeminiConfiguration(baseDir = process.cwd()) {
1798
1502
  const errors = [];
1799
1503
  const rules = [];
1800
1504
  let ignorePatterns;
1801
1505
  let mcpServers;
1802
- const geminiFilePath = (0, import_node_path18.join)(baseDir, "GEMINI.md");
1506
+ const geminiFilePath = join14(baseDir, "GEMINI.md");
1803
1507
  if (!await fileExists(geminiFilePath)) {
1804
1508
  errors.push("GEMINI.md file not found");
1805
1509
  return { rules, errors };
@@ -1810,12 +1514,12 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1810
1514
  if (mainRule) {
1811
1515
  rules.push(mainRule);
1812
1516
  }
1813
- const memoryDir = (0, import_node_path18.join)(baseDir, ".gemini", "memories");
1517
+ const memoryDir = join14(baseDir, ".gemini", "memories");
1814
1518
  if (await fileExists(memoryDir)) {
1815
1519
  const memoryRules = await parseGeminiMemoryFiles(memoryDir);
1816
1520
  rules.push(...memoryRules);
1817
1521
  }
1818
- const settingsPath = (0, import_node_path18.join)(baseDir, ".gemini", "settings.json");
1522
+ const settingsPath = join14(baseDir, ".gemini", "settings.json");
1819
1523
  if (await fileExists(settingsPath)) {
1820
1524
  const settingsResult = await parseGeminiSettings(settingsPath);
1821
1525
  if (settingsResult.ignorePatterns) {
@@ -1826,7 +1530,7 @@ async function parseGeminiConfiguration(baseDir = process.cwd()) {
1826
1530
  }
1827
1531
  errors.push(...settingsResult.errors);
1828
1532
  }
1829
- const aiexcludePath = (0, import_node_path18.join)(baseDir, ".aiexclude");
1533
+ const aiexcludePath = join14(baseDir, ".aiexclude");
1830
1534
  if (await fileExists(aiexcludePath)) {
1831
1535
  const aiexcludePatterns = await parseAiexclude(aiexcludePath);
1832
1536
  if (aiexcludePatterns.length > 0) {
@@ -1879,10 +1583,10 @@ async function parseGeminiMemoryFiles(memoryDir) {
1879
1583
  const files = await readdir2(memoryDir);
1880
1584
  for (const file of files) {
1881
1585
  if (file.endsWith(".md")) {
1882
- const filePath = (0, import_node_path18.join)(memoryDir, file);
1586
+ const filePath = join14(memoryDir, file);
1883
1587
  const content = await readFileContent(filePath);
1884
1588
  if (content.trim()) {
1885
- const filename = (0, import_node_path18.basename)(file, ".md");
1589
+ const filename = basename5(file, ".md");
1886
1590
  const frontmatter = {
1887
1591
  root: false,
1888
1592
  targets: ["geminicli"],
@@ -1898,7 +1602,7 @@ async function parseGeminiMemoryFiles(memoryDir) {
1898
1602
  }
1899
1603
  }
1900
1604
  }
1901
- } catch (_error) {
1605
+ } catch {
1902
1606
  }
1903
1607
  return rules;
1904
1608
  }
@@ -1925,17 +1629,17 @@ async function parseAiexclude(aiexcludePath) {
1925
1629
  const content = await readFileContent(aiexcludePath);
1926
1630
  const patterns = content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
1927
1631
  return patterns;
1928
- } catch (_error) {
1632
+ } catch {
1929
1633
  return [];
1930
1634
  }
1931
1635
  }
1932
1636
 
1933
1637
  // src/parsers/roo.ts
1934
- var import_node_path19 = require("path");
1638
+ import { join as join15 } from "path";
1935
1639
  async function parseRooConfiguration(baseDir = process.cwd()) {
1936
1640
  const errors = [];
1937
1641
  const rules = [];
1938
- const rooFilePath = (0, import_node_path19.join)(baseDir, ".roo", "instructions.md");
1642
+ const rooFilePath = join15(baseDir, ".roo", "instructions.md");
1939
1643
  if (await fileExists(rooFilePath)) {
1940
1644
  try {
1941
1645
  const content = await readFileContent(rooFilePath);
@@ -1958,14 +1662,14 @@ async function parseRooConfiguration(baseDir = process.cwd()) {
1958
1662
  errors.push(`Failed to parse .roo/instructions.md: ${errorMessage}`);
1959
1663
  }
1960
1664
  }
1961
- const rooRulesDir = (0, import_node_path19.join)(baseDir, ".roo", "rules");
1665
+ const rooRulesDir = join15(baseDir, ".roo", "rules");
1962
1666
  if (await fileExists(rooRulesDir)) {
1963
1667
  try {
1964
1668
  const { readdir: readdir2 } = await import("fs/promises");
1965
1669
  const files = await readdir2(rooRulesDir);
1966
1670
  for (const file of files) {
1967
1671
  if (file.endsWith(".md")) {
1968
- const filePath = (0, import_node_path19.join)(rooRulesDir, file);
1672
+ const filePath = join15(rooRulesDir, file);
1969
1673
  try {
1970
1674
  const content = await readFileContent(filePath);
1971
1675
  if (content.trim()) {
@@ -2066,7 +1770,7 @@ async function importConfiguration(options) {
2066
1770
  if (rules.length === 0 && !ignorePatterns && !mcpServers) {
2067
1771
  return { success: false, rulesCreated: 0, errors };
2068
1772
  }
2069
- const rulesDirPath = (0, import_node_path20.join)(baseDir, rulesDir);
1773
+ const rulesDirPath = join16(baseDir, rulesDir);
2070
1774
  try {
2071
1775
  const { mkdir: mkdir3 } = await import("fs/promises");
2072
1776
  await mkdir3(rulesDirPath, { recursive: true });
@@ -2080,7 +1784,7 @@ async function importConfiguration(options) {
2080
1784
  try {
2081
1785
  const baseFilename = `${tool}__${rule.filename}`;
2082
1786
  const filename = await generateUniqueFilename(rulesDirPath, baseFilename);
2083
- const filePath = (0, import_node_path20.join)(rulesDirPath, `${filename}.md`);
1787
+ const filePath = join16(rulesDirPath, `${filename}.md`);
2084
1788
  const content = generateRuleFileContent(rule);
2085
1789
  await writeFileContent(filePath, content);
2086
1790
  rulesCreated++;
@@ -2095,7 +1799,7 @@ async function importConfiguration(options) {
2095
1799
  let ignoreFileCreated = false;
2096
1800
  if (ignorePatterns && ignorePatterns.length > 0) {
2097
1801
  try {
2098
- const rulesyncignorePath = (0, import_node_path20.join)(baseDir, ".rulesyncignore");
1802
+ const rulesyncignorePath = join16(baseDir, ".rulesyncignore");
2099
1803
  const ignoreContent = `${ignorePatterns.join("\n")}
2100
1804
  `;
2101
1805
  await writeFileContent(rulesyncignorePath, ignoreContent);
@@ -2111,7 +1815,7 @@ async function importConfiguration(options) {
2111
1815
  let mcpFileCreated = false;
2112
1816
  if (mcpServers && Object.keys(mcpServers).length > 0) {
2113
1817
  try {
2114
- const mcpPath = (0, import_node_path20.join)(baseDir, rulesDir, ".mcp.json");
1818
+ const mcpPath = join16(baseDir, rulesDir, ".mcp.json");
2115
1819
  const mcpContent = `${JSON.stringify({ mcpServers }, null, 2)}
2116
1820
  `;
2117
1821
  await writeFileContent(mcpPath, mcpContent);
@@ -2133,13 +1837,13 @@ async function importConfiguration(options) {
2133
1837
  };
2134
1838
  }
2135
1839
  function generateRuleFileContent(rule) {
2136
- const frontmatter = import_gray_matter4.default.stringify("", rule.frontmatter);
1840
+ const frontmatter = matter4.stringify("", rule.frontmatter);
2137
1841
  return frontmatter + rule.content;
2138
1842
  }
2139
1843
  async function generateUniqueFilename(rulesDir, baseFilename) {
2140
1844
  let filename = baseFilename;
2141
1845
  let counter = 1;
2142
- while (await fileExists((0, import_node_path20.join)(rulesDir, `${filename}.md`))) {
1846
+ while (await fileExists(join16(rulesDir, `${filename}.md`))) {
2143
1847
  filename = `${baseFilename}-${counter}`;
2144
1848
  counter++;
2145
1849
  }
@@ -2204,7 +1908,7 @@ async function importCommand(options = {}) {
2204
1908
  }
2205
1909
 
2206
1910
  // src/cli/commands/init.ts
2207
- var import_node_path21 = require("path");
1911
+ import { join as join17 } from "path";
2208
1912
  async function initCommand() {
2209
1913
  const aiRulesDir = ".rulesync";
2210
1914
  console.log("Initializing rulesync...");
@@ -2334,7 +2038,7 @@ globs: ["src/api/**/*.ts", "src/services/**/*.ts", "src/models/**/*.ts"]
2334
2038
  }
2335
2039
  ];
2336
2040
  for (const file of sampleFiles) {
2337
- const filepath = (0, import_node_path21.join)(aiRulesDir, file.filename);
2041
+ const filepath = join17(aiRulesDir, file.filename);
2338
2042
  if (!await fileExists(filepath)) {
2339
2043
  await writeFileContent(filepath, file.content);
2340
2044
  console.log(`Created ${filepath}`);
@@ -2436,13 +2140,13 @@ async function validateCommand() {
2436
2140
  }
2437
2141
 
2438
2142
  // src/cli/commands/watch.ts
2439
- var import_chokidar = __toESM(require("chokidar"));
2143
+ import { watch } from "chokidar";
2440
2144
  async function watchCommand() {
2441
2145
  const config = getDefaultConfig();
2442
2146
  console.log("\u{1F440} Watching for changes in .rulesync directory...");
2443
2147
  console.log("Press Ctrl+C to stop watching");
2444
2148
  await generateCommand({ verbose: false });
2445
- const watcher = import_chokidar.default.watch(`${config.aiRulesDir}/**/*.md`, {
2149
+ const watcher = watch(`${config.aiRulesDir}/**/*.md`, {
2446
2150
  ignoreInitial: true,
2447
2151
  persistent: true
2448
2152
  });
@@ -2476,8 +2180,8 @@ async function watchCommand() {
2476
2180
  }
2477
2181
 
2478
2182
  // src/cli/index.ts
2479
- var program = new import_commander.Command();
2480
- program.name("rulesync").description("Unified AI rules management CLI tool").version("0.36.0");
2183
+ var program = new Command();
2184
+ program.name("rulesync").description("Unified AI rules management CLI tool").version("0.38.0");
2481
2185
  program.command("init").description("Initialize rulesync in current directory").action(initCommand);
2482
2186
  program.command("add <filename>").description("Add a new rule file").action(addCommand);
2483
2187
  program.command("gitignore").description("Add generated files to .gitignore").action(gitignoreCommand);