rulesync 7.15.2 → 7.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{chunk-WY325EI7.js → chunk-E5YWRHGW.js} +142 -39
- package/dist/cli/index.cjs +309 -173
- package/dist/cli/index.js +173 -138
- package/dist/index.cjs +140 -40
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -351,14 +351,21 @@ var ToolTargetSchema = import_mini2.z.enum(ALL_TOOL_TARGETS);
|
|
|
351
351
|
var ToolTargetsSchema = import_mini2.z.array(ToolTargetSchema);
|
|
352
352
|
var RulesyncTargetsSchema = import_mini2.z.array(import_mini2.z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD));
|
|
353
353
|
|
|
354
|
-
// src/
|
|
355
|
-
function
|
|
354
|
+
// src/utils/validation.ts
|
|
355
|
+
function findControlCharacter(value) {
|
|
356
356
|
for (let i = 0; i < value.length; i++) {
|
|
357
357
|
const code = value.charCodeAt(i);
|
|
358
|
-
if (code >= 0 && code <= 31 || code === 127)
|
|
358
|
+
if (code >= 0 && code <= 31 || code === 127) {
|
|
359
|
+
return { position: i, hex: `0x${code.toString(16).padStart(2, "0")}` };
|
|
360
|
+
}
|
|
359
361
|
}
|
|
360
|
-
return
|
|
362
|
+
return null;
|
|
361
363
|
}
|
|
364
|
+
function hasControlCharacters(value) {
|
|
365
|
+
return findControlCharacter(value) !== null;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/config/config.ts
|
|
362
369
|
var SourceEntrySchema = import_mini3.z.object({
|
|
363
370
|
source: import_mini3.z.string().check((0, import_mini3.minLength)(1, "source must be a non-empty string")),
|
|
364
371
|
skills: (0, import_mini3.optional)(import_mini3.z.array(import_mini3.z.string())),
|
|
@@ -738,6 +745,7 @@ var import_node_path7 = require("path");
|
|
|
738
745
|
|
|
739
746
|
// src/utils/frontmatter.ts
|
|
740
747
|
var import_gray_matter = __toESM(require("gray-matter"), 1);
|
|
748
|
+
var import_js_yaml = require("js-yaml");
|
|
741
749
|
function isPlainObject(value) {
|
|
742
750
|
if (value === null || typeof value !== "object") return false;
|
|
743
751
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -776,8 +784,55 @@ function deepRemoveNullishObject(obj) {
|
|
|
776
784
|
}
|
|
777
785
|
return result;
|
|
778
786
|
}
|
|
779
|
-
function
|
|
780
|
-
|
|
787
|
+
function deepFlattenStringsValue(value) {
|
|
788
|
+
if (value === null || value === void 0) {
|
|
789
|
+
return void 0;
|
|
790
|
+
}
|
|
791
|
+
if (typeof value === "string") {
|
|
792
|
+
return value.replace(/\n+/g, " ").trim();
|
|
793
|
+
}
|
|
794
|
+
if (Array.isArray(value)) {
|
|
795
|
+
const cleanedArray = value.map((item) => deepFlattenStringsValue(item)).filter((item) => item !== void 0);
|
|
796
|
+
return cleanedArray;
|
|
797
|
+
}
|
|
798
|
+
if (isPlainObject(value)) {
|
|
799
|
+
const result = {};
|
|
800
|
+
for (const [key, val] of Object.entries(value)) {
|
|
801
|
+
const cleaned = deepFlattenStringsValue(val);
|
|
802
|
+
if (cleaned !== void 0) {
|
|
803
|
+
result[key] = cleaned;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return result;
|
|
807
|
+
}
|
|
808
|
+
return value;
|
|
809
|
+
}
|
|
810
|
+
function deepFlattenStringsObject(obj) {
|
|
811
|
+
if (!obj || typeof obj !== "object") {
|
|
812
|
+
return {};
|
|
813
|
+
}
|
|
814
|
+
const result = {};
|
|
815
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
816
|
+
const cleaned = deepFlattenStringsValue(val);
|
|
817
|
+
if (cleaned !== void 0) {
|
|
818
|
+
result[key] = cleaned;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return result;
|
|
822
|
+
}
|
|
823
|
+
function stringifyFrontmatter(body, frontmatter, options) {
|
|
824
|
+
const { avoidBlockScalars = false } = options ?? {};
|
|
825
|
+
const cleanFrontmatter = avoidBlockScalars ? deepFlattenStringsObject(frontmatter) : deepRemoveNullishObject(frontmatter);
|
|
826
|
+
if (avoidBlockScalars) {
|
|
827
|
+
return import_gray_matter.default.stringify(body, cleanFrontmatter, {
|
|
828
|
+
engines: {
|
|
829
|
+
yaml: {
|
|
830
|
+
parse: (input) => (0, import_js_yaml.load)(input) ?? {},
|
|
831
|
+
stringify: (data) => (0, import_js_yaml.dump)(data, { lineWidth: -1 })
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
}
|
|
781
836
|
return import_gray_matter.default.stringify(body, cleanFrontmatter);
|
|
782
837
|
}
|
|
783
838
|
function parseFrontmatter(content, filePath) {
|
|
@@ -1896,7 +1951,7 @@ var CursorCommand = class _CursorCommand extends ToolCommand {
|
|
|
1896
1951
|
}
|
|
1897
1952
|
super({
|
|
1898
1953
|
...rest,
|
|
1899
|
-
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
1954
|
+
fileContent: stringifyFrontmatter(body, frontmatter, { avoidBlockScalars: true })
|
|
1900
1955
|
});
|
|
1901
1956
|
this.frontmatter = frontmatter;
|
|
1902
1957
|
this.body = body;
|
|
@@ -6322,12 +6377,26 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
6322
6377
|
json;
|
|
6323
6378
|
constructor(params) {
|
|
6324
6379
|
super(params);
|
|
6325
|
-
|
|
6380
|
+
if (this.fileContent !== void 0) {
|
|
6381
|
+
try {
|
|
6382
|
+
this.json = JSON.parse(this.fileContent);
|
|
6383
|
+
} catch (error) {
|
|
6384
|
+
throw new Error(
|
|
6385
|
+
`Failed to parse Cursor MCP config at ${(0, import_node_path48.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(error)}`,
|
|
6386
|
+
{ cause: error }
|
|
6387
|
+
);
|
|
6388
|
+
}
|
|
6389
|
+
} else {
|
|
6390
|
+
this.json = {};
|
|
6391
|
+
}
|
|
6326
6392
|
}
|
|
6327
6393
|
getJson() {
|
|
6328
6394
|
return this.json;
|
|
6329
6395
|
}
|
|
6330
|
-
|
|
6396
|
+
isDeletable() {
|
|
6397
|
+
return !this.global;
|
|
6398
|
+
}
|
|
6399
|
+
static getSettablePaths(_options) {
|
|
6331
6400
|
return {
|
|
6332
6401
|
relativeDirPath: ".cursor",
|
|
6333
6402
|
relativeFilePath: "mcp.json"
|
|
@@ -6335,41 +6404,62 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
6335
6404
|
}
|
|
6336
6405
|
static async fromFile({
|
|
6337
6406
|
baseDir = process.cwd(),
|
|
6338
|
-
validate = true
|
|
6407
|
+
validate = true,
|
|
6408
|
+
global = false
|
|
6339
6409
|
}) {
|
|
6340
|
-
const
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
)
|
|
6346
|
-
)
|
|
6410
|
+
const paths = this.getSettablePaths({ global });
|
|
6411
|
+
const filePath = (0, import_node_path48.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath);
|
|
6412
|
+
const fileContent = await readFileContentOrNull(filePath) ?? '{"mcpServers":{}}';
|
|
6413
|
+
let json;
|
|
6414
|
+
try {
|
|
6415
|
+
json = JSON.parse(fileContent);
|
|
6416
|
+
} catch (error) {
|
|
6417
|
+
throw new Error(
|
|
6418
|
+
`Failed to parse Cursor MCP config at ${(0, import_node_path48.join)(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError(error)}`,
|
|
6419
|
+
{ cause: error }
|
|
6420
|
+
);
|
|
6421
|
+
}
|
|
6422
|
+
const newJson = { ...json, mcpServers: json.mcpServers ?? {} };
|
|
6347
6423
|
return new _CursorMcp({
|
|
6348
6424
|
baseDir,
|
|
6349
|
-
relativeDirPath:
|
|
6350
|
-
relativeFilePath:
|
|
6351
|
-
fileContent,
|
|
6352
|
-
validate
|
|
6425
|
+
relativeDirPath: paths.relativeDirPath,
|
|
6426
|
+
relativeFilePath: paths.relativeFilePath,
|
|
6427
|
+
fileContent: JSON.stringify(newJson, null, 2),
|
|
6428
|
+
validate,
|
|
6429
|
+
global
|
|
6353
6430
|
});
|
|
6354
6431
|
}
|
|
6355
|
-
static fromRulesyncMcp({
|
|
6432
|
+
static async fromRulesyncMcp({
|
|
6356
6433
|
baseDir = process.cwd(),
|
|
6357
6434
|
rulesyncMcp,
|
|
6358
|
-
validate = true
|
|
6435
|
+
validate = true,
|
|
6436
|
+
global = false
|
|
6359
6437
|
}) {
|
|
6360
|
-
const
|
|
6361
|
-
const
|
|
6438
|
+
const paths = this.getSettablePaths({ global });
|
|
6439
|
+
const fileContent = await readOrInitializeFileContent(
|
|
6440
|
+
(0, import_node_path48.join)(baseDir, paths.relativeDirPath, paths.relativeFilePath),
|
|
6441
|
+
JSON.stringify({ mcpServers: {} }, null, 2)
|
|
6442
|
+
);
|
|
6443
|
+
let json;
|
|
6444
|
+
try {
|
|
6445
|
+
json = JSON.parse(fileContent);
|
|
6446
|
+
} catch (error) {
|
|
6447
|
+
throw new Error(
|
|
6448
|
+
`Failed to parse Cursor MCP config at ${(0, import_node_path48.join)(paths.relativeDirPath, paths.relativeFilePath)}: ${formatError(error)}`,
|
|
6449
|
+
{ cause: error }
|
|
6450
|
+
);
|
|
6451
|
+
}
|
|
6452
|
+
const rulesyncJson = rulesyncMcp.getJson();
|
|
6453
|
+
const mcpServers = isMcpServers(rulesyncJson.mcpServers) ? rulesyncJson.mcpServers : {};
|
|
6362
6454
|
const transformedServers = convertEnvToCursorFormat(mcpServers);
|
|
6363
|
-
const cursorConfig = {
|
|
6364
|
-
mcpServers: transformedServers
|
|
6365
|
-
};
|
|
6366
|
-
const fileContent = JSON.stringify(cursorConfig, null, 2);
|
|
6455
|
+
const cursorConfig = { ...json, mcpServers: transformedServers };
|
|
6367
6456
|
return new _CursorMcp({
|
|
6368
6457
|
baseDir,
|
|
6369
|
-
relativeDirPath:
|
|
6370
|
-
relativeFilePath:
|
|
6371
|
-
fileContent,
|
|
6372
|
-
validate
|
|
6458
|
+
relativeDirPath: paths.relativeDirPath,
|
|
6459
|
+
relativeFilePath: paths.relativeFilePath,
|
|
6460
|
+
fileContent: JSON.stringify(cursorConfig, null, 2),
|
|
6461
|
+
validate,
|
|
6462
|
+
global
|
|
6373
6463
|
});
|
|
6374
6464
|
}
|
|
6375
6465
|
toRulesyncMcp() {
|
|
@@ -6393,14 +6483,16 @@ var CursorMcp = class _CursorMcp extends ToolMcp {
|
|
|
6393
6483
|
static forDeletion({
|
|
6394
6484
|
baseDir = process.cwd(),
|
|
6395
6485
|
relativeDirPath,
|
|
6396
|
-
relativeFilePath
|
|
6486
|
+
relativeFilePath,
|
|
6487
|
+
global = false
|
|
6397
6488
|
}) {
|
|
6398
6489
|
return new _CursorMcp({
|
|
6399
6490
|
baseDir,
|
|
6400
6491
|
relativeDirPath,
|
|
6401
6492
|
relativeFilePath,
|
|
6402
6493
|
fileContent: "{}",
|
|
6403
|
-
validate: false
|
|
6494
|
+
validate: false,
|
|
6495
|
+
global
|
|
6404
6496
|
});
|
|
6405
6497
|
}
|
|
6406
6498
|
};
|
|
@@ -7229,7 +7321,7 @@ var toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
7229
7321
|
class: CursorMcp,
|
|
7230
7322
|
meta: {
|
|
7231
7323
|
supportsProject: true,
|
|
7232
|
-
supportsGlobal:
|
|
7324
|
+
supportsGlobal: true,
|
|
7233
7325
|
supportsEnabledTools: false,
|
|
7234
7326
|
supportsDisabledTools: false
|
|
7235
7327
|
}
|
|
@@ -7942,9 +8034,15 @@ var import_node_path61 = require("path");
|
|
|
7942
8034
|
var DirFeatureProcessor = class {
|
|
7943
8035
|
baseDir;
|
|
7944
8036
|
dryRun;
|
|
7945
|
-
|
|
8037
|
+
avoidBlockScalars;
|
|
8038
|
+
constructor({
|
|
8039
|
+
baseDir = process.cwd(),
|
|
8040
|
+
dryRun = false,
|
|
8041
|
+
avoidBlockScalars = false
|
|
8042
|
+
}) {
|
|
7946
8043
|
this.baseDir = baseDir;
|
|
7947
8044
|
this.dryRun = dryRun;
|
|
8045
|
+
this.avoidBlockScalars = avoidBlockScalars;
|
|
7948
8046
|
}
|
|
7949
8047
|
/**
|
|
7950
8048
|
* Return tool targets that this feature supports.
|
|
@@ -7970,7 +8068,9 @@ var DirFeatureProcessor = class {
|
|
|
7970
8068
|
let mainFileContent;
|
|
7971
8069
|
if (mainFile) {
|
|
7972
8070
|
const mainFilePath = (0, import_node_path61.join)(dirPath, mainFile.name);
|
|
7973
|
-
const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter
|
|
8071
|
+
const content = stringifyFrontmatter(mainFile.body, mainFile.frontmatter, {
|
|
8072
|
+
avoidBlockScalars: this.avoidBlockScalars
|
|
8073
|
+
});
|
|
7974
8074
|
mainFileContent = addTrailingNewline(content);
|
|
7975
8075
|
const existingContent = await readFileContentOrNull(mainFilePath);
|
|
7976
8076
|
if (existingContent !== mainFileContent) {
|
|
@@ -10709,7 +10809,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
10709
10809
|
getFactory = defaultGetFactory4,
|
|
10710
10810
|
dryRun = false
|
|
10711
10811
|
}) {
|
|
10712
|
-
super({ baseDir, dryRun });
|
|
10812
|
+
super({ baseDir, dryRun, avoidBlockScalars: toolTarget === "cursor" });
|
|
10713
10813
|
const result = SkillsProcessorToolTargetSchema.safeParse(toolTarget);
|
|
10714
10814
|
if (!result.success) {
|
|
10715
10815
|
throw new Error(
|
|
@@ -11790,7 +11890,7 @@ var CursorSubagent = class _CursorSubagent extends ToolSubagent {
|
|
|
11790
11890
|
...cursorSection
|
|
11791
11891
|
};
|
|
11792
11892
|
const body = rulesyncSubagent.getBody();
|
|
11793
|
-
const fileContent = stringifyFrontmatter(body, cursorFrontmatter);
|
|
11893
|
+
const fileContent = stringifyFrontmatter(body, cursorFrontmatter, { avoidBlockScalars: true });
|
|
11794
11894
|
const paths = this.getSettablePaths({ global });
|
|
11795
11895
|
return new _CursorSubagent({
|
|
11796
11896
|
baseDir,
|
package/dist/index.js
CHANGED