rulesync 3.23.6 → 3.25.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 +89 -33
- package/dist/index.cjs +1923 -485
- package/dist/index.js +1923 -485
- package/package.json +18 -18
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ var ANNOUNCEMENT = "".trim();
|
|
|
8
8
|
|
|
9
9
|
// src/types/features.ts
|
|
10
10
|
import { z } from "zod/mini";
|
|
11
|
-
var ALL_FEATURES = ["rules", "ignore", "mcp", "subagents", "commands"];
|
|
11
|
+
var ALL_FEATURES = ["rules", "ignore", "mcp", "subagents", "commands", "skills"];
|
|
12
12
|
var ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
|
|
13
13
|
var FeatureSchema = z.enum(ALL_FEATURES);
|
|
14
14
|
var FeaturesSchema = z.array(FeatureSchema);
|
|
@@ -137,6 +137,10 @@ async function readFileContent(filepath) {
|
|
|
137
137
|
logger.debug(`Reading file: ${filepath}`);
|
|
138
138
|
return readFile(filepath, "utf-8");
|
|
139
139
|
}
|
|
140
|
+
async function readFileBuffer(filepath) {
|
|
141
|
+
logger.debug(`Reading file buffer: ${filepath}`);
|
|
142
|
+
return readFile(filepath);
|
|
143
|
+
}
|
|
140
144
|
function addTrailingNewline(content) {
|
|
141
145
|
if (!content) {
|
|
142
146
|
return "\n";
|
|
@@ -164,11 +168,32 @@ async function listDirectoryFiles(dir) {
|
|
|
164
168
|
}
|
|
165
169
|
}
|
|
166
170
|
async function findFilesByGlobs(globs, options = {}) {
|
|
171
|
+
const { type = "all" } = options;
|
|
167
172
|
const items = globSync(globs, { withFileTypes: true });
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
switch (type) {
|
|
174
|
+
case "file":
|
|
175
|
+
return items.filter((item) => item.isFile()).map((item) => join(item.parentPath, item.name));
|
|
176
|
+
case "dir":
|
|
177
|
+
return items.filter((item) => item.isDirectory()).map((item) => join(item.parentPath, item.name));
|
|
178
|
+
case "all":
|
|
179
|
+
return items.map((item) => join(item.parentPath, item.name));
|
|
180
|
+
default:
|
|
181
|
+
throw new Error(`Invalid type: ${type}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
async function removeDirectory(dirPath) {
|
|
185
|
+
const dangerousPaths = [".", "/", "~", "src", "node_modules"];
|
|
186
|
+
if (dangerousPaths.includes(dirPath) || dirPath === "") {
|
|
187
|
+
logger.warn(`Skipping deletion of dangerous path: ${dirPath}`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
if (await fileExists(dirPath)) {
|
|
192
|
+
await rm(dirPath, { recursive: true, force: true });
|
|
193
|
+
}
|
|
194
|
+
} catch (error) {
|
|
195
|
+
logger.warn(`Failed to remove directory ${dirPath}:`, error);
|
|
170
196
|
}
|
|
171
|
-
return items.filter((item) => item.isFile()).map((item) => join(item.parentPath, item.name));
|
|
172
197
|
}
|
|
173
198
|
async function removeFile(filepath) {
|
|
174
199
|
logger.debug(`Removing file: ${filepath}`);
|
|
@@ -231,8 +256,9 @@ var ConfigParamsSchema = z3.object({
|
|
|
231
256
|
delete: z3.boolean(),
|
|
232
257
|
// New non-experimental options
|
|
233
258
|
global: optional(z3.boolean()),
|
|
234
|
-
|
|
235
|
-
|
|
259
|
+
simulateCommands: optional(z3.boolean()),
|
|
260
|
+
simulateSubagents: optional(z3.boolean()),
|
|
261
|
+
simulateSkills: optional(z3.boolean()),
|
|
236
262
|
modularMcp: optional(z3.boolean()),
|
|
237
263
|
// Deprecated experimental options (for backward compatibility)
|
|
238
264
|
experimentalGlobal: optional(z3.boolean()),
|
|
@@ -248,8 +274,9 @@ var Config = class {
|
|
|
248
274
|
verbose;
|
|
249
275
|
delete;
|
|
250
276
|
global;
|
|
251
|
-
|
|
252
|
-
|
|
277
|
+
simulateCommands;
|
|
278
|
+
simulateSubagents;
|
|
279
|
+
simulateSkills;
|
|
253
280
|
modularMcp;
|
|
254
281
|
constructor({
|
|
255
282
|
baseDirs,
|
|
@@ -258,8 +285,9 @@ var Config = class {
|
|
|
258
285
|
verbose,
|
|
259
286
|
delete: isDelete,
|
|
260
287
|
global,
|
|
261
|
-
|
|
262
|
-
|
|
288
|
+
simulateCommands,
|
|
289
|
+
simulateSubagents,
|
|
290
|
+
simulateSkills,
|
|
263
291
|
modularMcp,
|
|
264
292
|
experimentalGlobal,
|
|
265
293
|
experimentalSimulateCommands,
|
|
@@ -271,8 +299,9 @@ var Config = class {
|
|
|
271
299
|
this.verbose = verbose;
|
|
272
300
|
this.delete = isDelete;
|
|
273
301
|
this.global = global ?? experimentalGlobal ?? false;
|
|
274
|
-
this.
|
|
275
|
-
this.
|
|
302
|
+
this.simulateCommands = simulateCommands ?? experimentalSimulateCommands ?? false;
|
|
303
|
+
this.simulateSubagents = simulateSubagents ?? experimentalSimulateSubagents ?? false;
|
|
304
|
+
this.simulateSkills = simulateSkills ?? false;
|
|
276
305
|
this.modularMcp = modularMcp ?? false;
|
|
277
306
|
}
|
|
278
307
|
getBaseDirs() {
|
|
@@ -299,11 +328,14 @@ var Config = class {
|
|
|
299
328
|
getGlobal() {
|
|
300
329
|
return this.global;
|
|
301
330
|
}
|
|
302
|
-
|
|
303
|
-
return this.
|
|
331
|
+
getSimulateCommands() {
|
|
332
|
+
return this.simulateCommands;
|
|
304
333
|
}
|
|
305
|
-
|
|
306
|
-
return this.
|
|
334
|
+
getSimulateSubagents() {
|
|
335
|
+
return this.simulateSubagents;
|
|
336
|
+
}
|
|
337
|
+
getSimulateSkills() {
|
|
338
|
+
return this.simulateSkills;
|
|
307
339
|
}
|
|
308
340
|
getModularMcp() {
|
|
309
341
|
return this.modularMcp;
|
|
@@ -313,13 +345,13 @@ var Config = class {
|
|
|
313
345
|
getExperimentalGlobal() {
|
|
314
346
|
return this.global;
|
|
315
347
|
}
|
|
316
|
-
/** @deprecated Use
|
|
348
|
+
/** @deprecated Use getSimulateCommands() instead */
|
|
317
349
|
getExperimentalSimulateCommands() {
|
|
318
|
-
return this.
|
|
350
|
+
return this.simulateCommands;
|
|
319
351
|
}
|
|
320
|
-
/** @deprecated Use
|
|
352
|
+
/** @deprecated Use getSimulateSubagents() instead */
|
|
321
353
|
getExperimentalSimulateSubagents() {
|
|
322
|
-
return this.
|
|
354
|
+
return this.simulateSubagents;
|
|
323
355
|
}
|
|
324
356
|
};
|
|
325
357
|
|
|
@@ -332,8 +364,9 @@ var getDefaults = () => ({
|
|
|
332
364
|
baseDirs: [process.cwd()],
|
|
333
365
|
configPath: "rulesync.jsonc",
|
|
334
366
|
global: false,
|
|
335
|
-
|
|
336
|
-
|
|
367
|
+
simulateCommands: false,
|
|
368
|
+
simulateSubagents: false,
|
|
369
|
+
simulateSkills: false,
|
|
337
370
|
modularMcp: false,
|
|
338
371
|
experimentalGlobal: false,
|
|
339
372
|
experimentalSimulateCommands: false,
|
|
@@ -348,8 +381,9 @@ var ConfigResolver = class {
|
|
|
348
381
|
baseDirs,
|
|
349
382
|
configPath = getDefaults().configPath,
|
|
350
383
|
global,
|
|
351
|
-
|
|
352
|
-
|
|
384
|
+
simulateCommands,
|
|
385
|
+
simulateSubagents,
|
|
386
|
+
simulateSkills,
|
|
353
387
|
modularMcp,
|
|
354
388
|
experimentalGlobal,
|
|
355
389
|
experimentalSimulateCommands,
|
|
@@ -380,8 +414,9 @@ var ConfigResolver = class {
|
|
|
380
414
|
warnDeprecatedOptions({ experimentalSimulateSubagents: deprecatedSubagents });
|
|
381
415
|
}
|
|
382
416
|
const resolvedGlobal = global ?? configByFile.global ?? experimentalGlobal ?? configByFile.experimentalGlobal ?? getDefaults().global;
|
|
383
|
-
const
|
|
384
|
-
const
|
|
417
|
+
const resolvedSimulateCommands = simulateCommands ?? configByFile.simulateCommands ?? experimentalSimulateCommands ?? configByFile.experimentalSimulateCommands ?? getDefaults().simulateCommands;
|
|
418
|
+
const resolvedSimulateSubagents = simulateSubagents ?? configByFile.simulateSubagents ?? experimentalSimulateSubagents ?? configByFile.experimentalSimulateSubagents ?? getDefaults().simulateSubagents;
|
|
419
|
+
const resolvedSimulateSkills = simulateSkills ?? configByFile.simulateSkills ?? getDefaults().simulateSkills;
|
|
385
420
|
const configParams = {
|
|
386
421
|
targets: targets ?? configByFile.targets ?? getDefaults().targets,
|
|
387
422
|
features: features ?? configByFile.features ?? getDefaults().features,
|
|
@@ -392,8 +427,9 @@ var ConfigResolver = class {
|
|
|
392
427
|
global: resolvedGlobal
|
|
393
428
|
}),
|
|
394
429
|
global: resolvedGlobal,
|
|
395
|
-
|
|
396
|
-
|
|
430
|
+
simulateCommands: resolvedSimulateCommands,
|
|
431
|
+
simulateSubagents: resolvedSimulateSubagents,
|
|
432
|
+
simulateSkills: resolvedSimulateSkills,
|
|
397
433
|
modularMcp: modularMcp ?? configByFile.modularMcp ?? getDefaults().modularMcp
|
|
398
434
|
};
|
|
399
435
|
return new Config(configParams);
|
|
@@ -409,12 +445,12 @@ function warnDeprecatedOptions({
|
|
|
409
445
|
}
|
|
410
446
|
if (experimentalSimulateCommands !== void 0) {
|
|
411
447
|
logger.warn(
|
|
412
|
-
"'experimentalSimulateCommands' option is deprecated. Please use '
|
|
448
|
+
"'experimentalSimulateCommands' option is deprecated. Please use 'simulateCommands' instead."
|
|
413
449
|
);
|
|
414
450
|
}
|
|
415
451
|
if (experimentalSimulateSubagents !== void 0) {
|
|
416
452
|
logger.warn(
|
|
417
|
-
"'experimentalSimulateSubagents' option is deprecated. Please use '
|
|
453
|
+
"'experimentalSimulateSubagents' option is deprecated. Please use 'simulateSubagents' instead."
|
|
418
454
|
);
|
|
419
455
|
}
|
|
420
456
|
}
|
|
@@ -1674,7 +1710,7 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1674
1710
|
);
|
|
1675
1711
|
const rulesyncCommands = (await Promise.allSettled(
|
|
1676
1712
|
rulesyncCommandPaths.map(
|
|
1677
|
-
(
|
|
1713
|
+
(path3) => RulesyncCommand.fromFile({ relativeFilePath: basename11(path3) })
|
|
1678
1714
|
)
|
|
1679
1715
|
)).filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
1680
1716
|
logger.info(`Successfully loaded ${rulesyncCommands.length} rulesync commands`);
|
|
@@ -1684,7 +1720,9 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1684
1720
|
* Implementation of abstract method from FeatureProcessor
|
|
1685
1721
|
* Load tool-specific command configurations and parse them into ToolCommand instances
|
|
1686
1722
|
*/
|
|
1687
|
-
async loadToolFiles(
|
|
1723
|
+
async loadToolFiles({
|
|
1724
|
+
forDeletion: _forDeletion = false
|
|
1725
|
+
} = {}) {
|
|
1688
1726
|
switch (this.toolTarget) {
|
|
1689
1727
|
case "agentsmd":
|
|
1690
1728
|
return await this.loadAgentsmdCommands();
|
|
@@ -1704,9 +1742,6 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1704
1742
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
1705
1743
|
}
|
|
1706
1744
|
}
|
|
1707
|
-
async loadToolFilesToDelete() {
|
|
1708
|
-
return this.loadToolFiles();
|
|
1709
|
-
}
|
|
1710
1745
|
async loadToolCommandDefault({
|
|
1711
1746
|
toolTarget,
|
|
1712
1747
|
relativeDirPath,
|
|
@@ -1716,45 +1751,45 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1716
1751
|
join12(this.baseDir, relativeDirPath, `*.${extension}`)
|
|
1717
1752
|
);
|
|
1718
1753
|
const toolCommands = (await Promise.allSettled(
|
|
1719
|
-
commandFilePaths.map((
|
|
1754
|
+
commandFilePaths.map((path3) => {
|
|
1720
1755
|
switch (toolTarget) {
|
|
1721
1756
|
case "agentsmd":
|
|
1722
1757
|
return AgentsmdCommand.fromFile({
|
|
1723
1758
|
baseDir: this.baseDir,
|
|
1724
|
-
relativeFilePath: basename11(
|
|
1759
|
+
relativeFilePath: basename11(path3)
|
|
1725
1760
|
});
|
|
1726
1761
|
case "claudecode":
|
|
1727
1762
|
return ClaudecodeCommand.fromFile({
|
|
1728
1763
|
baseDir: this.baseDir,
|
|
1729
|
-
relativeFilePath: basename11(
|
|
1764
|
+
relativeFilePath: basename11(path3),
|
|
1730
1765
|
global: this.global
|
|
1731
1766
|
});
|
|
1732
1767
|
case "geminicli":
|
|
1733
1768
|
return GeminiCliCommand.fromFile({
|
|
1734
1769
|
baseDir: this.baseDir,
|
|
1735
|
-
relativeFilePath: basename11(
|
|
1770
|
+
relativeFilePath: basename11(path3),
|
|
1736
1771
|
global: this.global
|
|
1737
1772
|
});
|
|
1738
1773
|
case "roo":
|
|
1739
1774
|
return RooCommand.fromFile({
|
|
1740
1775
|
baseDir: this.baseDir,
|
|
1741
|
-
relativeFilePath: basename11(
|
|
1776
|
+
relativeFilePath: basename11(path3)
|
|
1742
1777
|
});
|
|
1743
1778
|
case "copilot":
|
|
1744
1779
|
return CopilotCommand.fromFile({
|
|
1745
1780
|
baseDir: this.baseDir,
|
|
1746
|
-
relativeFilePath: basename11(
|
|
1781
|
+
relativeFilePath: basename11(path3)
|
|
1747
1782
|
});
|
|
1748
1783
|
case "cursor":
|
|
1749
1784
|
return CursorCommand.fromFile({
|
|
1750
1785
|
baseDir: this.baseDir,
|
|
1751
|
-
relativeFilePath: basename11(
|
|
1786
|
+
relativeFilePath: basename11(path3),
|
|
1752
1787
|
global: this.global
|
|
1753
1788
|
});
|
|
1754
1789
|
case "codexcli":
|
|
1755
1790
|
return CodexcliCommand.fromFile({
|
|
1756
1791
|
baseDir: this.baseDir,
|
|
1757
|
-
relativeFilePath: basename11(
|
|
1792
|
+
relativeFilePath: basename11(path3),
|
|
1758
1793
|
global: this.global
|
|
1759
1794
|
});
|
|
1760
1795
|
default:
|
|
@@ -1844,8 +1879,12 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1844
1879
|
* Return the tool targets that this processor supports
|
|
1845
1880
|
*/
|
|
1846
1881
|
static getToolTargets({
|
|
1882
|
+
global = false,
|
|
1847
1883
|
includeSimulated = false
|
|
1848
1884
|
} = {}) {
|
|
1885
|
+
if (global) {
|
|
1886
|
+
return commandsProcessorToolTargetsGlobal;
|
|
1887
|
+
}
|
|
1849
1888
|
if (!includeSimulated) {
|
|
1850
1889
|
return commandsProcessorToolTargets.filter(
|
|
1851
1890
|
(target) => !commandsProcessorToolTargetsSimulated.includes(target)
|
|
@@ -1856,9 +1895,6 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
1856
1895
|
static getToolTargetsSimulated() {
|
|
1857
1896
|
return commandsProcessorToolTargetsSimulated;
|
|
1858
1897
|
}
|
|
1859
|
-
static getToolTargetsGlobal() {
|
|
1860
|
-
return commandsProcessorToolTargetsGlobal;
|
|
1861
|
-
}
|
|
1862
1898
|
};
|
|
1863
1899
|
|
|
1864
1900
|
// src/features/ignore/ignore-processor.ts
|
|
@@ -2282,7 +2318,7 @@ var JunieIgnore = class _JunieIgnore extends ToolIgnore {
|
|
|
2282
2318
|
static getSettablePaths() {
|
|
2283
2319
|
return {
|
|
2284
2320
|
relativeDirPath: ".",
|
|
2285
|
-
relativeFilePath: ".
|
|
2321
|
+
relativeFilePath: ".aiignore"
|
|
2286
2322
|
};
|
|
2287
2323
|
}
|
|
2288
2324
|
toRulesyncIgnore() {
|
|
@@ -2546,9 +2582,14 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
2546
2582
|
* Implementation of abstract method from FeatureProcessor
|
|
2547
2583
|
* Load tool-specific ignore configurations and parse them into ToolIgnore instances
|
|
2548
2584
|
*/
|
|
2549
|
-
async loadToolFiles(
|
|
2585
|
+
async loadToolFiles({
|
|
2586
|
+
forDeletion = false
|
|
2587
|
+
} = {}) {
|
|
2550
2588
|
try {
|
|
2551
2589
|
const toolIgnores = await this.loadToolIgnores();
|
|
2590
|
+
if (forDeletion) {
|
|
2591
|
+
return toolIgnores.filter((toolFile) => !(toolFile instanceof ClaudecodeIgnore));
|
|
2592
|
+
}
|
|
2552
2593
|
return toolIgnores;
|
|
2553
2594
|
} catch (error) {
|
|
2554
2595
|
const errorMessage = `Failed to load tool files: ${formatError(error)}`;
|
|
@@ -2588,11 +2629,6 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
2588
2629
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
2589
2630
|
}
|
|
2590
2631
|
}
|
|
2591
|
-
async loadToolFilesToDelete() {
|
|
2592
|
-
return (await this.loadToolFiles()).filter(
|
|
2593
|
-
(toolFile) => !(toolFile instanceof ClaudecodeIgnore)
|
|
2594
|
-
);
|
|
2595
|
-
}
|
|
2596
2632
|
/**
|
|
2597
2633
|
* Implementation of abstract method from FeatureProcessor
|
|
2598
2634
|
* Convert RulesyncFile[] to ToolFile[]
|
|
@@ -2684,13 +2720,16 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
2684
2720
|
* Implementation of abstract method from FeatureProcessor
|
|
2685
2721
|
* Return the tool targets that this processor supports
|
|
2686
2722
|
*/
|
|
2687
|
-
static getToolTargets() {
|
|
2723
|
+
static getToolTargets({ global = false } = {}) {
|
|
2724
|
+
if (global) {
|
|
2725
|
+
throw new Error("IgnoreProcessor does not support global mode");
|
|
2726
|
+
}
|
|
2688
2727
|
return ignoreProcessorToolTargets;
|
|
2689
2728
|
}
|
|
2690
2729
|
};
|
|
2691
2730
|
|
|
2692
2731
|
// src/features/mcp/mcp-processor.ts
|
|
2693
|
-
import { z as
|
|
2732
|
+
import { z as z16 } from "zod/mini";
|
|
2694
2733
|
|
|
2695
2734
|
// src/features/mcp/amazonqcli-mcp.ts
|
|
2696
2735
|
import { join as join26 } from "path";
|
|
@@ -2819,21 +2858,23 @@ var RulesyncMcp = class _RulesyncMcp extends RulesyncFile {
|
|
|
2819
2858
|
modularMcp
|
|
2820
2859
|
});
|
|
2821
2860
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2861
|
+
getMcpServers({ type = "all" } = {}) {
|
|
2862
|
+
const entries = Object.entries(this.json.mcpServers);
|
|
2863
|
+
const filteredEntries = entries.filter(([, serverConfig]) => {
|
|
2864
|
+
switch (type) {
|
|
2865
|
+
case "all":
|
|
2866
|
+
return true;
|
|
2867
|
+
case "exposed":
|
|
2868
|
+
return !this.modularMcp || serverConfig.exposed;
|
|
2869
|
+
case "modularized":
|
|
2870
|
+
return this.modularMcp && !serverConfig.exposed;
|
|
2871
|
+
}
|
|
2872
|
+
});
|
|
2831
2873
|
return Object.fromEntries(
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
])
|
|
2874
|
+
filteredEntries.map(([serverName, serverConfig]) => {
|
|
2875
|
+
const fieldsToOmit = type === "modularized" ? ["targets", "exposed"] : ["targets", "description", "exposed"];
|
|
2876
|
+
return [serverName, omit(serverConfig, fieldsToOmit)];
|
|
2877
|
+
})
|
|
2837
2878
|
);
|
|
2838
2879
|
}
|
|
2839
2880
|
getJson() {
|
|
@@ -3020,7 +3061,7 @@ var ModularMcp = class _ModularMcp extends AiFile {
|
|
|
3020
3061
|
global && relativeDirPath ? { global: true, relativeDirPath } : { global: false, relativeDirPath: void 0 }
|
|
3021
3062
|
);
|
|
3022
3063
|
const modularMcpJson = {
|
|
3023
|
-
mcpServers: rulesyncMcp.
|
|
3064
|
+
mcpServers: rulesyncMcp.getMcpServers({ type: "modularized" })
|
|
3024
3065
|
};
|
|
3025
3066
|
return new _ModularMcp({
|
|
3026
3067
|
baseDir,
|
|
@@ -3103,9 +3144,9 @@ var ClaudecodeMcp = class _ClaudecodeMcp extends ToolMcp {
|
|
|
3103
3144
|
relativeDirPath: this.getSettablePaths({ global: true }).relativeDirPath
|
|
3104
3145
|
}) : ModularMcp.getMcpServers({ baseDir, global: false }),
|
|
3105
3146
|
// Merge exposed servers
|
|
3106
|
-
...rulesyncMcp.
|
|
3147
|
+
...rulesyncMcp.getMcpServers({ type: "exposed" })
|
|
3107
3148
|
}
|
|
3108
|
-
} : { ...json, mcpServers: rulesyncMcp.
|
|
3149
|
+
} : { ...json, mcpServers: rulesyncMcp.getMcpServers({ type: "exposed" }) };
|
|
3109
3150
|
return new _ClaudecodeMcp({
|
|
3110
3151
|
baseDir,
|
|
3111
3152
|
relativeDirPath: paths.relativeDirPath,
|
|
@@ -3474,8 +3515,235 @@ var GeminiCliMcp = class _GeminiCliMcp extends ToolMcp {
|
|
|
3474
3515
|
}
|
|
3475
3516
|
};
|
|
3476
3517
|
|
|
3477
|
-
// src/features/mcp/
|
|
3518
|
+
// src/features/mcp/junie-mcp.ts
|
|
3478
3519
|
import { join as join34 } from "path";
|
|
3520
|
+
var JunieMcp = class _JunieMcp extends ToolMcp {
|
|
3521
|
+
json;
|
|
3522
|
+
constructor(params) {
|
|
3523
|
+
super(params);
|
|
3524
|
+
this.json = this.fileContent !== void 0 ? JSON.parse(this.fileContent) : {};
|
|
3525
|
+
}
|
|
3526
|
+
getJson() {
|
|
3527
|
+
return this.json;
|
|
3528
|
+
}
|
|
3529
|
+
static getSettablePaths() {
|
|
3530
|
+
return {
|
|
3531
|
+
relativeDirPath: join34(".junie", "mcp"),
|
|
3532
|
+
relativeFilePath: "mcp.json"
|
|
3533
|
+
};
|
|
3534
|
+
}
|
|
3535
|
+
static async fromFile({
|
|
3536
|
+
baseDir = process.cwd(),
|
|
3537
|
+
validate = true
|
|
3538
|
+
}) {
|
|
3539
|
+
const fileContent = await readFileContent(
|
|
3540
|
+
join34(
|
|
3541
|
+
baseDir,
|
|
3542
|
+
this.getSettablePaths().relativeDirPath,
|
|
3543
|
+
this.getSettablePaths().relativeFilePath
|
|
3544
|
+
)
|
|
3545
|
+
);
|
|
3546
|
+
return new _JunieMcp({
|
|
3547
|
+
baseDir,
|
|
3548
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
3549
|
+
relativeFilePath: this.getSettablePaths().relativeFilePath,
|
|
3550
|
+
fileContent,
|
|
3551
|
+
validate
|
|
3552
|
+
});
|
|
3553
|
+
}
|
|
3554
|
+
static fromRulesyncMcp({
|
|
3555
|
+
baseDir = process.cwd(),
|
|
3556
|
+
rulesyncMcp,
|
|
3557
|
+
validate = true
|
|
3558
|
+
}) {
|
|
3559
|
+
return new _JunieMcp({
|
|
3560
|
+
baseDir,
|
|
3561
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
3562
|
+
relativeFilePath: this.getSettablePaths().relativeFilePath,
|
|
3563
|
+
fileContent: rulesyncMcp.getFileContent(),
|
|
3564
|
+
validate
|
|
3565
|
+
});
|
|
3566
|
+
}
|
|
3567
|
+
toRulesyncMcp() {
|
|
3568
|
+
return this.toRulesyncMcpDefault();
|
|
3569
|
+
}
|
|
3570
|
+
validate() {
|
|
3571
|
+
return { success: true, error: null };
|
|
3572
|
+
}
|
|
3573
|
+
};
|
|
3574
|
+
|
|
3575
|
+
// src/features/mcp/opencode-mcp.ts
|
|
3576
|
+
import { join as join35 } from "path";
|
|
3577
|
+
import { z as z15 } from "zod/mini";
|
|
3578
|
+
var OpencodeMcpLocalServerSchema = z15.object({
|
|
3579
|
+
type: z15.literal("local"),
|
|
3580
|
+
command: z15.array(z15.string()),
|
|
3581
|
+
environment: z15.optional(z15.record(z15.string(), z15.string())),
|
|
3582
|
+
enabled: z15._default(z15.boolean(), true),
|
|
3583
|
+
cwd: z15.optional(z15.string())
|
|
3584
|
+
});
|
|
3585
|
+
var OpencodeMcpRemoteServerSchema = z15.object({
|
|
3586
|
+
type: z15.literal("remote"),
|
|
3587
|
+
url: z15.string(),
|
|
3588
|
+
headers: z15.optional(z15.record(z15.string(), z15.string())),
|
|
3589
|
+
enabled: z15._default(z15.boolean(), true)
|
|
3590
|
+
});
|
|
3591
|
+
var OpencodeMcpServerSchema = z15.union([
|
|
3592
|
+
OpencodeMcpLocalServerSchema,
|
|
3593
|
+
OpencodeMcpRemoteServerSchema
|
|
3594
|
+
]);
|
|
3595
|
+
var OpencodeConfigSchema = z15.looseObject({
|
|
3596
|
+
$schema: z15.optional(z15.string()),
|
|
3597
|
+
mcp: z15.optional(z15.record(z15.string(), OpencodeMcpServerSchema))
|
|
3598
|
+
});
|
|
3599
|
+
function convertFromOpencodeFormat(opencodeMcp) {
|
|
3600
|
+
return Object.fromEntries(
|
|
3601
|
+
Object.entries(opencodeMcp).map(([serverName, serverConfig]) => {
|
|
3602
|
+
if (serverConfig.type === "remote") {
|
|
3603
|
+
return [
|
|
3604
|
+
serverName,
|
|
3605
|
+
{
|
|
3606
|
+
type: "sse",
|
|
3607
|
+
url: serverConfig.url,
|
|
3608
|
+
...serverConfig.enabled === false && { disabled: true },
|
|
3609
|
+
...serverConfig.headers && { headers: serverConfig.headers }
|
|
3610
|
+
}
|
|
3611
|
+
];
|
|
3612
|
+
}
|
|
3613
|
+
const [command, ...args] = serverConfig.command;
|
|
3614
|
+
if (!command) {
|
|
3615
|
+
throw new Error(`Server "${serverName}" has an empty command array`);
|
|
3616
|
+
}
|
|
3617
|
+
return [
|
|
3618
|
+
serverName,
|
|
3619
|
+
{
|
|
3620
|
+
type: "stdio",
|
|
3621
|
+
command,
|
|
3622
|
+
...args.length > 0 && { args },
|
|
3623
|
+
...serverConfig.enabled === false && { disabled: true },
|
|
3624
|
+
...serverConfig.environment && { env: serverConfig.environment },
|
|
3625
|
+
...serverConfig.cwd && { cwd: serverConfig.cwd }
|
|
3626
|
+
}
|
|
3627
|
+
];
|
|
3628
|
+
})
|
|
3629
|
+
);
|
|
3630
|
+
}
|
|
3631
|
+
function convertToOpencodeFormat(mcpServers) {
|
|
3632
|
+
return Object.fromEntries(
|
|
3633
|
+
Object.entries(mcpServers).map(([serverName, serverConfig]) => {
|
|
3634
|
+
const isRemote = serverConfig.type === "sse" || serverConfig.type === "http" || serverConfig.url;
|
|
3635
|
+
if (isRemote) {
|
|
3636
|
+
const remoteServer = {
|
|
3637
|
+
type: "remote",
|
|
3638
|
+
url: serverConfig.url ?? serverConfig.httpUrl ?? "",
|
|
3639
|
+
enabled: serverConfig.disabled !== void 0 ? !serverConfig.disabled : true,
|
|
3640
|
+
...serverConfig.headers && { headers: serverConfig.headers }
|
|
3641
|
+
};
|
|
3642
|
+
return [serverName, remoteServer];
|
|
3643
|
+
}
|
|
3644
|
+
const commandArray = [];
|
|
3645
|
+
if (serverConfig.command) {
|
|
3646
|
+
if (Array.isArray(serverConfig.command)) {
|
|
3647
|
+
commandArray.push(...serverConfig.command);
|
|
3648
|
+
} else {
|
|
3649
|
+
commandArray.push(serverConfig.command);
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
if (serverConfig.args) {
|
|
3653
|
+
commandArray.push(...serverConfig.args);
|
|
3654
|
+
}
|
|
3655
|
+
const localServer = {
|
|
3656
|
+
type: "local",
|
|
3657
|
+
command: commandArray,
|
|
3658
|
+
enabled: serverConfig.disabled !== void 0 ? !serverConfig.disabled : true,
|
|
3659
|
+
...serverConfig.env && { environment: serverConfig.env },
|
|
3660
|
+
...serverConfig.cwd && { cwd: serverConfig.cwd }
|
|
3661
|
+
};
|
|
3662
|
+
return [serverName, localServer];
|
|
3663
|
+
})
|
|
3664
|
+
);
|
|
3665
|
+
}
|
|
3666
|
+
var OpencodeMcp = class _OpencodeMcp extends ToolMcp {
|
|
3667
|
+
json;
|
|
3668
|
+
constructor(params) {
|
|
3669
|
+
super(params);
|
|
3670
|
+
this.json = OpencodeConfigSchema.parse(JSON.parse(this.fileContent || "{}"));
|
|
3671
|
+
}
|
|
3672
|
+
getJson() {
|
|
3673
|
+
return this.json;
|
|
3674
|
+
}
|
|
3675
|
+
static getSettablePaths({ global } = {}) {
|
|
3676
|
+
if (global) {
|
|
3677
|
+
return {
|
|
3678
|
+
relativeDirPath: ".",
|
|
3679
|
+
relativeFilePath: "opencode.json"
|
|
3680
|
+
};
|
|
3681
|
+
}
|
|
3682
|
+
return {
|
|
3683
|
+
relativeDirPath: ".",
|
|
3684
|
+
relativeFilePath: "opencode.json"
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
static async fromFile({
|
|
3688
|
+
baseDir = process.cwd(),
|
|
3689
|
+
validate = true,
|
|
3690
|
+
global = false
|
|
3691
|
+
}) {
|
|
3692
|
+
const paths = this.getSettablePaths({ global });
|
|
3693
|
+
const fileContent = await readOrInitializeFileContent(
|
|
3694
|
+
join35(baseDir, paths.relativeDirPath, paths.relativeFilePath),
|
|
3695
|
+
JSON.stringify({ mcp: {} }, null, 2)
|
|
3696
|
+
);
|
|
3697
|
+
const json = JSON.parse(fileContent);
|
|
3698
|
+
const newJson = { ...json, mcp: json.mcp ?? {} };
|
|
3699
|
+
return new _OpencodeMcp({
|
|
3700
|
+
baseDir,
|
|
3701
|
+
relativeDirPath: paths.relativeDirPath,
|
|
3702
|
+
relativeFilePath: paths.relativeFilePath,
|
|
3703
|
+
fileContent: JSON.stringify(newJson, null, 2),
|
|
3704
|
+
validate
|
|
3705
|
+
});
|
|
3706
|
+
}
|
|
3707
|
+
static async fromRulesyncMcp({
|
|
3708
|
+
baseDir = process.cwd(),
|
|
3709
|
+
rulesyncMcp,
|
|
3710
|
+
validate = true,
|
|
3711
|
+
global = false
|
|
3712
|
+
}) {
|
|
3713
|
+
const paths = this.getSettablePaths({ global });
|
|
3714
|
+
const fileContent = await readOrInitializeFileContent(
|
|
3715
|
+
join35(baseDir, paths.relativeDirPath, paths.relativeFilePath),
|
|
3716
|
+
JSON.stringify({ mcp: {} }, null, 2)
|
|
3717
|
+
);
|
|
3718
|
+
const json = JSON.parse(fileContent);
|
|
3719
|
+
const convertedMcp = convertToOpencodeFormat(rulesyncMcp.getMcpServers());
|
|
3720
|
+
const newJson = { ...json, mcp: convertedMcp };
|
|
3721
|
+
return new _OpencodeMcp({
|
|
3722
|
+
baseDir,
|
|
3723
|
+
relativeDirPath: paths.relativeDirPath,
|
|
3724
|
+
relativeFilePath: paths.relativeFilePath,
|
|
3725
|
+
fileContent: JSON.stringify(newJson, null, 2),
|
|
3726
|
+
validate
|
|
3727
|
+
});
|
|
3728
|
+
}
|
|
3729
|
+
toRulesyncMcp() {
|
|
3730
|
+
const convertedMcpServers = convertFromOpencodeFormat(this.json.mcp ?? {});
|
|
3731
|
+
return this.toRulesyncMcpDefault({
|
|
3732
|
+
fileContent: JSON.stringify({ mcpServers: convertedMcpServers }, null, 2)
|
|
3733
|
+
});
|
|
3734
|
+
}
|
|
3735
|
+
validate() {
|
|
3736
|
+
const json = JSON.parse(this.fileContent || "{}");
|
|
3737
|
+
const result = OpencodeConfigSchema.safeParse(json);
|
|
3738
|
+
if (!result.success) {
|
|
3739
|
+
return { success: false, error: result.error };
|
|
3740
|
+
}
|
|
3741
|
+
return { success: true, error: null };
|
|
3742
|
+
}
|
|
3743
|
+
};
|
|
3744
|
+
|
|
3745
|
+
// src/features/mcp/roo-mcp.ts
|
|
3746
|
+
import { join as join36 } from "path";
|
|
3479
3747
|
var RooMcp = class _RooMcp extends ToolMcp {
|
|
3480
3748
|
json;
|
|
3481
3749
|
constructor(params) {
|
|
@@ -3496,7 +3764,7 @@ var RooMcp = class _RooMcp extends ToolMcp {
|
|
|
3496
3764
|
validate = true
|
|
3497
3765
|
}) {
|
|
3498
3766
|
const fileContent = await readFileContent(
|
|
3499
|
-
|
|
3767
|
+
join36(
|
|
3500
3768
|
baseDir,
|
|
3501
3769
|
this.getSettablePaths().relativeDirPath,
|
|
3502
3770
|
this.getSettablePaths().relativeFilePath
|
|
@@ -3537,16 +3805,23 @@ var mcpProcessorToolTargets = [
|
|
|
3537
3805
|
"amazonqcli",
|
|
3538
3806
|
"claudecode",
|
|
3539
3807
|
"cline",
|
|
3808
|
+
"junie",
|
|
3540
3809
|
"copilot",
|
|
3541
3810
|
"cursor",
|
|
3542
3811
|
"geminicli",
|
|
3812
|
+
"opencode",
|
|
3543
3813
|
"roo"
|
|
3544
3814
|
];
|
|
3545
|
-
var McpProcessorToolTargetSchema =
|
|
3815
|
+
var McpProcessorToolTargetSchema = z16.enum(
|
|
3546
3816
|
// codexcli is not in the list of tool targets but we add it here because it is a valid tool target for global mode generation
|
|
3547
3817
|
mcpProcessorToolTargets.concat("codexcli")
|
|
3548
3818
|
);
|
|
3549
|
-
var mcpProcessorToolTargetsGlobal = [
|
|
3819
|
+
var mcpProcessorToolTargetsGlobal = [
|
|
3820
|
+
"claudecode",
|
|
3821
|
+
"codexcli",
|
|
3822
|
+
"geminicli",
|
|
3823
|
+
"opencode"
|
|
3824
|
+
];
|
|
3550
3825
|
var mcpProcessorToolTargetsModular = ["claudecode"];
|
|
3551
3826
|
var McpProcessor = class extends FeatureProcessor {
|
|
3552
3827
|
toolTarget;
|
|
@@ -3581,19 +3856,13 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3581
3856
|
return [];
|
|
3582
3857
|
}
|
|
3583
3858
|
}
|
|
3584
|
-
async loadToolFilesToDelete() {
|
|
3585
|
-
if (this.global) {
|
|
3586
|
-
return (await this.loadToolFiles()).filter(
|
|
3587
|
-
(toolFile) => !(toolFile instanceof ClaudecodeMcp)
|
|
3588
|
-
);
|
|
3589
|
-
}
|
|
3590
|
-
return this.loadToolFiles();
|
|
3591
|
-
}
|
|
3592
3859
|
/**
|
|
3593
3860
|
* Implementation of abstract method from FeatureProcessor
|
|
3594
3861
|
* Load tool-specific MCP configurations and parse them into ToolMcp instances
|
|
3595
3862
|
*/
|
|
3596
|
-
async loadToolFiles(
|
|
3863
|
+
async loadToolFiles({
|
|
3864
|
+
forDeletion = false
|
|
3865
|
+
} = {}) {
|
|
3597
3866
|
try {
|
|
3598
3867
|
const toolMcps = await (async () => {
|
|
3599
3868
|
switch (this.toolTarget) {
|
|
@@ -3622,6 +3891,14 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3622
3891
|
})
|
|
3623
3892
|
];
|
|
3624
3893
|
}
|
|
3894
|
+
case "junie": {
|
|
3895
|
+
return [
|
|
3896
|
+
await JunieMcp.fromFile({
|
|
3897
|
+
baseDir: this.baseDir,
|
|
3898
|
+
validate: true
|
|
3899
|
+
})
|
|
3900
|
+
];
|
|
3901
|
+
}
|
|
3625
3902
|
case "codexcli": {
|
|
3626
3903
|
return [
|
|
3627
3904
|
await CodexcliMcp.fromFile({
|
|
@@ -3656,6 +3933,15 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3656
3933
|
})
|
|
3657
3934
|
];
|
|
3658
3935
|
}
|
|
3936
|
+
case "opencode": {
|
|
3937
|
+
return [
|
|
3938
|
+
await OpencodeMcp.fromFile({
|
|
3939
|
+
baseDir: this.baseDir,
|
|
3940
|
+
validate: true,
|
|
3941
|
+
global: this.global
|
|
3942
|
+
})
|
|
3943
|
+
];
|
|
3944
|
+
}
|
|
3659
3945
|
case "roo": {
|
|
3660
3946
|
return [
|
|
3661
3947
|
await RooMcp.fromFile({
|
|
@@ -3669,6 +3955,13 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3669
3955
|
}
|
|
3670
3956
|
})();
|
|
3671
3957
|
logger.info(`Successfully loaded ${toolMcps.length} ${this.toolTarget} MCP files`);
|
|
3958
|
+
if (forDeletion) {
|
|
3959
|
+
let filteredMcps = toolMcps.filter((toolFile) => !(toolFile instanceof OpencodeMcp));
|
|
3960
|
+
if (this.global) {
|
|
3961
|
+
filteredMcps = filteredMcps.filter((toolFile) => !(toolFile instanceof ClaudecodeMcp));
|
|
3962
|
+
}
|
|
3963
|
+
return filteredMcps;
|
|
3964
|
+
}
|
|
3672
3965
|
return toolMcps;
|
|
3673
3966
|
} catch (error) {
|
|
3674
3967
|
const errorMessage = `Failed to load MCP files for tool target: ${this.toolTarget}: ${formatError(error)}`;
|
|
@@ -3677,119 +3970,1159 @@ var McpProcessor = class extends FeatureProcessor {
|
|
|
3677
3970
|
} else {
|
|
3678
3971
|
logger.error(errorMessage);
|
|
3679
3972
|
}
|
|
3680
|
-
return [];
|
|
3973
|
+
return [];
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3976
|
+
/**
|
|
3977
|
+
* Implementation of abstract method from FeatureProcessor
|
|
3978
|
+
* Convert RulesyncFile[] to ToolFile[]
|
|
3979
|
+
*/
|
|
3980
|
+
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
3981
|
+
const rulesyncMcp = rulesyncFiles.find(
|
|
3982
|
+
(file) => file instanceof RulesyncMcp
|
|
3983
|
+
);
|
|
3984
|
+
if (!rulesyncMcp) {
|
|
3985
|
+
throw new Error(`No ${RULESYNC_MCP_RELATIVE_FILE_PATH} found.`);
|
|
3986
|
+
}
|
|
3987
|
+
const toolMcps = await Promise.all(
|
|
3988
|
+
[rulesyncMcp].map(async (rulesyncMcp2) => {
|
|
3989
|
+
switch (this.toolTarget) {
|
|
3990
|
+
case "amazonqcli":
|
|
3991
|
+
return AmazonqcliMcp.fromRulesyncMcp({
|
|
3992
|
+
baseDir: this.baseDir,
|
|
3993
|
+
rulesyncMcp: rulesyncMcp2
|
|
3994
|
+
});
|
|
3995
|
+
case "claudecode":
|
|
3996
|
+
return await ClaudecodeMcp.fromRulesyncMcp({
|
|
3997
|
+
baseDir: this.baseDir,
|
|
3998
|
+
rulesyncMcp: rulesyncMcp2,
|
|
3999
|
+
global: this.global,
|
|
4000
|
+
modularMcp: this.modularMcp
|
|
4001
|
+
});
|
|
4002
|
+
case "cline":
|
|
4003
|
+
return ClineMcp.fromRulesyncMcp({
|
|
4004
|
+
baseDir: this.baseDir,
|
|
4005
|
+
rulesyncMcp: rulesyncMcp2
|
|
4006
|
+
});
|
|
4007
|
+
case "junie":
|
|
4008
|
+
return JunieMcp.fromRulesyncMcp({
|
|
4009
|
+
baseDir: this.baseDir,
|
|
4010
|
+
rulesyncMcp: rulesyncMcp2
|
|
4011
|
+
});
|
|
4012
|
+
case "copilot":
|
|
4013
|
+
return CopilotMcp.fromRulesyncMcp({
|
|
4014
|
+
baseDir: this.baseDir,
|
|
4015
|
+
rulesyncMcp: rulesyncMcp2
|
|
4016
|
+
});
|
|
4017
|
+
case "cursor":
|
|
4018
|
+
return CursorMcp.fromRulesyncMcp({
|
|
4019
|
+
baseDir: this.baseDir,
|
|
4020
|
+
rulesyncMcp: rulesyncMcp2
|
|
4021
|
+
});
|
|
4022
|
+
case "codexcli":
|
|
4023
|
+
return await CodexcliMcp.fromRulesyncMcp({
|
|
4024
|
+
baseDir: this.baseDir,
|
|
4025
|
+
rulesyncMcp: rulesyncMcp2,
|
|
4026
|
+
global: this.global
|
|
4027
|
+
});
|
|
4028
|
+
case "geminicli":
|
|
4029
|
+
return GeminiCliMcp.fromRulesyncMcp({
|
|
4030
|
+
baseDir: this.baseDir,
|
|
4031
|
+
rulesyncMcp: rulesyncMcp2,
|
|
4032
|
+
global: this.global
|
|
4033
|
+
});
|
|
4034
|
+
case "opencode":
|
|
4035
|
+
return OpencodeMcp.fromRulesyncMcp({
|
|
4036
|
+
baseDir: this.baseDir,
|
|
4037
|
+
rulesyncMcp: rulesyncMcp2,
|
|
4038
|
+
global: this.global
|
|
4039
|
+
});
|
|
4040
|
+
case "roo":
|
|
4041
|
+
return RooMcp.fromRulesyncMcp({
|
|
4042
|
+
baseDir: this.baseDir,
|
|
4043
|
+
rulesyncMcp: rulesyncMcp2
|
|
4044
|
+
});
|
|
4045
|
+
default:
|
|
4046
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
4047
|
+
}
|
|
4048
|
+
})
|
|
4049
|
+
);
|
|
4050
|
+
const toolFiles = toolMcps;
|
|
4051
|
+
if (this.modularMcp && mcpProcessorToolTargetsModular.includes(this.toolTarget)) {
|
|
4052
|
+
const relativeDirPath = this.toolTarget === "claudecode" ? ClaudecodeMcp.getSettablePaths({ global: this.global }).relativeDirPath : void 0;
|
|
4053
|
+
toolFiles.push(
|
|
4054
|
+
ModularMcp.fromRulesyncMcp({
|
|
4055
|
+
baseDir: this.baseDir,
|
|
4056
|
+
rulesyncMcp,
|
|
4057
|
+
...this.global && relativeDirPath ? { global: true, relativeDirPath } : { global: false }
|
|
4058
|
+
})
|
|
4059
|
+
);
|
|
4060
|
+
}
|
|
4061
|
+
return toolFiles;
|
|
4062
|
+
}
|
|
4063
|
+
/**
|
|
4064
|
+
* Implementation of abstract method from FeatureProcessor
|
|
4065
|
+
* Convert ToolFile[] to RulesyncFile[]
|
|
4066
|
+
*/
|
|
4067
|
+
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
4068
|
+
const toolMcps = toolFiles.filter((file) => file instanceof ToolMcp);
|
|
4069
|
+
const rulesyncMcps = toolMcps.map((toolMcp) => {
|
|
4070
|
+
return toolMcp.toRulesyncMcp();
|
|
4071
|
+
});
|
|
4072
|
+
return rulesyncMcps;
|
|
4073
|
+
}
|
|
4074
|
+
/**
|
|
4075
|
+
* Implementation of abstract method from FeatureProcessor
|
|
4076
|
+
* Return the tool targets that this processor supports
|
|
4077
|
+
*/
|
|
4078
|
+
static getToolTargets({ global = false } = {}) {
|
|
4079
|
+
if (global) {
|
|
4080
|
+
return mcpProcessorToolTargetsGlobal;
|
|
4081
|
+
}
|
|
4082
|
+
return mcpProcessorToolTargets;
|
|
4083
|
+
}
|
|
4084
|
+
};
|
|
4085
|
+
|
|
4086
|
+
// src/features/rules/rules-processor.ts
|
|
4087
|
+
import { basename as basename19, join as join77 } from "path";
|
|
4088
|
+
import { XMLBuilder } from "fast-xml-parser";
|
|
4089
|
+
import { z as z29 } from "zod/mini";
|
|
4090
|
+
|
|
4091
|
+
// src/features/skills/codexcli-skill.ts
|
|
4092
|
+
import { join as join39 } from "path";
|
|
4093
|
+
|
|
4094
|
+
// src/features/skills/simulated-skill.ts
|
|
4095
|
+
import { join as join38 } from "path";
|
|
4096
|
+
import { z as z17 } from "zod/mini";
|
|
4097
|
+
|
|
4098
|
+
// src/constants/general.ts
|
|
4099
|
+
var SKILL_FILE_NAME = "SKILL.md";
|
|
4100
|
+
|
|
4101
|
+
// src/types/ai-dir.ts
|
|
4102
|
+
import path2, { basename as basename12, join as join37, relative as relative3, resolve as resolve4 } from "path";
|
|
4103
|
+
var AiDir = class {
|
|
4104
|
+
/**
|
|
4105
|
+
* @example "."
|
|
4106
|
+
*/
|
|
4107
|
+
baseDir;
|
|
4108
|
+
/**
|
|
4109
|
+
* @example ".rulesync/skills"
|
|
4110
|
+
*/
|
|
4111
|
+
relativeDirPath;
|
|
4112
|
+
/**
|
|
4113
|
+
* @example "my-skill"
|
|
4114
|
+
*/
|
|
4115
|
+
dirName;
|
|
4116
|
+
/**
|
|
4117
|
+
* Optional main file with frontmatter support
|
|
4118
|
+
*/
|
|
4119
|
+
mainFile;
|
|
4120
|
+
/**
|
|
4121
|
+
* Additional files in the directory
|
|
4122
|
+
*/
|
|
4123
|
+
otherFiles;
|
|
4124
|
+
/**
|
|
4125
|
+
* @example false
|
|
4126
|
+
*/
|
|
4127
|
+
global;
|
|
4128
|
+
constructor({
|
|
4129
|
+
baseDir = process.cwd(),
|
|
4130
|
+
relativeDirPath,
|
|
4131
|
+
dirName,
|
|
4132
|
+
mainFile,
|
|
4133
|
+
otherFiles = [],
|
|
4134
|
+
global = false
|
|
4135
|
+
}) {
|
|
4136
|
+
if (dirName.includes(path2.sep) || dirName.includes("/") || dirName.includes("\\")) {
|
|
4137
|
+
throw new Error(`Directory name cannot contain path separators: dirName="${dirName}"`);
|
|
4138
|
+
}
|
|
4139
|
+
this.baseDir = baseDir;
|
|
4140
|
+
this.relativeDirPath = relativeDirPath;
|
|
4141
|
+
this.dirName = dirName;
|
|
4142
|
+
this.mainFile = mainFile;
|
|
4143
|
+
this.otherFiles = otherFiles;
|
|
4144
|
+
this.global = global;
|
|
4145
|
+
}
|
|
4146
|
+
static async fromDir(_params) {
|
|
4147
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4148
|
+
}
|
|
4149
|
+
getBaseDir() {
|
|
4150
|
+
return this.baseDir;
|
|
4151
|
+
}
|
|
4152
|
+
getRelativeDirPath() {
|
|
4153
|
+
return this.relativeDirPath;
|
|
4154
|
+
}
|
|
4155
|
+
getDirName() {
|
|
4156
|
+
return this.dirName;
|
|
4157
|
+
}
|
|
4158
|
+
getDirPath() {
|
|
4159
|
+
const fullPath = path2.join(this.baseDir, this.relativeDirPath, this.dirName);
|
|
4160
|
+
const resolvedFull = resolve4(fullPath);
|
|
4161
|
+
const resolvedBase = resolve4(this.baseDir);
|
|
4162
|
+
const rel = relative3(resolvedBase, resolvedFull);
|
|
4163
|
+
if (rel.startsWith("..") || path2.isAbsolute(rel)) {
|
|
4164
|
+
throw new Error(
|
|
4165
|
+
`Path traversal detected: Final path escapes baseDir. baseDir="${this.baseDir}", relativeDirPath="${this.relativeDirPath}", dirName="${this.dirName}"`
|
|
4166
|
+
);
|
|
4167
|
+
}
|
|
4168
|
+
return fullPath;
|
|
4169
|
+
}
|
|
4170
|
+
getMainFile() {
|
|
4171
|
+
return this.mainFile;
|
|
4172
|
+
}
|
|
4173
|
+
getOtherFiles() {
|
|
4174
|
+
return this.otherFiles;
|
|
4175
|
+
}
|
|
4176
|
+
getRelativePathFromCwd() {
|
|
4177
|
+
return path2.join(this.relativeDirPath, this.dirName);
|
|
4178
|
+
}
|
|
4179
|
+
getGlobal() {
|
|
4180
|
+
return this.global;
|
|
4181
|
+
}
|
|
4182
|
+
setMainFile(name, body, frontmatter) {
|
|
4183
|
+
this.mainFile = { name, body, frontmatter };
|
|
4184
|
+
}
|
|
4185
|
+
/**
|
|
4186
|
+
* Recursively collects all files from a directory, excluding the specified main file.
|
|
4187
|
+
* This is a common utility for loading additional files alongside the main file.
|
|
4188
|
+
*
|
|
4189
|
+
* @param baseDir - The base directory path
|
|
4190
|
+
* @param relativeDirPath - The relative path to the directory containing the skill
|
|
4191
|
+
* @param dirName - The name of the directory
|
|
4192
|
+
* @param excludeFileName - The name of the file to exclude (typically the main file)
|
|
4193
|
+
* @returns Array of files with their relative paths and buffers
|
|
4194
|
+
*/
|
|
4195
|
+
static async collectOtherFiles(baseDir, relativeDirPath, dirName, excludeFileName) {
|
|
4196
|
+
const dirPath = join37(baseDir, relativeDirPath, dirName);
|
|
4197
|
+
const glob = join37(dirPath, "**", "*");
|
|
4198
|
+
const filePaths = await findFilesByGlobs(glob, { type: "file" });
|
|
4199
|
+
const filteredPaths = filePaths.filter((filePath) => basename12(filePath) !== excludeFileName);
|
|
4200
|
+
const files = await Promise.all(
|
|
4201
|
+
filteredPaths.map(async (filePath) => {
|
|
4202
|
+
const fileBuffer = await readFileBuffer(filePath);
|
|
4203
|
+
return {
|
|
4204
|
+
relativeFilePathToDirPath: relative3(dirPath, filePath),
|
|
4205
|
+
fileBuffer
|
|
4206
|
+
};
|
|
4207
|
+
})
|
|
4208
|
+
);
|
|
4209
|
+
return files;
|
|
4210
|
+
}
|
|
4211
|
+
};
|
|
4212
|
+
|
|
4213
|
+
// src/features/skills/tool-skill.ts
|
|
4214
|
+
var ToolSkill = class extends AiDir {
|
|
4215
|
+
/**
|
|
4216
|
+
* Get the settable paths for this tool's skill directories.
|
|
4217
|
+
*
|
|
4218
|
+
* @param options - Optional configuration including global mode
|
|
4219
|
+
* @returns Object containing the relative directory path
|
|
4220
|
+
*/
|
|
4221
|
+
static getSettablePaths(_options) {
|
|
4222
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4223
|
+
}
|
|
4224
|
+
/**
|
|
4225
|
+
* Load a skill from a tool-specific directory.
|
|
4226
|
+
*
|
|
4227
|
+
* This method should:
|
|
4228
|
+
* 1. Read the SKILL.md file content
|
|
4229
|
+
* 2. Parse tool-specific frontmatter format
|
|
4230
|
+
* 3. Validate the parsed data
|
|
4231
|
+
* 4. Collect other skill files in the directory
|
|
4232
|
+
* 5. Return a concrete ToolSkill instance
|
|
4233
|
+
*
|
|
4234
|
+
* @param params - Parameters including the skill directory name
|
|
4235
|
+
* @returns Promise resolving to a concrete ToolSkill instance
|
|
4236
|
+
*/
|
|
4237
|
+
static async fromDir(_params) {
|
|
4238
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4239
|
+
}
|
|
4240
|
+
/**
|
|
4241
|
+
* Convert a RulesyncSkill to the tool-specific skill format.
|
|
4242
|
+
*
|
|
4243
|
+
* This method should:
|
|
4244
|
+
* 1. Extract relevant data from the RulesyncSkill
|
|
4245
|
+
* 2. Transform frontmatter to tool-specific format
|
|
4246
|
+
* 3. Transform body content if needed
|
|
4247
|
+
* 4. Preserve other skill files
|
|
4248
|
+
* 5. Return a concrete ToolSkill instance
|
|
4249
|
+
*
|
|
4250
|
+
* @param params - Parameters including the RulesyncSkill to convert
|
|
4251
|
+
* @returns A concrete ToolSkill instance
|
|
4252
|
+
*/
|
|
4253
|
+
static fromRulesyncSkill(_params) {
|
|
4254
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4255
|
+
}
|
|
4256
|
+
/**
|
|
4257
|
+
* Check if this tool is targeted by a RulesyncSkill.
|
|
4258
|
+
* Since skills don't have targets field like commands/subagents,
|
|
4259
|
+
* the default behavior may vary by tool.
|
|
4260
|
+
*
|
|
4261
|
+
* @param rulesyncSkill - The RulesyncSkill to check
|
|
4262
|
+
* @returns True if this tool should use the skill
|
|
4263
|
+
*/
|
|
4264
|
+
static isTargetedByRulesyncSkill(_rulesyncSkill) {
|
|
4265
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4266
|
+
}
|
|
4267
|
+
};
|
|
4268
|
+
|
|
4269
|
+
// src/features/skills/simulated-skill.ts
|
|
4270
|
+
var SimulatedSkillFrontmatterSchema = z17.object({
|
|
4271
|
+
name: z17.string(),
|
|
4272
|
+
description: z17.string()
|
|
4273
|
+
});
|
|
4274
|
+
var SimulatedSkill = class extends ToolSkill {
|
|
4275
|
+
frontmatter;
|
|
4276
|
+
body;
|
|
4277
|
+
constructor({
|
|
4278
|
+
baseDir = process.cwd(),
|
|
4279
|
+
relativeDirPath,
|
|
4280
|
+
dirName,
|
|
4281
|
+
frontmatter,
|
|
4282
|
+
body,
|
|
4283
|
+
otherFiles = [],
|
|
4284
|
+
validate = true
|
|
4285
|
+
}) {
|
|
4286
|
+
super({
|
|
4287
|
+
baseDir,
|
|
4288
|
+
relativeDirPath,
|
|
4289
|
+
dirName,
|
|
4290
|
+
mainFile: {
|
|
4291
|
+
name: SKILL_FILE_NAME,
|
|
4292
|
+
body,
|
|
4293
|
+
frontmatter: { ...frontmatter }
|
|
4294
|
+
},
|
|
4295
|
+
otherFiles,
|
|
4296
|
+
global: false
|
|
4297
|
+
// Simulated skills are project mode only
|
|
4298
|
+
});
|
|
4299
|
+
if (validate) {
|
|
4300
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4301
|
+
if (!result.success) {
|
|
4302
|
+
throw new Error(
|
|
4303
|
+
`Invalid frontmatter in ${join38(relativeDirPath, dirName)}: ${formatError(result.error)}`
|
|
4304
|
+
);
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
4307
|
+
this.frontmatter = frontmatter;
|
|
4308
|
+
this.body = body;
|
|
4309
|
+
}
|
|
4310
|
+
getBody() {
|
|
4311
|
+
return this.body;
|
|
4312
|
+
}
|
|
4313
|
+
getFrontmatter() {
|
|
4314
|
+
return this.frontmatter;
|
|
4315
|
+
}
|
|
4316
|
+
toRulesyncSkill() {
|
|
4317
|
+
throw new Error("Not implemented because it is a SIMULATED skill.");
|
|
4318
|
+
}
|
|
4319
|
+
validate() {
|
|
4320
|
+
if (!this.frontmatter) {
|
|
4321
|
+
return { success: true, error: null };
|
|
4322
|
+
}
|
|
4323
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(this.frontmatter);
|
|
4324
|
+
if (result.success) {
|
|
4325
|
+
return { success: true, error: null };
|
|
4326
|
+
} else {
|
|
4327
|
+
return {
|
|
4328
|
+
success: false,
|
|
4329
|
+
error: new Error(
|
|
4330
|
+
`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
|
|
4331
|
+
)
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4334
|
+
}
|
|
4335
|
+
static fromRulesyncSkillDefault({
|
|
4336
|
+
rulesyncSkill,
|
|
4337
|
+
validate = true
|
|
4338
|
+
}) {
|
|
4339
|
+
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
4340
|
+
const simulatedFrontmatter = {
|
|
4341
|
+
name: rulesyncFrontmatter.name,
|
|
4342
|
+
description: rulesyncFrontmatter.description
|
|
4343
|
+
};
|
|
4344
|
+
const otherFiles = rulesyncSkill.getOtherFiles();
|
|
4345
|
+
if (otherFiles.length > 0) {
|
|
4346
|
+
logger.warn(
|
|
4347
|
+
`Skill "${rulesyncFrontmatter.name}" has ${otherFiles.length} additional file(s) that will be ignored for simulated skill generation.`
|
|
4348
|
+
);
|
|
4349
|
+
}
|
|
4350
|
+
return {
|
|
4351
|
+
baseDir: rulesyncSkill.getBaseDir(),
|
|
4352
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
4353
|
+
dirName: rulesyncSkill.getDirName(),
|
|
4354
|
+
frontmatter: simulatedFrontmatter,
|
|
4355
|
+
body: rulesyncSkill.getBody(),
|
|
4356
|
+
otherFiles: [],
|
|
4357
|
+
// Simulated skills ignore otherFiles
|
|
4358
|
+
validate
|
|
4359
|
+
};
|
|
4360
|
+
}
|
|
4361
|
+
static async fromDirDefault({
|
|
4362
|
+
baseDir = process.cwd(),
|
|
4363
|
+
relativeDirPath,
|
|
4364
|
+
dirName
|
|
4365
|
+
}) {
|
|
4366
|
+
const settablePaths = this.getSettablePaths();
|
|
4367
|
+
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
4368
|
+
const skillDirPath = join38(baseDir, actualRelativeDirPath, dirName);
|
|
4369
|
+
const skillFilePath = join38(skillDirPath, SKILL_FILE_NAME);
|
|
4370
|
+
if (!await fileExists(skillFilePath)) {
|
|
4371
|
+
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4372
|
+
}
|
|
4373
|
+
const fileContent = await readFileContent(skillFilePath);
|
|
4374
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4375
|
+
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4376
|
+
if (!result.success) {
|
|
4377
|
+
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4378
|
+
}
|
|
4379
|
+
return {
|
|
4380
|
+
baseDir,
|
|
4381
|
+
relativeDirPath: actualRelativeDirPath,
|
|
4382
|
+
dirName,
|
|
4383
|
+
frontmatter: result.data,
|
|
4384
|
+
body: content.trim(),
|
|
4385
|
+
otherFiles: [],
|
|
4386
|
+
// Simulated skills ignore otherFiles
|
|
4387
|
+
validate: true
|
|
4388
|
+
};
|
|
4389
|
+
}
|
|
4390
|
+
/**
|
|
4391
|
+
* Check if a RulesyncSkill should be converted to this simulated skill type.
|
|
4392
|
+
* Uses the targets field in the RulesyncSkill frontmatter to determine targeting.
|
|
4393
|
+
*/
|
|
4394
|
+
static isTargetedByRulesyncSkillDefault({
|
|
4395
|
+
rulesyncSkill,
|
|
4396
|
+
toolTarget
|
|
4397
|
+
}) {
|
|
4398
|
+
const frontmatter = rulesyncSkill.getFrontmatter();
|
|
4399
|
+
const targets = frontmatter.targets;
|
|
4400
|
+
if (targets.includes("*")) {
|
|
4401
|
+
return true;
|
|
4402
|
+
}
|
|
4403
|
+
return targets.includes(toolTarget);
|
|
4404
|
+
}
|
|
4405
|
+
/**
|
|
4406
|
+
* Get the settable paths for this tool's skill directories.
|
|
4407
|
+
* Must be implemented by concrete subclasses.
|
|
4408
|
+
*/
|
|
4409
|
+
static getSettablePaths(_options) {
|
|
4410
|
+
throw new Error("Please implement this method in the subclass.");
|
|
4411
|
+
}
|
|
4412
|
+
};
|
|
4413
|
+
|
|
4414
|
+
// src/features/skills/codexcli-skill.ts
|
|
4415
|
+
var CodexCliSkill = class _CodexCliSkill extends SimulatedSkill {
|
|
4416
|
+
static getSettablePaths(options) {
|
|
4417
|
+
if (options?.global) {
|
|
4418
|
+
throw new Error("CodexCliSkill does not support global mode.");
|
|
4419
|
+
}
|
|
4420
|
+
return {
|
|
4421
|
+
relativeDirPath: join39(".codex", "skills")
|
|
4422
|
+
};
|
|
4423
|
+
}
|
|
4424
|
+
static async fromDir(params) {
|
|
4425
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4426
|
+
return new _CodexCliSkill(baseParams);
|
|
4427
|
+
}
|
|
4428
|
+
static fromRulesyncSkill(params) {
|
|
4429
|
+
const baseParams = {
|
|
4430
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4431
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4432
|
+
};
|
|
4433
|
+
return new _CodexCliSkill(baseParams);
|
|
4434
|
+
}
|
|
4435
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4436
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4437
|
+
rulesyncSkill,
|
|
4438
|
+
toolTarget: "codexcli"
|
|
4439
|
+
});
|
|
4440
|
+
}
|
|
4441
|
+
};
|
|
4442
|
+
|
|
4443
|
+
// src/features/skills/copilot-skill.ts
|
|
4444
|
+
import { join as join40 } from "path";
|
|
4445
|
+
var CopilotSkill = class _CopilotSkill extends SimulatedSkill {
|
|
4446
|
+
static getSettablePaths(options) {
|
|
4447
|
+
if (options?.global) {
|
|
4448
|
+
throw new Error("CopilotSkill does not support global mode.");
|
|
4449
|
+
}
|
|
4450
|
+
return {
|
|
4451
|
+
relativeDirPath: join40(".github", "skills")
|
|
4452
|
+
};
|
|
4453
|
+
}
|
|
4454
|
+
static async fromDir(params) {
|
|
4455
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4456
|
+
return new _CopilotSkill(baseParams);
|
|
4457
|
+
}
|
|
4458
|
+
static fromRulesyncSkill(params) {
|
|
4459
|
+
const baseParams = {
|
|
4460
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4461
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4462
|
+
};
|
|
4463
|
+
return new _CopilotSkill(baseParams);
|
|
4464
|
+
}
|
|
4465
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4466
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4467
|
+
rulesyncSkill,
|
|
4468
|
+
toolTarget: "copilot"
|
|
4469
|
+
});
|
|
4470
|
+
}
|
|
4471
|
+
};
|
|
4472
|
+
|
|
4473
|
+
// src/features/skills/cursor-skill.ts
|
|
4474
|
+
import { join as join41 } from "path";
|
|
4475
|
+
var CursorSkill = class _CursorSkill extends SimulatedSkill {
|
|
4476
|
+
static getSettablePaths(options) {
|
|
4477
|
+
if (options?.global) {
|
|
4478
|
+
throw new Error("CursorSkill does not support global mode.");
|
|
4479
|
+
}
|
|
4480
|
+
return {
|
|
4481
|
+
relativeDirPath: join41(".cursor", "skills")
|
|
4482
|
+
};
|
|
4483
|
+
}
|
|
4484
|
+
static async fromDir(params) {
|
|
4485
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4486
|
+
return new _CursorSkill(baseParams);
|
|
4487
|
+
}
|
|
4488
|
+
static fromRulesyncSkill(params) {
|
|
4489
|
+
const baseParams = {
|
|
4490
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4491
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4492
|
+
};
|
|
4493
|
+
return new _CursorSkill(baseParams);
|
|
4494
|
+
}
|
|
4495
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4496
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4497
|
+
rulesyncSkill,
|
|
4498
|
+
toolTarget: "cursor"
|
|
4499
|
+
});
|
|
4500
|
+
}
|
|
4501
|
+
};
|
|
4502
|
+
|
|
4503
|
+
// src/features/skills/skills-processor.ts
|
|
4504
|
+
import { basename as basename13, join as join47 } from "path";
|
|
4505
|
+
import { z as z20 } from "zod/mini";
|
|
4506
|
+
|
|
4507
|
+
// src/types/dir-feature-processor.ts
|
|
4508
|
+
import { join as join42 } from "path";
|
|
4509
|
+
var DirFeatureProcessor = class {
|
|
4510
|
+
baseDir;
|
|
4511
|
+
constructor({ baseDir = process.cwd() }) {
|
|
4512
|
+
this.baseDir = baseDir;
|
|
4513
|
+
}
|
|
4514
|
+
/**
|
|
4515
|
+
* Return tool targets that this feature supports.
|
|
4516
|
+
*/
|
|
4517
|
+
static getToolTargets(_params = {}) {
|
|
4518
|
+
throw new Error("Not implemented");
|
|
4519
|
+
}
|
|
4520
|
+
/**
|
|
4521
|
+
* Once converted to rulesync/tool dirs, write them to the filesystem.
|
|
4522
|
+
* Returns the number of directories written.
|
|
4523
|
+
*/
|
|
4524
|
+
async writeAiDirs(aiDirs) {
|
|
4525
|
+
for (const aiDir of aiDirs) {
|
|
4526
|
+
const dirPath = aiDir.getDirPath();
|
|
4527
|
+
await ensureDir(dirPath);
|
|
4528
|
+
const mainFile = aiDir.getMainFile();
|
|
4529
|
+
if (mainFile) {
|
|
4530
|
+
const mainFilePath = join42(dirPath, mainFile.name);
|
|
4531
|
+
const contentWithNewline = addTrailingNewline(mainFile.body);
|
|
4532
|
+
await writeFileContent(mainFilePath, contentWithNewline);
|
|
4533
|
+
}
|
|
4534
|
+
const otherFiles = aiDir.getOtherFiles();
|
|
4535
|
+
for (const file of otherFiles) {
|
|
4536
|
+
const filePath = join42(dirPath, file.relativeFilePathToDirPath);
|
|
4537
|
+
const contentWithNewline = addTrailingNewline(file.fileBuffer.toString("utf-8"));
|
|
4538
|
+
await writeFileContent(filePath, contentWithNewline);
|
|
4539
|
+
}
|
|
4540
|
+
}
|
|
4541
|
+
return aiDirs.length;
|
|
4542
|
+
}
|
|
4543
|
+
async removeAiDirs(aiDirs) {
|
|
4544
|
+
for (const aiDir of aiDirs) {
|
|
4545
|
+
await removeDirectory(aiDir.getDirPath());
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
};
|
|
4549
|
+
|
|
4550
|
+
// src/features/skills/agentsmd-skill.ts
|
|
4551
|
+
import { join as join43 } from "path";
|
|
4552
|
+
var AgentsmdSkill = class _AgentsmdSkill extends SimulatedSkill {
|
|
4553
|
+
static getSettablePaths(options) {
|
|
4554
|
+
if (options?.global) {
|
|
4555
|
+
throw new Error("AgentsmdSkill does not support global mode.");
|
|
4556
|
+
}
|
|
4557
|
+
return {
|
|
4558
|
+
relativeDirPath: join43(".agents", "skills")
|
|
4559
|
+
};
|
|
4560
|
+
}
|
|
4561
|
+
static async fromDir(params) {
|
|
4562
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4563
|
+
return new _AgentsmdSkill(baseParams);
|
|
4564
|
+
}
|
|
4565
|
+
static fromRulesyncSkill(params) {
|
|
4566
|
+
const baseParams = {
|
|
4567
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4568
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4569
|
+
};
|
|
4570
|
+
return new _AgentsmdSkill(baseParams);
|
|
4571
|
+
}
|
|
4572
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4573
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4574
|
+
rulesyncSkill,
|
|
4575
|
+
toolTarget: "agentsmd"
|
|
4576
|
+
});
|
|
4577
|
+
}
|
|
4578
|
+
};
|
|
4579
|
+
|
|
4580
|
+
// src/features/skills/claudecode-skill.ts
|
|
4581
|
+
import { join as join45 } from "path";
|
|
4582
|
+
import { z as z19 } from "zod/mini";
|
|
4583
|
+
|
|
4584
|
+
// src/features/skills/rulesync-skill.ts
|
|
4585
|
+
import { join as join44 } from "path";
|
|
4586
|
+
import { z as z18 } from "zod/mini";
|
|
4587
|
+
var RulesyncSkillFrontmatterSchemaInternal = z18.object({
|
|
4588
|
+
name: z18.string(),
|
|
4589
|
+
description: z18.string(),
|
|
4590
|
+
targets: z18._default(RulesyncTargetsSchema, ["*"]),
|
|
4591
|
+
claudecode: z18.optional(
|
|
4592
|
+
z18.object({
|
|
4593
|
+
"allowed-tools": z18.optional(z18.array(z18.string()))
|
|
4594
|
+
})
|
|
4595
|
+
)
|
|
4596
|
+
});
|
|
4597
|
+
var RulesyncSkillFrontmatterSchema = RulesyncSkillFrontmatterSchemaInternal;
|
|
4598
|
+
var RulesyncSkill = class _RulesyncSkill extends AiDir {
|
|
4599
|
+
constructor({
|
|
4600
|
+
baseDir = process.cwd(),
|
|
4601
|
+
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4602
|
+
dirName,
|
|
4603
|
+
frontmatter,
|
|
4604
|
+
body,
|
|
4605
|
+
otherFiles = [],
|
|
4606
|
+
validate = true,
|
|
4607
|
+
global = false
|
|
4608
|
+
}) {
|
|
4609
|
+
super({
|
|
4610
|
+
baseDir,
|
|
4611
|
+
relativeDirPath,
|
|
4612
|
+
dirName,
|
|
4613
|
+
mainFile: {
|
|
4614
|
+
name: SKILL_FILE_NAME,
|
|
4615
|
+
body,
|
|
4616
|
+
frontmatter: { ...frontmatter }
|
|
4617
|
+
},
|
|
4618
|
+
otherFiles,
|
|
4619
|
+
global
|
|
4620
|
+
});
|
|
4621
|
+
if (validate) {
|
|
4622
|
+
const result = this.validate();
|
|
4623
|
+
if (!result.success) {
|
|
4624
|
+
throw result.error;
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4628
|
+
static getSettablePaths() {
|
|
4629
|
+
return {
|
|
4630
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH
|
|
4631
|
+
};
|
|
4632
|
+
}
|
|
4633
|
+
getFrontmatter() {
|
|
4634
|
+
if (!this.mainFile?.frontmatter) {
|
|
4635
|
+
throw new Error("Frontmatter is not defined");
|
|
4636
|
+
}
|
|
4637
|
+
const result = RulesyncSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4638
|
+
return result;
|
|
4639
|
+
}
|
|
4640
|
+
getBody() {
|
|
4641
|
+
return this.mainFile?.body ?? "";
|
|
4642
|
+
}
|
|
4643
|
+
validate() {
|
|
4644
|
+
const result = RulesyncSkillFrontmatterSchema.safeParse(this.mainFile?.frontmatter);
|
|
4645
|
+
if (!result.success) {
|
|
4646
|
+
return {
|
|
4647
|
+
success: false,
|
|
4648
|
+
error: new Error(
|
|
4649
|
+
`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
|
|
4650
|
+
)
|
|
4651
|
+
};
|
|
4652
|
+
}
|
|
4653
|
+
return { success: true, error: null };
|
|
4654
|
+
}
|
|
4655
|
+
static async fromDir({
|
|
4656
|
+
baseDir = process.cwd(),
|
|
4657
|
+
relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
4658
|
+
dirName,
|
|
4659
|
+
global = false
|
|
4660
|
+
}) {
|
|
4661
|
+
const skillDirPath = join44(baseDir, relativeDirPath, dirName);
|
|
4662
|
+
const skillFilePath = join44(skillDirPath, SKILL_FILE_NAME);
|
|
4663
|
+
if (!await fileExists(skillFilePath)) {
|
|
4664
|
+
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4665
|
+
}
|
|
4666
|
+
const fileContent = await readFileContent(skillFilePath);
|
|
4667
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4668
|
+
const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4669
|
+
if (!result.success) {
|
|
4670
|
+
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4671
|
+
}
|
|
4672
|
+
const otherFiles = await this.collectOtherFiles(
|
|
4673
|
+
baseDir,
|
|
4674
|
+
relativeDirPath,
|
|
4675
|
+
dirName,
|
|
4676
|
+
SKILL_FILE_NAME
|
|
4677
|
+
);
|
|
4678
|
+
return new _RulesyncSkill({
|
|
4679
|
+
baseDir,
|
|
4680
|
+
relativeDirPath,
|
|
4681
|
+
dirName,
|
|
4682
|
+
frontmatter: result.data,
|
|
4683
|
+
body: content.trim(),
|
|
4684
|
+
otherFiles,
|
|
4685
|
+
validate: true,
|
|
4686
|
+
global
|
|
4687
|
+
});
|
|
4688
|
+
}
|
|
4689
|
+
};
|
|
4690
|
+
|
|
4691
|
+
// src/features/skills/claudecode-skill.ts
|
|
4692
|
+
var ClaudecodeSkillFrontmatterSchema = z19.object({
|
|
4693
|
+
name: z19.string(),
|
|
4694
|
+
description: z19.string(),
|
|
4695
|
+
"allowed-tools": z19.optional(z19.array(z19.string()))
|
|
4696
|
+
});
|
|
4697
|
+
var ClaudecodeSkill = class _ClaudecodeSkill extends ToolSkill {
|
|
4698
|
+
constructor({
|
|
4699
|
+
baseDir = process.cwd(),
|
|
4700
|
+
relativeDirPath = join45(".claude", "skills"),
|
|
4701
|
+
dirName,
|
|
4702
|
+
frontmatter,
|
|
4703
|
+
body,
|
|
4704
|
+
otherFiles = [],
|
|
4705
|
+
validate = true,
|
|
4706
|
+
global = false
|
|
4707
|
+
}) {
|
|
4708
|
+
super({
|
|
4709
|
+
baseDir,
|
|
4710
|
+
relativeDirPath,
|
|
4711
|
+
dirName,
|
|
4712
|
+
mainFile: {
|
|
4713
|
+
name: SKILL_FILE_NAME,
|
|
4714
|
+
body,
|
|
4715
|
+
frontmatter: { ...frontmatter }
|
|
4716
|
+
},
|
|
4717
|
+
otherFiles,
|
|
4718
|
+
global
|
|
4719
|
+
});
|
|
4720
|
+
if (validate) {
|
|
4721
|
+
const result = this.validate();
|
|
4722
|
+
if (!result.success) {
|
|
4723
|
+
throw result.error;
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
static getSettablePaths({
|
|
4728
|
+
global: _global = false
|
|
4729
|
+
} = {}) {
|
|
4730
|
+
return {
|
|
4731
|
+
relativeDirPath: join45(".claude", "skills")
|
|
4732
|
+
};
|
|
4733
|
+
}
|
|
4734
|
+
getFrontmatter() {
|
|
4735
|
+
if (!this.mainFile?.frontmatter) {
|
|
4736
|
+
throw new Error("Frontmatter is not defined");
|
|
4737
|
+
}
|
|
4738
|
+
const result = ClaudecodeSkillFrontmatterSchema.parse(this.mainFile.frontmatter);
|
|
4739
|
+
return result;
|
|
4740
|
+
}
|
|
4741
|
+
getBody() {
|
|
4742
|
+
return this.mainFile?.body ?? "";
|
|
4743
|
+
}
|
|
4744
|
+
validate() {
|
|
4745
|
+
if (this.mainFile === void 0) {
|
|
4746
|
+
return {
|
|
4747
|
+
success: false,
|
|
4748
|
+
error: new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
4749
|
+
};
|
|
4750
|
+
}
|
|
4751
|
+
const result = ClaudecodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
4752
|
+
if (!result.success) {
|
|
4753
|
+
return {
|
|
4754
|
+
success: false,
|
|
4755
|
+
error: new Error(
|
|
4756
|
+
`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`
|
|
4757
|
+
)
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
return { success: true, error: null };
|
|
4761
|
+
}
|
|
4762
|
+
toRulesyncSkill() {
|
|
4763
|
+
const frontmatter = this.getFrontmatter();
|
|
4764
|
+
const rulesyncFrontmatter = {
|
|
4765
|
+
name: frontmatter.name,
|
|
4766
|
+
description: frontmatter.description,
|
|
4767
|
+
targets: ["*"],
|
|
4768
|
+
...frontmatter["allowed-tools"] && {
|
|
4769
|
+
claudecode: {
|
|
4770
|
+
"allowed-tools": frontmatter["allowed-tools"]
|
|
4771
|
+
}
|
|
4772
|
+
}
|
|
4773
|
+
};
|
|
4774
|
+
return new RulesyncSkill({
|
|
4775
|
+
baseDir: this.baseDir,
|
|
4776
|
+
relativeDirPath: this.relativeDirPath,
|
|
4777
|
+
dirName: this.getDirName(),
|
|
4778
|
+
frontmatter: rulesyncFrontmatter,
|
|
4779
|
+
body: this.getBody(),
|
|
4780
|
+
otherFiles: this.getOtherFiles(),
|
|
4781
|
+
validate: true,
|
|
4782
|
+
global: this.global
|
|
4783
|
+
});
|
|
4784
|
+
}
|
|
4785
|
+
static fromRulesyncSkill({
|
|
4786
|
+
rulesyncSkill,
|
|
4787
|
+
validate = true,
|
|
4788
|
+
global = false
|
|
4789
|
+
}) {
|
|
4790
|
+
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
4791
|
+
const claudecodeFrontmatter = {
|
|
4792
|
+
name: rulesyncFrontmatter.name,
|
|
4793
|
+
description: rulesyncFrontmatter.description,
|
|
4794
|
+
"allowed-tools": rulesyncFrontmatter.claudecode?.["allowed-tools"]
|
|
4795
|
+
};
|
|
4796
|
+
const settablePaths = _ClaudecodeSkill.getSettablePaths({ global });
|
|
4797
|
+
return new _ClaudecodeSkill({
|
|
4798
|
+
baseDir: rulesyncSkill.getBaseDir(),
|
|
4799
|
+
relativeDirPath: settablePaths.relativeDirPath,
|
|
4800
|
+
dirName: rulesyncSkill.getDirName(),
|
|
4801
|
+
frontmatter: claudecodeFrontmatter,
|
|
4802
|
+
body: rulesyncSkill.getBody(),
|
|
4803
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
4804
|
+
validate,
|
|
4805
|
+
global
|
|
4806
|
+
});
|
|
4807
|
+
}
|
|
4808
|
+
static isTargetedByRulesyncSkill(_rulesyncSkill) {
|
|
4809
|
+
return true;
|
|
4810
|
+
}
|
|
4811
|
+
static async fromDir({
|
|
4812
|
+
baseDir = process.cwd(),
|
|
4813
|
+
relativeDirPath,
|
|
4814
|
+
dirName,
|
|
4815
|
+
global = false
|
|
4816
|
+
}) {
|
|
4817
|
+
const settablePaths = this.getSettablePaths({ global });
|
|
4818
|
+
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
4819
|
+
const skillDirPath = join45(baseDir, actualRelativeDirPath, dirName);
|
|
4820
|
+
const skillFilePath = join45(skillDirPath, SKILL_FILE_NAME);
|
|
4821
|
+
if (!await fileExists(skillFilePath)) {
|
|
4822
|
+
throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
4823
|
+
}
|
|
4824
|
+
const fileContent = await readFileContent(skillFilePath);
|
|
4825
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4826
|
+
const result = ClaudecodeSkillFrontmatterSchema.safeParse(frontmatter);
|
|
4827
|
+
if (!result.success) {
|
|
4828
|
+
throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
4829
|
+
}
|
|
4830
|
+
const otherFiles = await this.collectOtherFiles(
|
|
4831
|
+
baseDir,
|
|
4832
|
+
actualRelativeDirPath,
|
|
4833
|
+
dirName,
|
|
4834
|
+
SKILL_FILE_NAME
|
|
4835
|
+
);
|
|
4836
|
+
return new _ClaudecodeSkill({
|
|
4837
|
+
baseDir,
|
|
4838
|
+
relativeDirPath: actualRelativeDirPath,
|
|
4839
|
+
dirName,
|
|
4840
|
+
frontmatter: result.data,
|
|
4841
|
+
body: content.trim(),
|
|
4842
|
+
otherFiles,
|
|
4843
|
+
validate: true,
|
|
4844
|
+
global
|
|
4845
|
+
});
|
|
4846
|
+
}
|
|
4847
|
+
};
|
|
4848
|
+
|
|
4849
|
+
// src/features/skills/geminicli-skill.ts
|
|
4850
|
+
import { join as join46 } from "path";
|
|
4851
|
+
var GeminiCliSkill = class _GeminiCliSkill extends SimulatedSkill {
|
|
4852
|
+
static getSettablePaths(options) {
|
|
4853
|
+
if (options?.global) {
|
|
4854
|
+
throw new Error("GeminiCliSkill does not support global mode.");
|
|
4855
|
+
}
|
|
4856
|
+
return {
|
|
4857
|
+
relativeDirPath: join46(".gemini", "skills")
|
|
4858
|
+
};
|
|
4859
|
+
}
|
|
4860
|
+
static async fromDir(params) {
|
|
4861
|
+
const baseParams = await this.fromDirDefault(params);
|
|
4862
|
+
return new _GeminiCliSkill(baseParams);
|
|
4863
|
+
}
|
|
4864
|
+
static fromRulesyncSkill(params) {
|
|
4865
|
+
const baseParams = {
|
|
4866
|
+
...this.fromRulesyncSkillDefault(params),
|
|
4867
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath
|
|
4868
|
+
};
|
|
4869
|
+
return new _GeminiCliSkill(baseParams);
|
|
4870
|
+
}
|
|
4871
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
4872
|
+
return this.isTargetedByRulesyncSkillDefault({
|
|
4873
|
+
rulesyncSkill,
|
|
4874
|
+
toolTarget: "geminicli"
|
|
4875
|
+
});
|
|
4876
|
+
}
|
|
4877
|
+
};
|
|
4878
|
+
|
|
4879
|
+
// src/features/skills/skills-processor.ts
|
|
4880
|
+
var skillsProcessorToolTargets = [
|
|
4881
|
+
"claudecode",
|
|
4882
|
+
"copilot",
|
|
4883
|
+
"cursor",
|
|
4884
|
+
"codexcli",
|
|
4885
|
+
"geminicli",
|
|
4886
|
+
"agentsmd"
|
|
4887
|
+
];
|
|
4888
|
+
var skillsProcessorToolTargetsSimulated = [
|
|
4889
|
+
"copilot",
|
|
4890
|
+
"cursor",
|
|
4891
|
+
"codexcli",
|
|
4892
|
+
"geminicli",
|
|
4893
|
+
"agentsmd"
|
|
4894
|
+
];
|
|
4895
|
+
var skillsProcessorToolTargetsGlobal = ["claudecode"];
|
|
4896
|
+
var SkillsProcessorToolTargetSchema = z20.enum(skillsProcessorToolTargets);
|
|
4897
|
+
var SkillsProcessor = class extends DirFeatureProcessor {
|
|
4898
|
+
toolTarget;
|
|
4899
|
+
global;
|
|
4900
|
+
constructor({
|
|
4901
|
+
baseDir = process.cwd(),
|
|
4902
|
+
toolTarget,
|
|
4903
|
+
global = false
|
|
4904
|
+
}) {
|
|
4905
|
+
super({ baseDir });
|
|
4906
|
+
const result = SkillsProcessorToolTargetSchema.safeParse(toolTarget);
|
|
4907
|
+
if (!result.success) {
|
|
4908
|
+
throw new Error(
|
|
4909
|
+
`Invalid tool target for SkillsProcessor: ${toolTarget}. ${formatError(result.error)}`
|
|
4910
|
+
);
|
|
4911
|
+
}
|
|
4912
|
+
this.toolTarget = result.data;
|
|
4913
|
+
this.global = global;
|
|
4914
|
+
}
|
|
4915
|
+
async convertRulesyncDirsToToolDirs(rulesyncDirs) {
|
|
4916
|
+
const rulesyncSkills = rulesyncDirs.filter(
|
|
4917
|
+
(dir) => dir instanceof RulesyncSkill
|
|
4918
|
+
);
|
|
4919
|
+
const toolSkills = [];
|
|
4920
|
+
for (const rulesyncSkill of rulesyncSkills) {
|
|
4921
|
+
switch (this.toolTarget) {
|
|
4922
|
+
case "claudecode":
|
|
4923
|
+
if (!ClaudecodeSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4924
|
+
continue;
|
|
4925
|
+
}
|
|
4926
|
+
toolSkills.push(
|
|
4927
|
+
ClaudecodeSkill.fromRulesyncSkill({
|
|
4928
|
+
rulesyncSkill,
|
|
4929
|
+
global: this.global
|
|
4930
|
+
})
|
|
4931
|
+
);
|
|
4932
|
+
break;
|
|
4933
|
+
case "copilot":
|
|
4934
|
+
if (!CopilotSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4935
|
+
continue;
|
|
4936
|
+
}
|
|
4937
|
+
toolSkills.push(
|
|
4938
|
+
CopilotSkill.fromRulesyncSkill({
|
|
4939
|
+
rulesyncSkill
|
|
4940
|
+
})
|
|
4941
|
+
);
|
|
4942
|
+
break;
|
|
4943
|
+
case "cursor":
|
|
4944
|
+
if (!CursorSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4945
|
+
continue;
|
|
4946
|
+
}
|
|
4947
|
+
toolSkills.push(
|
|
4948
|
+
CursorSkill.fromRulesyncSkill({
|
|
4949
|
+
rulesyncSkill
|
|
4950
|
+
})
|
|
4951
|
+
);
|
|
4952
|
+
break;
|
|
4953
|
+
case "codexcli":
|
|
4954
|
+
if (!CodexCliSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4955
|
+
continue;
|
|
4956
|
+
}
|
|
4957
|
+
toolSkills.push(
|
|
4958
|
+
CodexCliSkill.fromRulesyncSkill({
|
|
4959
|
+
rulesyncSkill
|
|
4960
|
+
})
|
|
4961
|
+
);
|
|
4962
|
+
break;
|
|
4963
|
+
case "geminicli":
|
|
4964
|
+
if (!GeminiCliSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4965
|
+
continue;
|
|
4966
|
+
}
|
|
4967
|
+
toolSkills.push(
|
|
4968
|
+
GeminiCliSkill.fromRulesyncSkill({
|
|
4969
|
+
rulesyncSkill
|
|
4970
|
+
})
|
|
4971
|
+
);
|
|
4972
|
+
break;
|
|
4973
|
+
case "agentsmd":
|
|
4974
|
+
if (!AgentsmdSkill.isTargetedByRulesyncSkill(rulesyncSkill)) {
|
|
4975
|
+
continue;
|
|
4976
|
+
}
|
|
4977
|
+
toolSkills.push(
|
|
4978
|
+
AgentsmdSkill.fromRulesyncSkill({
|
|
4979
|
+
rulesyncSkill
|
|
4980
|
+
})
|
|
4981
|
+
);
|
|
4982
|
+
break;
|
|
4983
|
+
default:
|
|
4984
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
return toolSkills;
|
|
4988
|
+
}
|
|
4989
|
+
async convertToolDirsToRulesyncDirs(toolDirs) {
|
|
4990
|
+
const toolSkills = toolDirs.filter((dir) => dir instanceof ToolSkill);
|
|
4991
|
+
const rulesyncSkills = [];
|
|
4992
|
+
for (const toolSkill of toolSkills) {
|
|
4993
|
+
if (toolSkill instanceof SimulatedSkill) {
|
|
4994
|
+
logger.debug(`Skipping simulated skill conversion: ${toolSkill.getDirPath()}`);
|
|
4995
|
+
continue;
|
|
4996
|
+
}
|
|
4997
|
+
rulesyncSkills.push(toolSkill.toRulesyncSkill());
|
|
4998
|
+
}
|
|
4999
|
+
return rulesyncSkills;
|
|
5000
|
+
}
|
|
5001
|
+
/**
|
|
5002
|
+
* Implementation of abstract method from DirFeatureProcessor
|
|
5003
|
+
* Load and parse rulesync skill directories from .rulesync/skills/ directory
|
|
5004
|
+
*/
|
|
5005
|
+
async loadRulesyncDirs() {
|
|
5006
|
+
const paths = RulesyncSkill.getSettablePaths();
|
|
5007
|
+
const rulesyncSkillsDirPath = join47(this.baseDir, paths.relativeDirPath);
|
|
5008
|
+
const dirPaths = await findFilesByGlobs(join47(rulesyncSkillsDirPath, "*"), { type: "dir" });
|
|
5009
|
+
const dirNames = dirPaths.map((path3) => basename13(path3));
|
|
5010
|
+
const results = await Promise.allSettled(
|
|
5011
|
+
dirNames.map(
|
|
5012
|
+
(dirName) => RulesyncSkill.fromDir({ baseDir: this.baseDir, dirName, global: this.global })
|
|
5013
|
+
)
|
|
5014
|
+
);
|
|
5015
|
+
const rulesyncSkills = [];
|
|
5016
|
+
for (const result of results) {
|
|
5017
|
+
if (result.status === "fulfilled") {
|
|
5018
|
+
rulesyncSkills.push(result.value);
|
|
5019
|
+
}
|
|
3681
5020
|
}
|
|
5021
|
+
logger.info(`Successfully loaded ${rulesyncSkills.length} rulesync skills`);
|
|
5022
|
+
return rulesyncSkills;
|
|
3682
5023
|
}
|
|
3683
5024
|
/**
|
|
3684
|
-
* Implementation of abstract method from
|
|
3685
|
-
*
|
|
5025
|
+
* Implementation of abstract method from DirFeatureProcessor
|
|
5026
|
+
* Load tool-specific skill configurations and parse them into ToolSkill instances
|
|
3686
5027
|
*/
|
|
3687
|
-
async
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
5028
|
+
async loadToolDirs() {
|
|
5029
|
+
switch (this.toolTarget) {
|
|
5030
|
+
case "claudecode":
|
|
5031
|
+
return await this.loadClaudecodeSkills();
|
|
5032
|
+
case "copilot":
|
|
5033
|
+
return await this.loadSimulatedSkills(CopilotSkill);
|
|
5034
|
+
case "cursor":
|
|
5035
|
+
return await this.loadSimulatedSkills(CursorSkill);
|
|
5036
|
+
case "codexcli":
|
|
5037
|
+
return await this.loadSimulatedSkills(CodexCliSkill);
|
|
5038
|
+
case "geminicli":
|
|
5039
|
+
return await this.loadSimulatedSkills(GeminiCliSkill);
|
|
5040
|
+
case "agentsmd":
|
|
5041
|
+
return await this.loadSimulatedSkills(AgentsmdSkill);
|
|
5042
|
+
default:
|
|
5043
|
+
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
3693
5044
|
}
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
case "cline":
|
|
3710
|
-
return ClineMcp.fromRulesyncMcp({
|
|
3711
|
-
baseDir: this.baseDir,
|
|
3712
|
-
rulesyncMcp: rulesyncMcp2
|
|
3713
|
-
});
|
|
3714
|
-
case "copilot":
|
|
3715
|
-
return CopilotMcp.fromRulesyncMcp({
|
|
3716
|
-
baseDir: this.baseDir,
|
|
3717
|
-
rulesyncMcp: rulesyncMcp2
|
|
3718
|
-
});
|
|
3719
|
-
case "cursor":
|
|
3720
|
-
return CursorMcp.fromRulesyncMcp({
|
|
3721
|
-
baseDir: this.baseDir,
|
|
3722
|
-
rulesyncMcp: rulesyncMcp2
|
|
3723
|
-
});
|
|
3724
|
-
case "codexcli":
|
|
3725
|
-
return await CodexcliMcp.fromRulesyncMcp({
|
|
3726
|
-
baseDir: this.baseDir,
|
|
3727
|
-
rulesyncMcp: rulesyncMcp2,
|
|
3728
|
-
global: this.global
|
|
3729
|
-
});
|
|
3730
|
-
case "geminicli":
|
|
3731
|
-
return GeminiCliMcp.fromRulesyncMcp({
|
|
3732
|
-
baseDir: this.baseDir,
|
|
3733
|
-
rulesyncMcp: rulesyncMcp2,
|
|
3734
|
-
global: this.global
|
|
3735
|
-
});
|
|
3736
|
-
case "roo":
|
|
3737
|
-
return RooMcp.fromRulesyncMcp({
|
|
3738
|
-
baseDir: this.baseDir,
|
|
3739
|
-
rulesyncMcp: rulesyncMcp2
|
|
3740
|
-
});
|
|
3741
|
-
default:
|
|
3742
|
-
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
3743
|
-
}
|
|
3744
|
-
})
|
|
3745
|
-
);
|
|
3746
|
-
const toolFiles = toolMcps;
|
|
3747
|
-
if (this.modularMcp && mcpProcessorToolTargetsModular.includes(this.toolTarget)) {
|
|
3748
|
-
const relativeDirPath = this.toolTarget === "claudecode" ? ClaudecodeMcp.getSettablePaths({ global: this.global }).relativeDirPath : void 0;
|
|
3749
|
-
toolFiles.push(
|
|
3750
|
-
ModularMcp.fromRulesyncMcp({
|
|
5045
|
+
}
|
|
5046
|
+
async loadToolDirsToDelete() {
|
|
5047
|
+
return this.loadToolDirs();
|
|
5048
|
+
}
|
|
5049
|
+
/**
|
|
5050
|
+
* Load Claude Code skill configurations from .claude/skills/ directory
|
|
5051
|
+
*/
|
|
5052
|
+
async loadClaudecodeSkills() {
|
|
5053
|
+
const paths = ClaudecodeSkill.getSettablePaths({ global: this.global });
|
|
5054
|
+
const skillsDirPath = join47(this.baseDir, paths.relativeDirPath);
|
|
5055
|
+
const dirPaths = await findFilesByGlobs(join47(skillsDirPath, "*"), { type: "dir" });
|
|
5056
|
+
const dirNames = dirPaths.map((path3) => basename13(path3));
|
|
5057
|
+
const toolSkills = (await Promise.allSettled(
|
|
5058
|
+
dirNames.map(
|
|
5059
|
+
(dirName) => ClaudecodeSkill.fromDir({
|
|
3751
5060
|
baseDir: this.baseDir,
|
|
3752
|
-
|
|
3753
|
-
|
|
5061
|
+
dirName,
|
|
5062
|
+
global: this.global
|
|
3754
5063
|
})
|
|
3755
|
-
)
|
|
3756
|
-
|
|
3757
|
-
|
|
5064
|
+
)
|
|
5065
|
+
)).filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
5066
|
+
logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
|
|
5067
|
+
return toolSkills;
|
|
3758
5068
|
}
|
|
3759
5069
|
/**
|
|
3760
|
-
*
|
|
3761
|
-
* Convert ToolFile[] to RulesyncFile[]
|
|
5070
|
+
* Load simulated skill configurations from tool-specific directories
|
|
3762
5071
|
*/
|
|
3763
|
-
async
|
|
3764
|
-
const
|
|
3765
|
-
const
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
5072
|
+
async loadSimulatedSkills(SkillClass) {
|
|
5073
|
+
const paths = SkillClass.getSettablePaths();
|
|
5074
|
+
const skillsDirPath = join47(this.baseDir, paths.relativeDirPath);
|
|
5075
|
+
const dirPaths = await findFilesByGlobs(join47(skillsDirPath, "*"), { type: "dir" });
|
|
5076
|
+
const dirNames = dirPaths.map((path3) => basename13(path3));
|
|
5077
|
+
const toolSkills = (await Promise.allSettled(
|
|
5078
|
+
dirNames.map(
|
|
5079
|
+
(dirName) => SkillClass.fromDir({
|
|
5080
|
+
baseDir: this.baseDir,
|
|
5081
|
+
dirName
|
|
5082
|
+
})
|
|
5083
|
+
)
|
|
5084
|
+
)).filter((result) => result.status === "fulfilled").map((result) => result.value);
|
|
5085
|
+
logger.info(`Successfully loaded ${toolSkills.length} ${paths.relativeDirPath} skills`);
|
|
5086
|
+
return toolSkills;
|
|
3769
5087
|
}
|
|
3770
5088
|
/**
|
|
3771
|
-
* Implementation of abstract method from
|
|
5089
|
+
* Implementation of abstract method from DirFeatureProcessor
|
|
3772
5090
|
* Return the tool targets that this processor supports
|
|
3773
5091
|
*/
|
|
3774
|
-
static getToolTargets(
|
|
3775
|
-
|
|
5092
|
+
static getToolTargets({
|
|
5093
|
+
global = false,
|
|
5094
|
+
includeSimulated = false
|
|
5095
|
+
} = {}) {
|
|
5096
|
+
if (global) {
|
|
5097
|
+
return skillsProcessorToolTargetsGlobal;
|
|
5098
|
+
}
|
|
5099
|
+
if (!includeSimulated) {
|
|
5100
|
+
return skillsProcessorToolTargets.filter(
|
|
5101
|
+
(target) => !skillsProcessorToolTargetsSimulated.includes(target)
|
|
5102
|
+
);
|
|
5103
|
+
}
|
|
5104
|
+
return skillsProcessorToolTargets;
|
|
5105
|
+
}
|
|
5106
|
+
/**
|
|
5107
|
+
* Return the simulated tool targets
|
|
5108
|
+
*/
|
|
5109
|
+
static getToolTargetsSimulated() {
|
|
5110
|
+
return skillsProcessorToolTargetsSimulated;
|
|
3776
5111
|
}
|
|
5112
|
+
/**
|
|
5113
|
+
* Return the tool targets that this processor supports in global mode
|
|
5114
|
+
*/
|
|
3777
5115
|
static getToolTargetsGlobal() {
|
|
3778
|
-
return
|
|
5116
|
+
return skillsProcessorToolTargetsGlobal;
|
|
3779
5117
|
}
|
|
3780
5118
|
};
|
|
3781
5119
|
|
|
3782
|
-
// src/features/rules/rules-processor.ts
|
|
3783
|
-
import { basename as basename17, join as join64 } from "path";
|
|
3784
|
-
import { XMLBuilder } from "fast-xml-parser";
|
|
3785
|
-
import { z as z24 } from "zod/mini";
|
|
3786
|
-
|
|
3787
5120
|
// src/features/subagents/agentsmd-subagent.ts
|
|
3788
|
-
import { join as
|
|
5121
|
+
import { join as join49 } from "path";
|
|
3789
5122
|
|
|
3790
5123
|
// src/features/subagents/simulated-subagent.ts
|
|
3791
|
-
import { basename as
|
|
3792
|
-
import { z as
|
|
5124
|
+
import { basename as basename14, join as join48 } from "path";
|
|
5125
|
+
import { z as z21 } from "zod/mini";
|
|
3793
5126
|
|
|
3794
5127
|
// src/features/subagents/tool-subagent.ts
|
|
3795
5128
|
var ToolSubagent = class extends ToolFile {
|
|
@@ -3824,9 +5157,9 @@ var ToolSubagent = class extends ToolFile {
|
|
|
3824
5157
|
};
|
|
3825
5158
|
|
|
3826
5159
|
// src/features/subagents/simulated-subagent.ts
|
|
3827
|
-
var SimulatedSubagentFrontmatterSchema =
|
|
3828
|
-
name:
|
|
3829
|
-
description:
|
|
5160
|
+
var SimulatedSubagentFrontmatterSchema = z21.object({
|
|
5161
|
+
name: z21.string(),
|
|
5162
|
+
description: z21.string()
|
|
3830
5163
|
});
|
|
3831
5164
|
var SimulatedSubagent = class extends ToolSubagent {
|
|
3832
5165
|
frontmatter;
|
|
@@ -3836,7 +5169,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3836
5169
|
const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
3837
5170
|
if (!result.success) {
|
|
3838
5171
|
throw new Error(
|
|
3839
|
-
`Invalid frontmatter in ${
|
|
5172
|
+
`Invalid frontmatter in ${join48(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
3840
5173
|
);
|
|
3841
5174
|
}
|
|
3842
5175
|
}
|
|
@@ -3887,7 +5220,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3887
5220
|
return {
|
|
3888
5221
|
success: false,
|
|
3889
5222
|
error: new Error(
|
|
3890
|
-
`Invalid frontmatter in ${
|
|
5223
|
+
`Invalid frontmatter in ${join48(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
3891
5224
|
)
|
|
3892
5225
|
};
|
|
3893
5226
|
}
|
|
@@ -3897,7 +5230,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3897
5230
|
relativeFilePath,
|
|
3898
5231
|
validate = true
|
|
3899
5232
|
}) {
|
|
3900
|
-
const filePath =
|
|
5233
|
+
const filePath = join48(baseDir, this.getSettablePaths().relativeDirPath, relativeFilePath);
|
|
3901
5234
|
const fileContent = await readFileContent(filePath);
|
|
3902
5235
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
3903
5236
|
const result = SimulatedSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -3907,7 +5240,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3907
5240
|
return {
|
|
3908
5241
|
baseDir,
|
|
3909
5242
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
3910
|
-
relativeFilePath:
|
|
5243
|
+
relativeFilePath: basename14(relativeFilePath),
|
|
3911
5244
|
frontmatter: result.data,
|
|
3912
5245
|
body: content.trim(),
|
|
3913
5246
|
validate
|
|
@@ -3919,7 +5252,7 @@ var SimulatedSubagent = class extends ToolSubagent {
|
|
|
3919
5252
|
var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
|
|
3920
5253
|
static getSettablePaths() {
|
|
3921
5254
|
return {
|
|
3922
|
-
relativeDirPath:
|
|
5255
|
+
relativeDirPath: join49(".agents", "subagents")
|
|
3923
5256
|
};
|
|
3924
5257
|
}
|
|
3925
5258
|
static async fromFile(params) {
|
|
@@ -3939,11 +5272,11 @@ var AgentsmdSubagent = class _AgentsmdSubagent extends SimulatedSubagent {
|
|
|
3939
5272
|
};
|
|
3940
5273
|
|
|
3941
5274
|
// src/features/subagents/codexcli-subagent.ts
|
|
3942
|
-
import { join as
|
|
5275
|
+
import { join as join50 } from "path";
|
|
3943
5276
|
var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
|
|
3944
5277
|
static getSettablePaths() {
|
|
3945
5278
|
return {
|
|
3946
|
-
relativeDirPath:
|
|
5279
|
+
relativeDirPath: join50(".codex", "subagents")
|
|
3947
5280
|
};
|
|
3948
5281
|
}
|
|
3949
5282
|
static async fromFile(params) {
|
|
@@ -3963,11 +5296,11 @@ var CodexCliSubagent = class _CodexCliSubagent extends SimulatedSubagent {
|
|
|
3963
5296
|
};
|
|
3964
5297
|
|
|
3965
5298
|
// src/features/subagents/copilot-subagent.ts
|
|
3966
|
-
import { join as
|
|
5299
|
+
import { join as join51 } from "path";
|
|
3967
5300
|
var CopilotSubagent = class _CopilotSubagent extends SimulatedSubagent {
|
|
3968
5301
|
static getSettablePaths() {
|
|
3969
5302
|
return {
|
|
3970
|
-
relativeDirPath:
|
|
5303
|
+
relativeDirPath: join51(".github", "subagents")
|
|
3971
5304
|
};
|
|
3972
5305
|
}
|
|
3973
5306
|
static async fromFile(params) {
|
|
@@ -3987,11 +5320,11 @@ var CopilotSubagent = class _CopilotSubagent extends SimulatedSubagent {
|
|
|
3987
5320
|
};
|
|
3988
5321
|
|
|
3989
5322
|
// src/features/subagents/cursor-subagent.ts
|
|
3990
|
-
import { join as
|
|
5323
|
+
import { join as join52 } from "path";
|
|
3991
5324
|
var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
|
|
3992
5325
|
static getSettablePaths() {
|
|
3993
5326
|
return {
|
|
3994
|
-
relativeDirPath:
|
|
5327
|
+
relativeDirPath: join52(".cursor", "subagents")
|
|
3995
5328
|
};
|
|
3996
5329
|
}
|
|
3997
5330
|
static async fromFile(params) {
|
|
@@ -4011,11 +5344,11 @@ var CursorSubagent = class _CursorSubagent extends SimulatedSubagent {
|
|
|
4011
5344
|
};
|
|
4012
5345
|
|
|
4013
5346
|
// src/features/subagents/geminicli-subagent.ts
|
|
4014
|
-
import { join as
|
|
5347
|
+
import { join as join53 } from "path";
|
|
4015
5348
|
var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
|
|
4016
5349
|
static getSettablePaths() {
|
|
4017
5350
|
return {
|
|
4018
|
-
relativeDirPath:
|
|
5351
|
+
relativeDirPath: join53(".gemini", "subagents")
|
|
4019
5352
|
};
|
|
4020
5353
|
}
|
|
4021
5354
|
static async fromFile(params) {
|
|
@@ -4035,11 +5368,11 @@ var GeminiCliSubagent = class _GeminiCliSubagent extends SimulatedSubagent {
|
|
|
4035
5368
|
};
|
|
4036
5369
|
|
|
4037
5370
|
// src/features/subagents/roo-subagent.ts
|
|
4038
|
-
import { join as
|
|
5371
|
+
import { join as join54 } from "path";
|
|
4039
5372
|
var RooSubagent = class _RooSubagent extends SimulatedSubagent {
|
|
4040
5373
|
static getSettablePaths() {
|
|
4041
5374
|
return {
|
|
4042
|
-
relativeDirPath:
|
|
5375
|
+
relativeDirPath: join54(".roo", "subagents")
|
|
4043
5376
|
};
|
|
4044
5377
|
}
|
|
4045
5378
|
static async fromFile(params) {
|
|
@@ -4059,23 +5392,23 @@ var RooSubagent = class _RooSubagent extends SimulatedSubagent {
|
|
|
4059
5392
|
};
|
|
4060
5393
|
|
|
4061
5394
|
// src/features/subagents/subagents-processor.ts
|
|
4062
|
-
import { basename as
|
|
4063
|
-
import { z as
|
|
5395
|
+
import { basename as basename16, join as join57 } from "path";
|
|
5396
|
+
import { z as z24 } from "zod/mini";
|
|
4064
5397
|
|
|
4065
5398
|
// src/features/subagents/claudecode-subagent.ts
|
|
4066
|
-
import { join as
|
|
4067
|
-
import { z as
|
|
5399
|
+
import { join as join56 } from "path";
|
|
5400
|
+
import { z as z23 } from "zod/mini";
|
|
4068
5401
|
|
|
4069
5402
|
// src/features/subagents/rulesync-subagent.ts
|
|
4070
|
-
import { basename as
|
|
4071
|
-
import { z as
|
|
4072
|
-
var RulesyncSubagentModelSchema =
|
|
4073
|
-
var RulesyncSubagentFrontmatterSchema =
|
|
5403
|
+
import { basename as basename15, join as join55 } from "path";
|
|
5404
|
+
import { z as z22 } from "zod/mini";
|
|
5405
|
+
var RulesyncSubagentModelSchema = z22.enum(["opus", "sonnet", "haiku", "inherit"]);
|
|
5406
|
+
var RulesyncSubagentFrontmatterSchema = z22.object({
|
|
4074
5407
|
targets: RulesyncTargetsSchema,
|
|
4075
|
-
name:
|
|
4076
|
-
description:
|
|
4077
|
-
claudecode:
|
|
4078
|
-
|
|
5408
|
+
name: z22.string(),
|
|
5409
|
+
description: z22.string(),
|
|
5410
|
+
claudecode: z22.optional(
|
|
5411
|
+
z22.object({
|
|
4079
5412
|
model: RulesyncSubagentModelSchema
|
|
4080
5413
|
})
|
|
4081
5414
|
)
|
|
@@ -4088,7 +5421,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4088
5421
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4089
5422
|
if (!result.success) {
|
|
4090
5423
|
throw new Error(
|
|
4091
|
-
`Invalid frontmatter in ${
|
|
5424
|
+
`Invalid frontmatter in ${join55(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
4092
5425
|
);
|
|
4093
5426
|
}
|
|
4094
5427
|
}
|
|
@@ -4121,7 +5454,7 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4121
5454
|
return {
|
|
4122
5455
|
success: false,
|
|
4123
5456
|
error: new Error(
|
|
4124
|
-
`Invalid frontmatter in ${
|
|
5457
|
+
`Invalid frontmatter in ${join55(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
4125
5458
|
)
|
|
4126
5459
|
};
|
|
4127
5460
|
}
|
|
@@ -4130,14 +5463,14 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4130
5463
|
relativeFilePath
|
|
4131
5464
|
}) {
|
|
4132
5465
|
const fileContent = await readFileContent(
|
|
4133
|
-
|
|
5466
|
+
join55(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, relativeFilePath)
|
|
4134
5467
|
);
|
|
4135
5468
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4136
5469
|
const result = RulesyncSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4137
5470
|
if (!result.success) {
|
|
4138
5471
|
throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
|
|
4139
5472
|
}
|
|
4140
|
-
const filename =
|
|
5473
|
+
const filename = basename15(relativeFilePath);
|
|
4141
5474
|
return new _RulesyncSubagent({
|
|
4142
5475
|
baseDir: process.cwd(),
|
|
4143
5476
|
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
@@ -4149,10 +5482,10 @@ var RulesyncSubagent = class _RulesyncSubagent extends RulesyncFile {
|
|
|
4149
5482
|
};
|
|
4150
5483
|
|
|
4151
5484
|
// src/features/subagents/claudecode-subagent.ts
|
|
4152
|
-
var ClaudecodeSubagentFrontmatterSchema =
|
|
4153
|
-
name:
|
|
4154
|
-
description:
|
|
4155
|
-
model:
|
|
5485
|
+
var ClaudecodeSubagentFrontmatterSchema = z23.object({
|
|
5486
|
+
name: z23.string(),
|
|
5487
|
+
description: z23.string(),
|
|
5488
|
+
model: z23.optional(z23.enum(["opus", "sonnet", "haiku", "inherit"]))
|
|
4156
5489
|
});
|
|
4157
5490
|
var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
4158
5491
|
frontmatter;
|
|
@@ -4162,7 +5495,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4162
5495
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
4163
5496
|
if (!result.success) {
|
|
4164
5497
|
throw new Error(
|
|
4165
|
-
`Invalid frontmatter in ${
|
|
5498
|
+
`Invalid frontmatter in ${join56(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
4166
5499
|
);
|
|
4167
5500
|
}
|
|
4168
5501
|
}
|
|
@@ -4174,7 +5507,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4174
5507
|
}
|
|
4175
5508
|
static getSettablePaths(_options = {}) {
|
|
4176
5509
|
return {
|
|
4177
|
-
relativeDirPath:
|
|
5510
|
+
relativeDirPath: join56(".claude", "agents")
|
|
4178
5511
|
};
|
|
4179
5512
|
}
|
|
4180
5513
|
getFrontmatter() {
|
|
@@ -4240,7 +5573,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4240
5573
|
return {
|
|
4241
5574
|
success: false,
|
|
4242
5575
|
error: new Error(
|
|
4243
|
-
`Invalid frontmatter in ${
|
|
5576
|
+
`Invalid frontmatter in ${join56(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
4244
5577
|
)
|
|
4245
5578
|
};
|
|
4246
5579
|
}
|
|
@@ -4258,7 +5591,7 @@ var ClaudecodeSubagent = class _ClaudecodeSubagent extends ToolSubagent {
|
|
|
4258
5591
|
global = false
|
|
4259
5592
|
}) {
|
|
4260
5593
|
const paths = this.getSettablePaths({ global });
|
|
4261
|
-
const filePath =
|
|
5594
|
+
const filePath = join56(baseDir, paths.relativeDirPath, relativeFilePath);
|
|
4262
5595
|
const fileContent = await readFileContent(filePath);
|
|
4263
5596
|
const { frontmatter, body: content } = parseFrontmatter(fileContent);
|
|
4264
5597
|
const result = ClaudecodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
@@ -4296,7 +5629,7 @@ var subagentsProcessorToolTargetsSimulated = [
|
|
|
4296
5629
|
"roo"
|
|
4297
5630
|
];
|
|
4298
5631
|
var subagentsProcessorToolTargetsGlobal = ["claudecode"];
|
|
4299
|
-
var SubagentsProcessorToolTargetSchema =
|
|
5632
|
+
var SubagentsProcessorToolTargetSchema = z24.enum(subagentsProcessorToolTargets);
|
|
4300
5633
|
var SubagentsProcessor = class extends FeatureProcessor {
|
|
4301
5634
|
toolTarget;
|
|
4302
5635
|
global;
|
|
@@ -4412,7 +5745,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4412
5745
|
* Load and parse rulesync subagent files from .rulesync/subagents/ directory
|
|
4413
5746
|
*/
|
|
4414
5747
|
async loadRulesyncFiles() {
|
|
4415
|
-
const subagentsDir =
|
|
5748
|
+
const subagentsDir = join57(this.baseDir, RulesyncSubagent.getSettablePaths().relativeDirPath);
|
|
4416
5749
|
const dirExists = await directoryExists(subagentsDir);
|
|
4417
5750
|
if (!dirExists) {
|
|
4418
5751
|
logger.debug(`Rulesync subagents directory not found: ${subagentsDir}`);
|
|
@@ -4427,7 +5760,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4427
5760
|
logger.info(`Found ${mdFiles.length} subagent files in ${subagentsDir}`);
|
|
4428
5761
|
const rulesyncSubagents = [];
|
|
4429
5762
|
for (const mdFile of mdFiles) {
|
|
4430
|
-
const filepath =
|
|
5763
|
+
const filepath = join57(subagentsDir, mdFile);
|
|
4431
5764
|
try {
|
|
4432
5765
|
const rulesyncSubagent = await RulesyncSubagent.fromFile({
|
|
4433
5766
|
relativeFilePath: mdFile,
|
|
@@ -4451,7 +5784,9 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4451
5784
|
* Implementation of abstract method from Processor
|
|
4452
5785
|
* Load tool-specific subagent configurations and parse them into ToolSubagent instances
|
|
4453
5786
|
*/
|
|
4454
|
-
async loadToolFiles(
|
|
5787
|
+
async loadToolFiles({
|
|
5788
|
+
forDeletion: _forDeletion = false
|
|
5789
|
+
} = {}) {
|
|
4455
5790
|
switch (this.toolTarget) {
|
|
4456
5791
|
case "agentsmd":
|
|
4457
5792
|
return await this.loadAgentsmdSubagents();
|
|
@@ -4471,9 +5806,6 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4471
5806
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
4472
5807
|
}
|
|
4473
5808
|
}
|
|
4474
|
-
async loadToolFilesToDelete() {
|
|
4475
|
-
return this.loadToolFiles();
|
|
4476
|
-
}
|
|
4477
5809
|
/**
|
|
4478
5810
|
* Load Agents.md subagent configurations from .agents/subagents/ directory
|
|
4479
5811
|
*/
|
|
@@ -4546,8 +5878,8 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4546
5878
|
relativeDirPath,
|
|
4547
5879
|
fromFile
|
|
4548
5880
|
}) {
|
|
4549
|
-
const paths = await findFilesByGlobs(
|
|
4550
|
-
const subagents = (await Promise.allSettled(paths.map((
|
|
5881
|
+
const paths = await findFilesByGlobs(join57(this.baseDir, relativeDirPath, "*.md"));
|
|
5882
|
+
const subagents = (await Promise.allSettled(paths.map((path3) => fromFile(basename16(path3))))).filter((r) => r.status === "fulfilled").map((r) => r.value);
|
|
4551
5883
|
logger.info(`Successfully loaded ${subagents.length} ${relativeDirPath} subagents`);
|
|
4552
5884
|
return subagents;
|
|
4553
5885
|
}
|
|
@@ -4556,8 +5888,12 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4556
5888
|
* Return the tool targets that this processor supports
|
|
4557
5889
|
*/
|
|
4558
5890
|
static getToolTargets({
|
|
5891
|
+
global = false,
|
|
4559
5892
|
includeSimulated = false
|
|
4560
5893
|
} = {}) {
|
|
5894
|
+
if (global) {
|
|
5895
|
+
return subagentsProcessorToolTargetsGlobal;
|
|
5896
|
+
}
|
|
4561
5897
|
if (!includeSimulated) {
|
|
4562
5898
|
return subagentsProcessorToolTargets.filter(
|
|
4563
5899
|
(target) => !subagentsProcessorToolTargetsSimulated.includes(target)
|
|
@@ -4568,36 +5904,33 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
4568
5904
|
static getToolTargetsSimulated() {
|
|
4569
5905
|
return subagentsProcessorToolTargetsSimulated;
|
|
4570
5906
|
}
|
|
4571
|
-
static getToolTargetsGlobal() {
|
|
4572
|
-
return subagentsProcessorToolTargetsGlobal;
|
|
4573
|
-
}
|
|
4574
5907
|
};
|
|
4575
5908
|
|
|
4576
5909
|
// src/features/rules/agentsmd-rule.ts
|
|
4577
|
-
import { join as
|
|
5910
|
+
import { join as join60 } from "path";
|
|
4578
5911
|
|
|
4579
5912
|
// src/features/rules/tool-rule.ts
|
|
4580
|
-
import { join as
|
|
5913
|
+
import { join as join59 } from "path";
|
|
4581
5914
|
|
|
4582
5915
|
// src/features/rules/rulesync-rule.ts
|
|
4583
|
-
import { basename as
|
|
4584
|
-
import { z as
|
|
4585
|
-
var RulesyncRuleFrontmatterSchema =
|
|
4586
|
-
root:
|
|
4587
|
-
targets:
|
|
4588
|
-
description:
|
|
4589
|
-
globs:
|
|
4590
|
-
agentsmd:
|
|
4591
|
-
|
|
5916
|
+
import { basename as basename17, join as join58 } from "path";
|
|
5917
|
+
import { z as z25 } from "zod/mini";
|
|
5918
|
+
var RulesyncRuleFrontmatterSchema = z25.object({
|
|
5919
|
+
root: z25.optional(z25.optional(z25.boolean())),
|
|
5920
|
+
targets: z25.optional(RulesyncTargetsSchema),
|
|
5921
|
+
description: z25.optional(z25.string()),
|
|
5922
|
+
globs: z25.optional(z25.array(z25.string())),
|
|
5923
|
+
agentsmd: z25.optional(
|
|
5924
|
+
z25.object({
|
|
4592
5925
|
// @example "path/to/subproject"
|
|
4593
|
-
subprojectPath:
|
|
5926
|
+
subprojectPath: z25.optional(z25.string())
|
|
4594
5927
|
})
|
|
4595
5928
|
),
|
|
4596
|
-
cursor:
|
|
4597
|
-
|
|
4598
|
-
alwaysApply:
|
|
4599
|
-
description:
|
|
4600
|
-
globs:
|
|
5929
|
+
cursor: z25.optional(
|
|
5930
|
+
z25.object({
|
|
5931
|
+
alwaysApply: z25.optional(z25.boolean()),
|
|
5932
|
+
description: z25.optional(z25.string()),
|
|
5933
|
+
globs: z25.optional(z25.array(z25.string()))
|
|
4601
5934
|
})
|
|
4602
5935
|
)
|
|
4603
5936
|
});
|
|
@@ -4609,7 +5942,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4609
5942
|
const result = RulesyncRuleFrontmatterSchema.safeParse(frontmatter);
|
|
4610
5943
|
if (!result.success) {
|
|
4611
5944
|
throw new Error(
|
|
4612
|
-
`Invalid frontmatter in ${
|
|
5945
|
+
`Invalid frontmatter in ${join58(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
4613
5946
|
);
|
|
4614
5947
|
}
|
|
4615
5948
|
}
|
|
@@ -4644,7 +5977,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4644
5977
|
return {
|
|
4645
5978
|
success: false,
|
|
4646
5979
|
error: new Error(
|
|
4647
|
-
`Invalid frontmatter in ${
|
|
5980
|
+
`Invalid frontmatter in ${join58(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
4648
5981
|
)
|
|
4649
5982
|
};
|
|
4650
5983
|
}
|
|
@@ -4653,12 +5986,12 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4653
5986
|
relativeFilePath,
|
|
4654
5987
|
validate = true
|
|
4655
5988
|
}) {
|
|
4656
|
-
const legacyPath =
|
|
5989
|
+
const legacyPath = join58(
|
|
4657
5990
|
process.cwd(),
|
|
4658
5991
|
this.getSettablePaths().legacy.relativeDirPath,
|
|
4659
5992
|
relativeFilePath
|
|
4660
5993
|
);
|
|
4661
|
-
const recommendedPath =
|
|
5994
|
+
const recommendedPath = join58(
|
|
4662
5995
|
this.getSettablePaths().recommended.relativeDirPath,
|
|
4663
5996
|
relativeFilePath
|
|
4664
5997
|
);
|
|
@@ -4677,7 +6010,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4677
6010
|
agentsmd: result.data.agentsmd,
|
|
4678
6011
|
cursor: result.data.cursor
|
|
4679
6012
|
};
|
|
4680
|
-
const filename =
|
|
6013
|
+
const filename = basename17(legacyPath);
|
|
4681
6014
|
return new _RulesyncRule({
|
|
4682
6015
|
baseDir: process.cwd(),
|
|
4683
6016
|
relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
|
|
@@ -4691,7 +6024,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4691
6024
|
relativeFilePath,
|
|
4692
6025
|
validate = true
|
|
4693
6026
|
}) {
|
|
4694
|
-
const filePath =
|
|
6027
|
+
const filePath = join58(
|
|
4695
6028
|
process.cwd(),
|
|
4696
6029
|
this.getSettablePaths().recommended.relativeDirPath,
|
|
4697
6030
|
relativeFilePath
|
|
@@ -4710,7 +6043,7 @@ var RulesyncRule = class _RulesyncRule extends RulesyncFile {
|
|
|
4710
6043
|
agentsmd: result.data.agentsmd,
|
|
4711
6044
|
cursor: result.data.cursor
|
|
4712
6045
|
};
|
|
4713
|
-
const filename =
|
|
6046
|
+
const filename = basename17(filePath);
|
|
4714
6047
|
return new _RulesyncRule({
|
|
4715
6048
|
baseDir: process.cwd(),
|
|
4716
6049
|
relativeDirPath: this.getSettablePaths().recommended.relativeDirPath,
|
|
@@ -4785,7 +6118,7 @@ var ToolRule = class extends ToolFile {
|
|
|
4785
6118
|
rulesyncRule,
|
|
4786
6119
|
validate = true,
|
|
4787
6120
|
rootPath = { relativeDirPath: ".", relativeFilePath: "AGENTS.md" },
|
|
4788
|
-
nonRootPath = { relativeDirPath:
|
|
6121
|
+
nonRootPath = { relativeDirPath: join59(".agents", "memories") }
|
|
4789
6122
|
}) {
|
|
4790
6123
|
const params = this.buildToolRuleParamsDefault({
|
|
4791
6124
|
baseDir,
|
|
@@ -4796,7 +6129,7 @@ var ToolRule = class extends ToolFile {
|
|
|
4796
6129
|
});
|
|
4797
6130
|
const rulesyncFrontmatter = rulesyncRule.getFrontmatter();
|
|
4798
6131
|
if (!rulesyncFrontmatter.root && rulesyncFrontmatter.agentsmd?.subprojectPath) {
|
|
4799
|
-
params.relativeDirPath =
|
|
6132
|
+
params.relativeDirPath = join59(rulesyncFrontmatter.agentsmd.subprojectPath);
|
|
4800
6133
|
params.relativeFilePath = "AGENTS.md";
|
|
4801
6134
|
}
|
|
4802
6135
|
return params;
|
|
@@ -4861,7 +6194,7 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
4861
6194
|
relativeFilePath: "AGENTS.md"
|
|
4862
6195
|
},
|
|
4863
6196
|
nonRoot: {
|
|
4864
|
-
relativeDirPath:
|
|
6197
|
+
relativeDirPath: join60(".agents", "memories")
|
|
4865
6198
|
}
|
|
4866
6199
|
};
|
|
4867
6200
|
}
|
|
@@ -4871,8 +6204,8 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
4871
6204
|
validate = true
|
|
4872
6205
|
}) {
|
|
4873
6206
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
4874
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
4875
|
-
const fileContent = await readFileContent(
|
|
6207
|
+
const relativePath = isRoot ? "AGENTS.md" : join60(".agents", "memories", relativeFilePath);
|
|
6208
|
+
const fileContent = await readFileContent(join60(baseDir, relativePath));
|
|
4876
6209
|
return new _AgentsMdRule({
|
|
4877
6210
|
baseDir,
|
|
4878
6211
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -4912,12 +6245,12 @@ var AgentsMdRule = class _AgentsMdRule extends ToolRule {
|
|
|
4912
6245
|
};
|
|
4913
6246
|
|
|
4914
6247
|
// src/features/rules/amazonqcli-rule.ts
|
|
4915
|
-
import { join as
|
|
6248
|
+
import { join as join61 } from "path";
|
|
4916
6249
|
var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
4917
6250
|
static getSettablePaths() {
|
|
4918
6251
|
return {
|
|
4919
6252
|
nonRoot: {
|
|
4920
|
-
relativeDirPath:
|
|
6253
|
+
relativeDirPath: join61(".amazonq", "rules")
|
|
4921
6254
|
}
|
|
4922
6255
|
};
|
|
4923
6256
|
}
|
|
@@ -4927,7 +6260,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
4927
6260
|
validate = true
|
|
4928
6261
|
}) {
|
|
4929
6262
|
const fileContent = await readFileContent(
|
|
4930
|
-
|
|
6263
|
+
join61(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
4931
6264
|
);
|
|
4932
6265
|
return new _AmazonQCliRule({
|
|
4933
6266
|
baseDir,
|
|
@@ -4967,7 +6300,7 @@ var AmazonQCliRule = class _AmazonQCliRule extends ToolRule {
|
|
|
4967
6300
|
};
|
|
4968
6301
|
|
|
4969
6302
|
// src/features/rules/augmentcode-legacy-rule.ts
|
|
4970
|
-
import { join as
|
|
6303
|
+
import { join as join62 } from "path";
|
|
4971
6304
|
var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
4972
6305
|
toRulesyncRule() {
|
|
4973
6306
|
const rulesyncFrontmatter = {
|
|
@@ -4993,7 +6326,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
4993
6326
|
relativeFilePath: ".augment-guidelines"
|
|
4994
6327
|
},
|
|
4995
6328
|
nonRoot: {
|
|
4996
|
-
relativeDirPath:
|
|
6329
|
+
relativeDirPath: join62(".augment", "rules")
|
|
4997
6330
|
}
|
|
4998
6331
|
};
|
|
4999
6332
|
}
|
|
@@ -5028,8 +6361,8 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
5028
6361
|
}) {
|
|
5029
6362
|
const settablePaths = this.getSettablePaths();
|
|
5030
6363
|
const isRoot = relativeFilePath === settablePaths.root.relativeFilePath;
|
|
5031
|
-
const relativePath = isRoot ? settablePaths.root.relativeFilePath :
|
|
5032
|
-
const fileContent = await readFileContent(
|
|
6364
|
+
const relativePath = isRoot ? settablePaths.root.relativeFilePath : join62(settablePaths.nonRoot.relativeDirPath, relativeFilePath);
|
|
6365
|
+
const fileContent = await readFileContent(join62(baseDir, relativePath));
|
|
5033
6366
|
return new _AugmentcodeLegacyRule({
|
|
5034
6367
|
baseDir,
|
|
5035
6368
|
relativeDirPath: isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath,
|
|
@@ -5042,7 +6375,7 @@ var AugmentcodeLegacyRule = class _AugmentcodeLegacyRule extends ToolRule {
|
|
|
5042
6375
|
};
|
|
5043
6376
|
|
|
5044
6377
|
// src/features/rules/augmentcode-rule.ts
|
|
5045
|
-
import { join as
|
|
6378
|
+
import { join as join63 } from "path";
|
|
5046
6379
|
var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
5047
6380
|
toRulesyncRule() {
|
|
5048
6381
|
return this.toRulesyncRuleDefault();
|
|
@@ -5050,7 +6383,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
5050
6383
|
static getSettablePaths() {
|
|
5051
6384
|
return {
|
|
5052
6385
|
nonRoot: {
|
|
5053
|
-
relativeDirPath:
|
|
6386
|
+
relativeDirPath: join63(".augment", "rules")
|
|
5054
6387
|
}
|
|
5055
6388
|
};
|
|
5056
6389
|
}
|
|
@@ -5074,7 +6407,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
5074
6407
|
validate = true
|
|
5075
6408
|
}) {
|
|
5076
6409
|
const fileContent = await readFileContent(
|
|
5077
|
-
|
|
6410
|
+
join63(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5078
6411
|
);
|
|
5079
6412
|
const { body: content } = parseFrontmatter(fileContent);
|
|
5080
6413
|
return new _AugmentcodeRule({
|
|
@@ -5097,7 +6430,7 @@ var AugmentcodeRule = class _AugmentcodeRule extends ToolRule {
|
|
|
5097
6430
|
};
|
|
5098
6431
|
|
|
5099
6432
|
// src/features/rules/claudecode-rule.ts
|
|
5100
|
-
import { join as
|
|
6433
|
+
import { join as join64 } from "path";
|
|
5101
6434
|
var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
5102
6435
|
static getSettablePaths({
|
|
5103
6436
|
global
|
|
@@ -5116,7 +6449,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
5116
6449
|
relativeFilePath: "CLAUDE.md"
|
|
5117
6450
|
},
|
|
5118
6451
|
nonRoot: {
|
|
5119
|
-
relativeDirPath:
|
|
6452
|
+
relativeDirPath: join64(".claude", "memories")
|
|
5120
6453
|
}
|
|
5121
6454
|
};
|
|
5122
6455
|
}
|
|
@@ -5131,7 +6464,7 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
5131
6464
|
if (isRoot) {
|
|
5132
6465
|
const relativePath2 = paths.root.relativeFilePath;
|
|
5133
6466
|
const fileContent2 = await readFileContent(
|
|
5134
|
-
|
|
6467
|
+
join64(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
5135
6468
|
);
|
|
5136
6469
|
return new _ClaudecodeRule({
|
|
5137
6470
|
baseDir,
|
|
@@ -5145,8 +6478,8 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
5145
6478
|
if (!paths.nonRoot) {
|
|
5146
6479
|
throw new Error("nonRoot path is not set");
|
|
5147
6480
|
}
|
|
5148
|
-
const relativePath =
|
|
5149
|
-
const fileContent = await readFileContent(
|
|
6481
|
+
const relativePath = join64(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
6482
|
+
const fileContent = await readFileContent(join64(baseDir, relativePath));
|
|
5150
6483
|
return new _ClaudecodeRule({
|
|
5151
6484
|
baseDir,
|
|
5152
6485
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -5188,10 +6521,10 @@ var ClaudecodeRule = class _ClaudecodeRule extends ToolRule {
|
|
|
5188
6521
|
};
|
|
5189
6522
|
|
|
5190
6523
|
// src/features/rules/cline-rule.ts
|
|
5191
|
-
import { join as
|
|
5192
|
-
import { z as
|
|
5193
|
-
var ClineRuleFrontmatterSchema =
|
|
5194
|
-
description:
|
|
6524
|
+
import { join as join65 } from "path";
|
|
6525
|
+
import { z as z26 } from "zod/mini";
|
|
6526
|
+
var ClineRuleFrontmatterSchema = z26.object({
|
|
6527
|
+
description: z26.string()
|
|
5195
6528
|
});
|
|
5196
6529
|
var ClineRule = class _ClineRule extends ToolRule {
|
|
5197
6530
|
static getSettablePaths() {
|
|
@@ -5233,7 +6566,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
5233
6566
|
validate = true
|
|
5234
6567
|
}) {
|
|
5235
6568
|
const fileContent = await readFileContent(
|
|
5236
|
-
|
|
6569
|
+
join65(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5237
6570
|
);
|
|
5238
6571
|
return new _ClineRule({
|
|
5239
6572
|
baseDir,
|
|
@@ -5246,7 +6579,7 @@ var ClineRule = class _ClineRule extends ToolRule {
|
|
|
5246
6579
|
};
|
|
5247
6580
|
|
|
5248
6581
|
// src/features/rules/codexcli-rule.ts
|
|
5249
|
-
import { join as
|
|
6582
|
+
import { join as join66 } from "path";
|
|
5250
6583
|
var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
5251
6584
|
static getSettablePaths({
|
|
5252
6585
|
global
|
|
@@ -5265,7 +6598,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
5265
6598
|
relativeFilePath: "AGENTS.md"
|
|
5266
6599
|
},
|
|
5267
6600
|
nonRoot: {
|
|
5268
|
-
relativeDirPath:
|
|
6601
|
+
relativeDirPath: join66(".codex", "memories")
|
|
5269
6602
|
}
|
|
5270
6603
|
};
|
|
5271
6604
|
}
|
|
@@ -5280,7 +6613,7 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
5280
6613
|
if (isRoot) {
|
|
5281
6614
|
const relativePath2 = paths.root.relativeFilePath;
|
|
5282
6615
|
const fileContent2 = await readFileContent(
|
|
5283
|
-
|
|
6616
|
+
join66(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
5284
6617
|
);
|
|
5285
6618
|
return new _CodexcliRule({
|
|
5286
6619
|
baseDir,
|
|
@@ -5294,8 +6627,8 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
5294
6627
|
if (!paths.nonRoot) {
|
|
5295
6628
|
throw new Error("nonRoot path is not set");
|
|
5296
6629
|
}
|
|
5297
|
-
const relativePath =
|
|
5298
|
-
const fileContent = await readFileContent(
|
|
6630
|
+
const relativePath = join66(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
6631
|
+
const fileContent = await readFileContent(join66(baseDir, relativePath));
|
|
5299
6632
|
return new _CodexcliRule({
|
|
5300
6633
|
baseDir,
|
|
5301
6634
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -5337,11 +6670,11 @@ var CodexcliRule = class _CodexcliRule extends ToolRule {
|
|
|
5337
6670
|
};
|
|
5338
6671
|
|
|
5339
6672
|
// src/features/rules/copilot-rule.ts
|
|
5340
|
-
import { join as
|
|
5341
|
-
import { z as
|
|
5342
|
-
var CopilotRuleFrontmatterSchema =
|
|
5343
|
-
description:
|
|
5344
|
-
applyTo:
|
|
6673
|
+
import { join as join67 } from "path";
|
|
6674
|
+
import { z as z27 } from "zod/mini";
|
|
6675
|
+
var CopilotRuleFrontmatterSchema = z27.object({
|
|
6676
|
+
description: z27.optional(z27.string()),
|
|
6677
|
+
applyTo: z27.optional(z27.string())
|
|
5345
6678
|
});
|
|
5346
6679
|
var CopilotRule = class _CopilotRule extends ToolRule {
|
|
5347
6680
|
frontmatter;
|
|
@@ -5353,7 +6686,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5353
6686
|
relativeFilePath: "copilot-instructions.md"
|
|
5354
6687
|
},
|
|
5355
6688
|
nonRoot: {
|
|
5356
|
-
relativeDirPath:
|
|
6689
|
+
relativeDirPath: join67(".github", "instructions")
|
|
5357
6690
|
}
|
|
5358
6691
|
};
|
|
5359
6692
|
}
|
|
@@ -5362,7 +6695,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5362
6695
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5363
6696
|
if (!result.success) {
|
|
5364
6697
|
throw new Error(
|
|
5365
|
-
`Invalid frontmatter in ${
|
|
6698
|
+
`Invalid frontmatter in ${join67(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
5366
6699
|
);
|
|
5367
6700
|
}
|
|
5368
6701
|
}
|
|
@@ -5440,11 +6773,11 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5440
6773
|
validate = true
|
|
5441
6774
|
}) {
|
|
5442
6775
|
const isRoot = relativeFilePath === "copilot-instructions.md";
|
|
5443
|
-
const relativePath = isRoot ?
|
|
6776
|
+
const relativePath = isRoot ? join67(
|
|
5444
6777
|
this.getSettablePaths().root.relativeDirPath,
|
|
5445
6778
|
this.getSettablePaths().root.relativeFilePath
|
|
5446
|
-
) :
|
|
5447
|
-
const fileContent = await readFileContent(
|
|
6779
|
+
) : join67(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
6780
|
+
const fileContent = await readFileContent(join67(baseDir, relativePath));
|
|
5448
6781
|
if (isRoot) {
|
|
5449
6782
|
return new _CopilotRule({
|
|
5450
6783
|
baseDir,
|
|
@@ -5463,7 +6796,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5463
6796
|
const result = CopilotRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5464
6797
|
if (!result.success) {
|
|
5465
6798
|
throw new Error(
|
|
5466
|
-
`Invalid frontmatter in ${
|
|
6799
|
+
`Invalid frontmatter in ${join67(baseDir, relativeFilePath)}: ${formatError(result.error)}`
|
|
5467
6800
|
);
|
|
5468
6801
|
}
|
|
5469
6802
|
return new _CopilotRule({
|
|
@@ -5487,7 +6820,7 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5487
6820
|
return {
|
|
5488
6821
|
success: false,
|
|
5489
6822
|
error: new Error(
|
|
5490
|
-
`Invalid frontmatter in ${
|
|
6823
|
+
`Invalid frontmatter in ${join67(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
5491
6824
|
)
|
|
5492
6825
|
};
|
|
5493
6826
|
}
|
|
@@ -5507,12 +6840,12 @@ var CopilotRule = class _CopilotRule extends ToolRule {
|
|
|
5507
6840
|
};
|
|
5508
6841
|
|
|
5509
6842
|
// src/features/rules/cursor-rule.ts
|
|
5510
|
-
import { basename as
|
|
5511
|
-
import { z as
|
|
5512
|
-
var CursorRuleFrontmatterSchema =
|
|
5513
|
-
description:
|
|
5514
|
-
globs:
|
|
5515
|
-
alwaysApply:
|
|
6843
|
+
import { basename as basename18, join as join68 } from "path";
|
|
6844
|
+
import { z as z28 } from "zod/mini";
|
|
6845
|
+
var CursorRuleFrontmatterSchema = z28.object({
|
|
6846
|
+
description: z28.optional(z28.string()),
|
|
6847
|
+
globs: z28.optional(z28.string()),
|
|
6848
|
+
alwaysApply: z28.optional(z28.boolean())
|
|
5516
6849
|
});
|
|
5517
6850
|
var CursorRule = class _CursorRule extends ToolRule {
|
|
5518
6851
|
frontmatter;
|
|
@@ -5520,7 +6853,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5520
6853
|
static getSettablePaths() {
|
|
5521
6854
|
return {
|
|
5522
6855
|
nonRoot: {
|
|
5523
|
-
relativeDirPath:
|
|
6856
|
+
relativeDirPath: join68(".cursor", "rules")
|
|
5524
6857
|
}
|
|
5525
6858
|
};
|
|
5526
6859
|
}
|
|
@@ -5529,7 +6862,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5529
6862
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5530
6863
|
if (!result.success) {
|
|
5531
6864
|
throw new Error(
|
|
5532
|
-
`Invalid frontmatter in ${
|
|
6865
|
+
`Invalid frontmatter in ${join68(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`
|
|
5533
6866
|
);
|
|
5534
6867
|
}
|
|
5535
6868
|
}
|
|
@@ -5646,19 +6979,19 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5646
6979
|
validate = true
|
|
5647
6980
|
}) {
|
|
5648
6981
|
const fileContent = await readFileContent(
|
|
5649
|
-
|
|
6982
|
+
join68(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5650
6983
|
);
|
|
5651
6984
|
const { frontmatter, body: content } = _CursorRule.parseCursorFrontmatter(fileContent);
|
|
5652
6985
|
const result = CursorRuleFrontmatterSchema.safeParse(frontmatter);
|
|
5653
6986
|
if (!result.success) {
|
|
5654
6987
|
throw new Error(
|
|
5655
|
-
`Invalid frontmatter in ${
|
|
6988
|
+
`Invalid frontmatter in ${join68(baseDir, relativeFilePath)}: ${formatError(result.error)}`
|
|
5656
6989
|
);
|
|
5657
6990
|
}
|
|
5658
6991
|
return new _CursorRule({
|
|
5659
6992
|
baseDir,
|
|
5660
6993
|
relativeDirPath: this.getSettablePaths().nonRoot.relativeDirPath,
|
|
5661
|
-
relativeFilePath:
|
|
6994
|
+
relativeFilePath: basename18(relativeFilePath),
|
|
5662
6995
|
frontmatter: result.data,
|
|
5663
6996
|
body: content.trim(),
|
|
5664
6997
|
validate
|
|
@@ -5675,7 +7008,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5675
7008
|
return {
|
|
5676
7009
|
success: false,
|
|
5677
7010
|
error: new Error(
|
|
5678
|
-
`Invalid frontmatter in ${
|
|
7011
|
+
`Invalid frontmatter in ${join68(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`
|
|
5679
7012
|
)
|
|
5680
7013
|
};
|
|
5681
7014
|
}
|
|
@@ -5695,7 +7028,7 @@ var CursorRule = class _CursorRule extends ToolRule {
|
|
|
5695
7028
|
};
|
|
5696
7029
|
|
|
5697
7030
|
// src/features/rules/geminicli-rule.ts
|
|
5698
|
-
import { join as
|
|
7031
|
+
import { join as join69 } from "path";
|
|
5699
7032
|
var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
5700
7033
|
static getSettablePaths({
|
|
5701
7034
|
global
|
|
@@ -5714,7 +7047,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5714
7047
|
relativeFilePath: "GEMINI.md"
|
|
5715
7048
|
},
|
|
5716
7049
|
nonRoot: {
|
|
5717
|
-
relativeDirPath:
|
|
7050
|
+
relativeDirPath: join69(".gemini", "memories")
|
|
5718
7051
|
}
|
|
5719
7052
|
};
|
|
5720
7053
|
}
|
|
@@ -5729,7 +7062,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5729
7062
|
if (isRoot) {
|
|
5730
7063
|
const relativePath2 = paths.root.relativeFilePath;
|
|
5731
7064
|
const fileContent2 = await readFileContent(
|
|
5732
|
-
|
|
7065
|
+
join69(baseDir, paths.root.relativeDirPath, relativePath2)
|
|
5733
7066
|
);
|
|
5734
7067
|
return new _GeminiCliRule({
|
|
5735
7068
|
baseDir,
|
|
@@ -5743,8 +7076,8 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5743
7076
|
if (!paths.nonRoot) {
|
|
5744
7077
|
throw new Error("nonRoot path is not set");
|
|
5745
7078
|
}
|
|
5746
|
-
const relativePath =
|
|
5747
|
-
const fileContent = await readFileContent(
|
|
7079
|
+
const relativePath = join69(paths.nonRoot.relativeDirPath, relativeFilePath);
|
|
7080
|
+
const fileContent = await readFileContent(join69(baseDir, relativePath));
|
|
5748
7081
|
return new _GeminiCliRule({
|
|
5749
7082
|
baseDir,
|
|
5750
7083
|
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
@@ -5786,7 +7119,7 @@ var GeminiCliRule = class _GeminiCliRule extends ToolRule {
|
|
|
5786
7119
|
};
|
|
5787
7120
|
|
|
5788
7121
|
// src/features/rules/junie-rule.ts
|
|
5789
|
-
import { join as
|
|
7122
|
+
import { join as join70 } from "path";
|
|
5790
7123
|
var JunieRule = class _JunieRule extends ToolRule {
|
|
5791
7124
|
static getSettablePaths() {
|
|
5792
7125
|
return {
|
|
@@ -5795,7 +7128,7 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
5795
7128
|
relativeFilePath: "guidelines.md"
|
|
5796
7129
|
},
|
|
5797
7130
|
nonRoot: {
|
|
5798
|
-
relativeDirPath:
|
|
7131
|
+
relativeDirPath: join70(".junie", "memories")
|
|
5799
7132
|
}
|
|
5800
7133
|
};
|
|
5801
7134
|
}
|
|
@@ -5805,8 +7138,8 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
5805
7138
|
validate = true
|
|
5806
7139
|
}) {
|
|
5807
7140
|
const isRoot = relativeFilePath === "guidelines.md";
|
|
5808
|
-
const relativePath = isRoot ? "guidelines.md" :
|
|
5809
|
-
const fileContent = await readFileContent(
|
|
7141
|
+
const relativePath = isRoot ? "guidelines.md" : join70(".junie", "memories", relativeFilePath);
|
|
7142
|
+
const fileContent = await readFileContent(join70(baseDir, relativePath));
|
|
5810
7143
|
return new _JunieRule({
|
|
5811
7144
|
baseDir,
|
|
5812
7145
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -5846,12 +7179,12 @@ var JunieRule = class _JunieRule extends ToolRule {
|
|
|
5846
7179
|
};
|
|
5847
7180
|
|
|
5848
7181
|
// src/features/rules/kiro-rule.ts
|
|
5849
|
-
import { join as
|
|
7182
|
+
import { join as join71 } from "path";
|
|
5850
7183
|
var KiroRule = class _KiroRule extends ToolRule {
|
|
5851
7184
|
static getSettablePaths() {
|
|
5852
7185
|
return {
|
|
5853
7186
|
nonRoot: {
|
|
5854
|
-
relativeDirPath:
|
|
7187
|
+
relativeDirPath: join71(".kiro", "steering")
|
|
5855
7188
|
}
|
|
5856
7189
|
};
|
|
5857
7190
|
}
|
|
@@ -5861,7 +7194,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
5861
7194
|
validate = true
|
|
5862
7195
|
}) {
|
|
5863
7196
|
const fileContent = await readFileContent(
|
|
5864
|
-
|
|
7197
|
+
join71(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
5865
7198
|
);
|
|
5866
7199
|
return new _KiroRule({
|
|
5867
7200
|
baseDir,
|
|
@@ -5901,7 +7234,7 @@ var KiroRule = class _KiroRule extends ToolRule {
|
|
|
5901
7234
|
};
|
|
5902
7235
|
|
|
5903
7236
|
// src/features/rules/opencode-rule.ts
|
|
5904
|
-
import { join as
|
|
7237
|
+
import { join as join72 } from "path";
|
|
5905
7238
|
var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
5906
7239
|
static getSettablePaths() {
|
|
5907
7240
|
return {
|
|
@@ -5910,7 +7243,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
5910
7243
|
relativeFilePath: "AGENTS.md"
|
|
5911
7244
|
},
|
|
5912
7245
|
nonRoot: {
|
|
5913
|
-
relativeDirPath:
|
|
7246
|
+
relativeDirPath: join72(".opencode", "memories")
|
|
5914
7247
|
}
|
|
5915
7248
|
};
|
|
5916
7249
|
}
|
|
@@ -5920,8 +7253,8 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
5920
7253
|
validate = true
|
|
5921
7254
|
}) {
|
|
5922
7255
|
const isRoot = relativeFilePath === "AGENTS.md";
|
|
5923
|
-
const relativePath = isRoot ? "AGENTS.md" :
|
|
5924
|
-
const fileContent = await readFileContent(
|
|
7256
|
+
const relativePath = isRoot ? "AGENTS.md" : join72(".opencode", "memories", relativeFilePath);
|
|
7257
|
+
const fileContent = await readFileContent(join72(baseDir, relativePath));
|
|
5925
7258
|
return new _OpenCodeRule({
|
|
5926
7259
|
baseDir,
|
|
5927
7260
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -5961,7 +7294,7 @@ var OpenCodeRule = class _OpenCodeRule extends ToolRule {
|
|
|
5961
7294
|
};
|
|
5962
7295
|
|
|
5963
7296
|
// src/features/rules/qwencode-rule.ts
|
|
5964
|
-
import { join as
|
|
7297
|
+
import { join as join73 } from "path";
|
|
5965
7298
|
var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
5966
7299
|
static getSettablePaths() {
|
|
5967
7300
|
return {
|
|
@@ -5970,7 +7303,7 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
5970
7303
|
relativeFilePath: "QWEN.md"
|
|
5971
7304
|
},
|
|
5972
7305
|
nonRoot: {
|
|
5973
|
-
relativeDirPath:
|
|
7306
|
+
relativeDirPath: join73(".qwen", "memories")
|
|
5974
7307
|
}
|
|
5975
7308
|
};
|
|
5976
7309
|
}
|
|
@@ -5980,8 +7313,8 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
5980
7313
|
validate = true
|
|
5981
7314
|
}) {
|
|
5982
7315
|
const isRoot = relativeFilePath === "QWEN.md";
|
|
5983
|
-
const relativePath = isRoot ? "QWEN.md" :
|
|
5984
|
-
const fileContent = await readFileContent(
|
|
7316
|
+
const relativePath = isRoot ? "QWEN.md" : join73(".qwen", "memories", relativeFilePath);
|
|
7317
|
+
const fileContent = await readFileContent(join73(baseDir, relativePath));
|
|
5985
7318
|
return new _QwencodeRule({
|
|
5986
7319
|
baseDir,
|
|
5987
7320
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : this.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -6018,12 +7351,12 @@ var QwencodeRule = class _QwencodeRule extends ToolRule {
|
|
|
6018
7351
|
};
|
|
6019
7352
|
|
|
6020
7353
|
// src/features/rules/roo-rule.ts
|
|
6021
|
-
import { join as
|
|
7354
|
+
import { join as join74 } from "path";
|
|
6022
7355
|
var RooRule = class _RooRule extends ToolRule {
|
|
6023
7356
|
static getSettablePaths() {
|
|
6024
7357
|
return {
|
|
6025
7358
|
nonRoot: {
|
|
6026
|
-
relativeDirPath:
|
|
7359
|
+
relativeDirPath: join74(".roo", "rules")
|
|
6027
7360
|
}
|
|
6028
7361
|
};
|
|
6029
7362
|
}
|
|
@@ -6033,7 +7366,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
6033
7366
|
validate = true
|
|
6034
7367
|
}) {
|
|
6035
7368
|
const fileContent = await readFileContent(
|
|
6036
|
-
|
|
7369
|
+
join74(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
6037
7370
|
);
|
|
6038
7371
|
return new _RooRule({
|
|
6039
7372
|
baseDir,
|
|
@@ -6088,7 +7421,7 @@ var RooRule = class _RooRule extends ToolRule {
|
|
|
6088
7421
|
};
|
|
6089
7422
|
|
|
6090
7423
|
// src/features/rules/warp-rule.ts
|
|
6091
|
-
import { join as
|
|
7424
|
+
import { join as join75 } from "path";
|
|
6092
7425
|
var WarpRule = class _WarpRule extends ToolRule {
|
|
6093
7426
|
constructor({ fileContent, root, ...rest }) {
|
|
6094
7427
|
super({
|
|
@@ -6104,7 +7437,7 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
6104
7437
|
relativeFilePath: "WARP.md"
|
|
6105
7438
|
},
|
|
6106
7439
|
nonRoot: {
|
|
6107
|
-
relativeDirPath:
|
|
7440
|
+
relativeDirPath: join75(".warp", "memories")
|
|
6108
7441
|
}
|
|
6109
7442
|
};
|
|
6110
7443
|
}
|
|
@@ -6114,8 +7447,8 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
6114
7447
|
validate = true
|
|
6115
7448
|
}) {
|
|
6116
7449
|
const isRoot = relativeFilePath === this.getSettablePaths().root.relativeFilePath;
|
|
6117
|
-
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath :
|
|
6118
|
-
const fileContent = await readFileContent(
|
|
7450
|
+
const relativePath = isRoot ? this.getSettablePaths().root.relativeFilePath : join75(this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath);
|
|
7451
|
+
const fileContent = await readFileContent(join75(baseDir, relativePath));
|
|
6119
7452
|
return new _WarpRule({
|
|
6120
7453
|
baseDir,
|
|
6121
7454
|
relativeDirPath: isRoot ? this.getSettablePaths().root.relativeDirPath : ".warp",
|
|
@@ -6155,12 +7488,12 @@ var WarpRule = class _WarpRule extends ToolRule {
|
|
|
6155
7488
|
};
|
|
6156
7489
|
|
|
6157
7490
|
// src/features/rules/windsurf-rule.ts
|
|
6158
|
-
import { join as
|
|
7491
|
+
import { join as join76 } from "path";
|
|
6159
7492
|
var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
6160
7493
|
static getSettablePaths() {
|
|
6161
7494
|
return {
|
|
6162
7495
|
nonRoot: {
|
|
6163
|
-
relativeDirPath:
|
|
7496
|
+
relativeDirPath: join76(".windsurf", "rules")
|
|
6164
7497
|
}
|
|
6165
7498
|
};
|
|
6166
7499
|
}
|
|
@@ -6170,7 +7503,7 @@ var WindsurfRule = class _WindsurfRule extends ToolRule {
|
|
|
6170
7503
|
validate = true
|
|
6171
7504
|
}) {
|
|
6172
7505
|
const fileContent = await readFileContent(
|
|
6173
|
-
|
|
7506
|
+
join76(baseDir, this.getSettablePaths().nonRoot.relativeDirPath, relativeFilePath)
|
|
6174
7507
|
);
|
|
6175
7508
|
return new _WindsurfRule({
|
|
6176
7509
|
baseDir,
|
|
@@ -6228,7 +7561,7 @@ var rulesProcessorToolTargets = [
|
|
|
6228
7561
|
"warp",
|
|
6229
7562
|
"windsurf"
|
|
6230
7563
|
];
|
|
6231
|
-
var RulesProcessorToolTargetSchema =
|
|
7564
|
+
var RulesProcessorToolTargetSchema = z29.enum(rulesProcessorToolTargets);
|
|
6232
7565
|
var rulesProcessorToolTargetsGlobal = [
|
|
6233
7566
|
"claudecode",
|
|
6234
7567
|
"codexcli",
|
|
@@ -6238,12 +7571,14 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6238
7571
|
toolTarget;
|
|
6239
7572
|
simulateCommands;
|
|
6240
7573
|
simulateSubagents;
|
|
7574
|
+
simulateSkills;
|
|
6241
7575
|
global;
|
|
6242
7576
|
constructor({
|
|
6243
7577
|
baseDir = process.cwd(),
|
|
6244
7578
|
toolTarget,
|
|
6245
7579
|
simulateCommands = false,
|
|
6246
7580
|
simulateSubagents = false,
|
|
7581
|
+
simulateSkills = false,
|
|
6247
7582
|
global = false
|
|
6248
7583
|
}) {
|
|
6249
7584
|
super({ baseDir });
|
|
@@ -6257,6 +7592,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6257
7592
|
this.global = global;
|
|
6258
7593
|
this.simulateCommands = simulateCommands;
|
|
6259
7594
|
this.simulateSubagents = simulateSubagents;
|
|
7595
|
+
this.simulateSkills = simulateSkills;
|
|
6260
7596
|
}
|
|
6261
7597
|
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
6262
7598
|
const rulesyncRules = rulesyncFiles.filter(
|
|
@@ -6424,7 +7760,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6424
7760
|
throw new Error(`Unsupported tool target: ${this.toolTarget}`);
|
|
6425
7761
|
}
|
|
6426
7762
|
}).filter((rule) => rule !== null);
|
|
6427
|
-
const isSimulated = this.simulateCommands || this.simulateSubagents;
|
|
7763
|
+
const isSimulated = this.simulateCommands || this.simulateSubagents || this.simulateSkills;
|
|
6428
7764
|
if (isSimulated && this.toolTarget === "cursor") {
|
|
6429
7765
|
toolRules.push(
|
|
6430
7766
|
new CursorRule({
|
|
@@ -6436,6 +7772,9 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6436
7772
|
commands: { relativeDirPath: CursorCommand.getSettablePaths().relativeDirPath },
|
|
6437
7773
|
subagents: {
|
|
6438
7774
|
relativeDirPath: CursorSubagent.getSettablePaths().relativeDirPath
|
|
7775
|
+
},
|
|
7776
|
+
skills: {
|
|
7777
|
+
relativeDirPath: CursorSkill.getSettablePaths().relativeDirPath
|
|
6439
7778
|
}
|
|
6440
7779
|
}),
|
|
6441
7780
|
relativeDirPath: CursorRule.getSettablePaths().nonRoot.relativeDirPath,
|
|
@@ -6497,6 +7836,9 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6497
7836
|
this.generateXmlReferencesSection(toolRules) + this.generateAdditionalConventionsSection({
|
|
6498
7837
|
subagents: {
|
|
6499
7838
|
relativeDirPath: CodexCliSubagent.getSettablePaths().relativeDirPath
|
|
7839
|
+
},
|
|
7840
|
+
skills: {
|
|
7841
|
+
relativeDirPath: CodexCliSkill.getSettablePaths().relativeDirPath
|
|
6500
7842
|
}
|
|
6501
7843
|
}) + rootRule.getFileContent()
|
|
6502
7844
|
);
|
|
@@ -6509,6 +7851,9 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6509
7851
|
commands: { relativeDirPath: CopilotCommand.getSettablePaths().relativeDirPath },
|
|
6510
7852
|
subagents: {
|
|
6511
7853
|
relativeDirPath: CopilotSubagent.getSettablePaths().relativeDirPath
|
|
7854
|
+
},
|
|
7855
|
+
skills: {
|
|
7856
|
+
relativeDirPath: CopilotSkill.getSettablePaths().relativeDirPath
|
|
6512
7857
|
}
|
|
6513
7858
|
}) + rootRule.getFileContent()
|
|
6514
7859
|
);
|
|
@@ -6570,10 +7915,10 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6570
7915
|
* Load and parse rulesync rule files from .rulesync/rules/ directory
|
|
6571
7916
|
*/
|
|
6572
7917
|
async loadRulesyncFiles() {
|
|
6573
|
-
const files = await findFilesByGlobs(
|
|
7918
|
+
const files = await findFilesByGlobs(join77(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md"));
|
|
6574
7919
|
logger.debug(`Found ${files.length} rulesync files`);
|
|
6575
7920
|
const rulesyncRules = await Promise.all(
|
|
6576
|
-
files.map((file) => RulesyncRule.fromFile({ relativeFilePath:
|
|
7921
|
+
files.map((file) => RulesyncRule.fromFile({ relativeFilePath: basename19(file) }))
|
|
6577
7922
|
);
|
|
6578
7923
|
const rootRules = rulesyncRules.filter((rule) => rule.getFrontmatter().root);
|
|
6579
7924
|
if (rootRules.length > 1) {
|
|
@@ -6591,17 +7936,19 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6591
7936
|
return rulesyncRules;
|
|
6592
7937
|
}
|
|
6593
7938
|
async loadRulesyncFilesLegacy() {
|
|
6594
|
-
const legacyFiles = await findFilesByGlobs(
|
|
7939
|
+
const legacyFiles = await findFilesByGlobs(join77(RULESYNC_RELATIVE_DIR_PATH, "*.md"));
|
|
6595
7940
|
logger.debug(`Found ${legacyFiles.length} legacy rulesync files`);
|
|
6596
7941
|
return Promise.all(
|
|
6597
|
-
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath:
|
|
7942
|
+
legacyFiles.map((file) => RulesyncRule.fromFileLegacy({ relativeFilePath: basename19(file) }))
|
|
6598
7943
|
);
|
|
6599
7944
|
}
|
|
6600
7945
|
/**
|
|
6601
7946
|
* Implementation of abstract method from FeatureProcessor
|
|
6602
7947
|
* Load tool-specific rule configurations and parse them into ToolRule instances
|
|
6603
7948
|
*/
|
|
6604
|
-
async loadToolFiles(
|
|
7949
|
+
async loadToolFiles({
|
|
7950
|
+
forDeletion: _forDeletion = false
|
|
7951
|
+
} = {}) {
|
|
6605
7952
|
try {
|
|
6606
7953
|
switch (this.toolTarget) {
|
|
6607
7954
|
case "agentsmd":
|
|
@@ -6646,9 +7993,6 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6646
7993
|
return [];
|
|
6647
7994
|
}
|
|
6648
7995
|
}
|
|
6649
|
-
async loadToolFilesToDelete() {
|
|
6650
|
-
return this.loadToolFiles();
|
|
6651
|
-
}
|
|
6652
7996
|
async loadToolRulesDefault({
|
|
6653
7997
|
root,
|
|
6654
7998
|
nonRoot
|
|
@@ -6658,13 +8002,13 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6658
8002
|
return [];
|
|
6659
8003
|
}
|
|
6660
8004
|
const rootFilePaths = await findFilesByGlobs(
|
|
6661
|
-
|
|
8005
|
+
join77(this.baseDir, root.relativeDirPath ?? ".", root.relativeFilePath)
|
|
6662
8006
|
);
|
|
6663
8007
|
return await Promise.all(
|
|
6664
8008
|
rootFilePaths.map(
|
|
6665
8009
|
(filePath) => root.fromFile({
|
|
6666
8010
|
baseDir: this.baseDir,
|
|
6667
|
-
relativeFilePath:
|
|
8011
|
+
relativeFilePath: basename19(filePath),
|
|
6668
8012
|
global: this.global
|
|
6669
8013
|
})
|
|
6670
8014
|
)
|
|
@@ -6676,13 +8020,13 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6676
8020
|
return [];
|
|
6677
8021
|
}
|
|
6678
8022
|
const nonRootFilePaths = await findFilesByGlobs(
|
|
6679
|
-
|
|
8023
|
+
join77(this.baseDir, nonRoot.relativeDirPath, `*.${nonRoot.extension}`)
|
|
6680
8024
|
);
|
|
6681
8025
|
return await Promise.all(
|
|
6682
8026
|
nonRootFilePaths.map(
|
|
6683
8027
|
(filePath) => nonRoot.fromFile({
|
|
6684
8028
|
baseDir: this.baseDir,
|
|
6685
|
-
relativeFilePath:
|
|
8029
|
+
relativeFilePath: basename19(filePath),
|
|
6686
8030
|
global: this.global
|
|
6687
8031
|
})
|
|
6688
8032
|
)
|
|
@@ -6969,12 +8313,12 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
6969
8313
|
* Implementation of abstract method from FeatureProcessor
|
|
6970
8314
|
* Return the tool targets that this processor supports
|
|
6971
8315
|
*/
|
|
6972
|
-
static getToolTargets() {
|
|
8316
|
+
static getToolTargets({ global = false } = {}) {
|
|
8317
|
+
if (global) {
|
|
8318
|
+
return rulesProcessorToolTargetsGlobal;
|
|
8319
|
+
}
|
|
6973
8320
|
return rulesProcessorToolTargets;
|
|
6974
8321
|
}
|
|
6975
|
-
static getToolTargetsGlobal() {
|
|
6976
|
-
return rulesProcessorToolTargetsGlobal;
|
|
6977
|
-
}
|
|
6978
8322
|
generateXmlReferencesSection(toolRules) {
|
|
6979
8323
|
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
6980
8324
|
if (toolRulesWithoutRoot.length === 0) {
|
|
@@ -7032,7 +8376,8 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
7032
8376
|
}
|
|
7033
8377
|
generateAdditionalConventionsSection({
|
|
7034
8378
|
commands,
|
|
7035
|
-
subagents
|
|
8379
|
+
subagents,
|
|
8380
|
+
skills
|
|
7036
8381
|
}) {
|
|
7037
8382
|
const overview = `# Additional Conventions Beyond the Built-in Functions
|
|
7038
8383
|
|
|
@@ -7049,21 +8394,31 @@ Users can use following syntax to invoke a custom command.
|
|
|
7049
8394
|
s/<command> [arguments]
|
|
7050
8395
|
\`\`\`
|
|
7051
8396
|
|
|
7052
|
-
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
8397
|
+
This syntax employs a double slash (\`s/\`) to prevent conflicts with built-in slash commands.
|
|
7053
8398
|
The \`s\` in \`s/\` stands for *simulate*. Because custom slash commands are not built-in, this syntax provides a pseudo way to invoke them.
|
|
7054
8399
|
|
|
7055
|
-
When users call a custom slash command, you have to look for the markdown file, \`${
|
|
8400
|
+
When users call a custom slash command, you have to look for the markdown file, \`${join77(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "{command}.md")}\`, then execute the contents of that file as the block of operations.` : "";
|
|
7056
8401
|
const subagentsSection = subagents ? `## Simulated Subagents
|
|
7057
8402
|
|
|
7058
8403
|
Simulated subagents are specialized AI assistants that can be invoked to handle specific types of tasks. In this case, it can be appear something like custom slash commands simply. Simulated subagents can be called by custom slash commands.
|
|
7059
8404
|
|
|
7060
|
-
When users call a simulated subagent, it will look for the corresponding markdown file, \`${
|
|
8405
|
+
When users call a simulated subagent, it will look for the corresponding markdown file, \`${join77(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "{subagent}.md")}\`, and execute its contents as the block of operations.
|
|
7061
8406
|
|
|
7062
|
-
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${
|
|
8407
|
+
For example, if the user instructs \`Call planner subagent to plan the refactoring\`, you have to look for the markdown file, \`${join77(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "planner.md")}\`, and execute its contents as the block of operations.` : "";
|
|
8408
|
+
const skillsSection = skills ? `## Simulated Skills
|
|
8409
|
+
|
|
8410
|
+
Simulated skills are specialized capabilities that can be invoked to handle specific types of tasks.
|
|
8411
|
+
|
|
8412
|
+
When users invoke a simulated skill, look for the corresponding SKILL.md file in \`${join77(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "{skill}/SKILL.md")}\` and execute its contents as the block of operations.
|
|
8413
|
+
|
|
8414
|
+
For example, if the user instructs \`Use the skill example-skill to achieve something\`, look for \`${join77(RULESYNC_SKILLS_RELATIVE_DIR_PATH, "example-skill/SKILL.md")}\` and execute its contents.
|
|
8415
|
+
|
|
8416
|
+
Additionally, you should proactively consider using available skills when they would help accomplish a task more effectively, even if the user doesn't explicitly request them.` : "";
|
|
7063
8417
|
const result = [
|
|
7064
8418
|
overview,
|
|
7065
8419
|
...this.simulateCommands && CommandsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [commandsSection] : [],
|
|
7066
|
-
...this.simulateSubagents && SubagentsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [subagentsSection] : []
|
|
8420
|
+
...this.simulateSubagents && SubagentsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [subagentsSection] : [],
|
|
8421
|
+
...this.simulateSkills && SkillsProcessor.getToolTargetsSimulated().includes(this.toolTarget) ? [skillsSection] : []
|
|
7067
8422
|
].join("\n\n") + "\n\n";
|
|
7068
8423
|
return result;
|
|
7069
8424
|
}
|
|
@@ -7084,7 +8439,8 @@ async function generateCommand(options) {
|
|
|
7084
8439
|
const totalMcpOutputs = await generateMcp(config);
|
|
7085
8440
|
const totalCommandOutputs = await generateCommands(config);
|
|
7086
8441
|
const totalSubagentOutputs = await generateSubagents(config);
|
|
7087
|
-
const
|
|
8442
|
+
const totalSkillOutputs = await generateSkills(config);
|
|
8443
|
+
const totalGenerated = totalRulesOutputs + totalMcpOutputs + totalCommandOutputs + totalIgnoreOutputs + totalSubagentOutputs + totalSkillOutputs;
|
|
7088
8444
|
if (totalGenerated === 0) {
|
|
7089
8445
|
const enabledFeatures = config.getFeatures().join(", ");
|
|
7090
8446
|
logger.warn(`\u26A0\uFE0F No files generated for enabled features: ${enabledFeatures}`);
|
|
@@ -7097,6 +8453,7 @@ async function generateCommand(options) {
|
|
|
7097
8453
|
if (totalMcpOutputs > 0) parts.push(`${totalMcpOutputs} MCP files`);
|
|
7098
8454
|
if (totalCommandOutputs > 0) parts.push(`${totalCommandOutputs} commands`);
|
|
7099
8455
|
if (totalSubagentOutputs > 0) parts.push(`${totalSubagentOutputs} subagents`);
|
|
8456
|
+
if (totalSkillOutputs > 0) parts.push(`${totalSkillOutputs} skills`);
|
|
7100
8457
|
logger.success(`\u{1F389} All done! Generated ${totalGenerated} file(s) total (${parts.join(" + ")})`);
|
|
7101
8458
|
}
|
|
7102
8459
|
}
|
|
@@ -7107,18 +8464,22 @@ async function generateRules(config) {
|
|
|
7107
8464
|
}
|
|
7108
8465
|
let totalRulesOutputs = 0;
|
|
7109
8466
|
logger.info("Generating rule files...");
|
|
7110
|
-
const toolTargets =
|
|
8467
|
+
const toolTargets = intersection(
|
|
8468
|
+
config.getTargets(),
|
|
8469
|
+
RulesProcessor.getToolTargets({ global: config.getGlobal() })
|
|
8470
|
+
);
|
|
7111
8471
|
for (const baseDir of config.getBaseDirs()) {
|
|
7112
8472
|
for (const toolTarget of toolTargets) {
|
|
7113
8473
|
const processor = new RulesProcessor({
|
|
7114
8474
|
baseDir,
|
|
7115
8475
|
toolTarget,
|
|
7116
8476
|
global: config.getGlobal(),
|
|
7117
|
-
simulateCommands: config.
|
|
7118
|
-
simulateSubagents: config.
|
|
8477
|
+
simulateCommands: config.getSimulateCommands(),
|
|
8478
|
+
simulateSubagents: config.getSimulateSubagents(),
|
|
8479
|
+
simulateSkills: config.getSimulateSkills()
|
|
7119
8480
|
});
|
|
7120
8481
|
if (config.getDelete()) {
|
|
7121
|
-
const oldToolFiles = await processor.
|
|
8482
|
+
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
7122
8483
|
await processor.removeAiFiles(oldToolFiles);
|
|
7123
8484
|
}
|
|
7124
8485
|
let rulesyncFiles = await processor.loadRulesyncFiles();
|
|
@@ -7152,7 +8513,7 @@ async function generateIgnore(config) {
|
|
|
7152
8513
|
toolTarget
|
|
7153
8514
|
});
|
|
7154
8515
|
if (config.getDelete()) {
|
|
7155
|
-
const oldToolFiles = await processor.
|
|
8516
|
+
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
7156
8517
|
await processor.removeAiFiles(oldToolFiles);
|
|
7157
8518
|
}
|
|
7158
8519
|
const rulesyncFiles = await processor.loadRulesyncFiles();
|
|
@@ -7183,7 +8544,10 @@ async function generateMcp(config) {
|
|
|
7183
8544
|
if (config.getModularMcp()) {
|
|
7184
8545
|
logger.info("\u2139\uFE0F Modular MCP support is experimental.");
|
|
7185
8546
|
}
|
|
7186
|
-
const toolTargets =
|
|
8547
|
+
const toolTargets = intersection(
|
|
8548
|
+
config.getTargets(),
|
|
8549
|
+
McpProcessor.getToolTargets({ global: config.getGlobal() })
|
|
8550
|
+
);
|
|
7187
8551
|
for (const baseDir of config.getBaseDirs()) {
|
|
7188
8552
|
for (const toolTarget of toolTargets) {
|
|
7189
8553
|
const processor = new McpProcessor({
|
|
@@ -7193,7 +8557,7 @@ async function generateMcp(config) {
|
|
|
7193
8557
|
modularMcp: config.getModularMcp()
|
|
7194
8558
|
});
|
|
7195
8559
|
if (config.getDelete()) {
|
|
7196
|
-
const oldToolFiles = await processor.
|
|
8560
|
+
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
7197
8561
|
await processor.removeAiFiles(oldToolFiles);
|
|
7198
8562
|
}
|
|
7199
8563
|
const rulesyncFiles = await processor.loadRulesyncFiles();
|
|
@@ -7212,10 +8576,11 @@ async function generateCommands(config) {
|
|
|
7212
8576
|
}
|
|
7213
8577
|
let totalCommandOutputs = 0;
|
|
7214
8578
|
logger.info("Generating command files...");
|
|
7215
|
-
const toolTargets =
|
|
8579
|
+
const toolTargets = intersection(
|
|
7216
8580
|
config.getTargets(),
|
|
7217
8581
|
CommandsProcessor.getToolTargets({
|
|
7218
|
-
|
|
8582
|
+
global: config.getGlobal(),
|
|
8583
|
+
includeSimulated: config.getSimulateCommands()
|
|
7219
8584
|
})
|
|
7220
8585
|
);
|
|
7221
8586
|
for (const baseDir of config.getBaseDirs()) {
|
|
@@ -7226,7 +8591,7 @@ async function generateCommands(config) {
|
|
|
7226
8591
|
global: config.getGlobal()
|
|
7227
8592
|
});
|
|
7228
8593
|
if (config.getDelete()) {
|
|
7229
|
-
const oldToolFiles = await processor.
|
|
8594
|
+
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
7230
8595
|
await processor.removeAiFiles(oldToolFiles);
|
|
7231
8596
|
}
|
|
7232
8597
|
const rulesyncFiles = await processor.loadRulesyncFiles();
|
|
@@ -7245,10 +8610,11 @@ async function generateSubagents(config) {
|
|
|
7245
8610
|
}
|
|
7246
8611
|
let totalSubagentOutputs = 0;
|
|
7247
8612
|
logger.info("Generating subagent files...");
|
|
7248
|
-
const toolTargets =
|
|
8613
|
+
const toolTargets = intersection(
|
|
7249
8614
|
config.getTargets(),
|
|
7250
8615
|
SubagentsProcessor.getToolTargets({
|
|
7251
|
-
|
|
8616
|
+
global: config.getGlobal(),
|
|
8617
|
+
includeSimulated: config.getSimulateSubagents()
|
|
7252
8618
|
})
|
|
7253
8619
|
);
|
|
7254
8620
|
for (const baseDir of config.getBaseDirs()) {
|
|
@@ -7259,7 +8625,7 @@ async function generateSubagents(config) {
|
|
|
7259
8625
|
global: config.getGlobal()
|
|
7260
8626
|
});
|
|
7261
8627
|
if (config.getDelete()) {
|
|
7262
|
-
const oldToolFiles = await processor.
|
|
8628
|
+
const oldToolFiles = await processor.loadToolFiles({ forDeletion: true });
|
|
7263
8629
|
await processor.removeAiFiles(oldToolFiles);
|
|
7264
8630
|
}
|
|
7265
8631
|
const rulesyncFiles = await processor.loadRulesyncFiles();
|
|
@@ -7271,16 +8637,51 @@ async function generateSubagents(config) {
|
|
|
7271
8637
|
}
|
|
7272
8638
|
return totalSubagentOutputs;
|
|
7273
8639
|
}
|
|
8640
|
+
async function generateSkills(config) {
|
|
8641
|
+
if (!config.getFeatures().includes("skills")) {
|
|
8642
|
+
logger.debug("Skipping skill generation (not in --features)");
|
|
8643
|
+
return 0;
|
|
8644
|
+
}
|
|
8645
|
+
let totalSkillOutputs = 0;
|
|
8646
|
+
logger.info("Generating skill files...");
|
|
8647
|
+
const toolTargets = intersection(
|
|
8648
|
+
config.getTargets(),
|
|
8649
|
+
SkillsProcessor.getToolTargets({
|
|
8650
|
+
global: config.getGlobal(),
|
|
8651
|
+
includeSimulated: config.getSimulateSkills()
|
|
8652
|
+
})
|
|
8653
|
+
);
|
|
8654
|
+
for (const baseDir of config.getBaseDirs()) {
|
|
8655
|
+
for (const toolTarget of toolTargets) {
|
|
8656
|
+
const processor = new SkillsProcessor({
|
|
8657
|
+
baseDir,
|
|
8658
|
+
toolTarget,
|
|
8659
|
+
global: config.getGlobal()
|
|
8660
|
+
});
|
|
8661
|
+
if (config.getDelete()) {
|
|
8662
|
+
const oldToolDirs = await processor.loadToolDirsToDelete();
|
|
8663
|
+
await processor.removeAiDirs(oldToolDirs);
|
|
8664
|
+
}
|
|
8665
|
+
const rulesyncDirs = await processor.loadRulesyncDirs();
|
|
8666
|
+
const toolDirs = await processor.convertRulesyncDirsToToolDirs(rulesyncDirs);
|
|
8667
|
+
const writtenCount = await processor.writeAiDirs(toolDirs);
|
|
8668
|
+
totalSkillOutputs += writtenCount;
|
|
8669
|
+
logger.success(`Generated ${writtenCount} ${toolTarget} skill(s) in ${baseDir}`);
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8672
|
+
return totalSkillOutputs;
|
|
8673
|
+
}
|
|
7274
8674
|
|
|
7275
8675
|
// src/cli/commands/gitignore.ts
|
|
7276
|
-
import { join as
|
|
8676
|
+
import { join as join78 } from "path";
|
|
7277
8677
|
var gitignoreCommand = async () => {
|
|
7278
|
-
const gitignorePath =
|
|
8678
|
+
const gitignorePath = join78(process.cwd(), ".gitignore");
|
|
7279
8679
|
const rulesFilesToIgnore = [
|
|
7280
8680
|
"# Generated by rulesync - AI tool configuration files",
|
|
7281
8681
|
// AGENTS.md
|
|
7282
8682
|
"**/AGENTS.md",
|
|
7283
8683
|
"**/.agents/",
|
|
8684
|
+
"**/.agents/skills/",
|
|
7284
8685
|
// Amazon Q
|
|
7285
8686
|
"**/.amazonq/",
|
|
7286
8687
|
// Augment
|
|
@@ -7292,6 +8693,7 @@ var gitignoreCommand = async () => {
|
|
|
7292
8693
|
"**/.claude/memories/",
|
|
7293
8694
|
"**/.claude/commands/",
|
|
7294
8695
|
"**/.claude/agents/",
|
|
8696
|
+
"**/.claude/skills/",
|
|
7295
8697
|
"**/.claude/settings.local.json",
|
|
7296
8698
|
"**/.mcp.json",
|
|
7297
8699
|
// Cline
|
|
@@ -7301,20 +8703,25 @@ var gitignoreCommand = async () => {
|
|
|
7301
8703
|
// Codex
|
|
7302
8704
|
"**/.codexignore",
|
|
7303
8705
|
"**/.codex/",
|
|
8706
|
+
"**/.codex/skills/",
|
|
7304
8707
|
// Cursor
|
|
7305
8708
|
"**/.cursor/",
|
|
7306
8709
|
"**/.cursorignore",
|
|
7307
8710
|
"**/.cursor/mcp.json",
|
|
8711
|
+
"**/.cursor/subagents/",
|
|
8712
|
+
"**/.cursor/skills/",
|
|
7308
8713
|
// Gemini
|
|
7309
8714
|
"**/GEMINI.md",
|
|
7310
8715
|
"**/.gemini/memories/",
|
|
7311
8716
|
"**/.gemini/commands/",
|
|
7312
8717
|
"**/.gemini/subagents/",
|
|
8718
|
+
"**/.gemini/skills/",
|
|
7313
8719
|
// GitHub Copilot
|
|
7314
8720
|
"**/.github/copilot-instructions.md",
|
|
7315
8721
|
"**/.github/instructions/",
|
|
7316
8722
|
"**/.github/prompts/",
|
|
7317
8723
|
"**/.github/subagents/",
|
|
8724
|
+
"**/.github/skills/",
|
|
7318
8725
|
"**/.vscode/mcp.json",
|
|
7319
8726
|
// Junie
|
|
7320
8727
|
"**/.junie/guidelines.md",
|
|
@@ -7385,13 +8792,14 @@ async function importCommand(options) {
|
|
|
7385
8792
|
await importMcp(config, tool);
|
|
7386
8793
|
await importCommands(config, tool);
|
|
7387
8794
|
await importSubagents(config, tool);
|
|
8795
|
+
await importSkills(config, tool);
|
|
7388
8796
|
}
|
|
7389
8797
|
async function importRules(config, tool) {
|
|
7390
8798
|
if (!config.getFeatures().includes("rules")) {
|
|
7391
8799
|
return 0;
|
|
7392
8800
|
}
|
|
7393
8801
|
const global = config.getGlobal();
|
|
7394
|
-
const supportedTargets =
|
|
8802
|
+
const supportedTargets = RulesProcessor.getToolTargets({ global });
|
|
7395
8803
|
if (!supportedTargets.includes(tool)) {
|
|
7396
8804
|
return 0;
|
|
7397
8805
|
}
|
|
@@ -7445,7 +8853,7 @@ async function importMcp(config, tool) {
|
|
|
7445
8853
|
return 0;
|
|
7446
8854
|
}
|
|
7447
8855
|
const global = config.getGlobal();
|
|
7448
|
-
const supportedTargets =
|
|
8856
|
+
const supportedTargets = McpProcessor.getToolTargets({ global });
|
|
7449
8857
|
if (!supportedTargets.includes(tool)) {
|
|
7450
8858
|
return 0;
|
|
7451
8859
|
}
|
|
@@ -7470,7 +8878,7 @@ async function importCommands(config, tool) {
|
|
|
7470
8878
|
return 0;
|
|
7471
8879
|
}
|
|
7472
8880
|
const global = config.getGlobal();
|
|
7473
|
-
const supportedTargets =
|
|
8881
|
+
const supportedTargets = CommandsProcessor.getToolTargets({ global, includeSimulated: false });
|
|
7474
8882
|
if (!supportedTargets.includes(tool)) {
|
|
7475
8883
|
return 0;
|
|
7476
8884
|
}
|
|
@@ -7494,7 +8902,8 @@ async function importSubagents(config, tool) {
|
|
|
7494
8902
|
if (!config.getFeatures().includes("subagents")) {
|
|
7495
8903
|
return 0;
|
|
7496
8904
|
}
|
|
7497
|
-
const
|
|
8905
|
+
const global = config.getGlobal();
|
|
8906
|
+
const supportedTargets = SubagentsProcessor.getToolTargets({ global, includeSimulated: false });
|
|
7498
8907
|
if (!supportedTargets.includes(tool)) {
|
|
7499
8908
|
return 0;
|
|
7500
8909
|
}
|
|
@@ -7514,9 +8923,34 @@ async function importSubagents(config, tool) {
|
|
|
7514
8923
|
}
|
|
7515
8924
|
return writtenCount;
|
|
7516
8925
|
}
|
|
8926
|
+
async function importSkills(config, tool) {
|
|
8927
|
+
if (!config.getFeatures().includes("skills")) {
|
|
8928
|
+
return 0;
|
|
8929
|
+
}
|
|
8930
|
+
const global = config.getGlobal();
|
|
8931
|
+
const supportedTargets = SkillsProcessor.getToolTargets({ global });
|
|
8932
|
+
if (!supportedTargets.includes(tool)) {
|
|
8933
|
+
return 0;
|
|
8934
|
+
}
|
|
8935
|
+
const skillsProcessor = new SkillsProcessor({
|
|
8936
|
+
baseDir: config.getBaseDirs()[0] ?? ".",
|
|
8937
|
+
toolTarget: tool,
|
|
8938
|
+
global
|
|
8939
|
+
});
|
|
8940
|
+
const toolDirs = await skillsProcessor.loadToolDirs();
|
|
8941
|
+
if (toolDirs.length === 0) {
|
|
8942
|
+
return 0;
|
|
8943
|
+
}
|
|
8944
|
+
const rulesyncDirs = await skillsProcessor.convertToolDirsToRulesyncDirs(toolDirs);
|
|
8945
|
+
const writtenCount = await skillsProcessor.writeAiDirs(rulesyncDirs);
|
|
8946
|
+
if (config.getVerbose() && writtenCount > 0) {
|
|
8947
|
+
logger.success(`Created ${writtenCount} skill directories`);
|
|
8948
|
+
}
|
|
8949
|
+
return writtenCount;
|
|
8950
|
+
}
|
|
7517
8951
|
|
|
7518
8952
|
// src/cli/commands/init.ts
|
|
7519
|
-
import { join as
|
|
8953
|
+
import { join as join79 } from "path";
|
|
7520
8954
|
async function initCommand() {
|
|
7521
8955
|
logger.info("Initializing rulesync...");
|
|
7522
8956
|
await ensureDir(RULESYNC_RELATIVE_DIR_PATH);
|
|
@@ -7544,8 +8978,8 @@ async function createConfigFile() {
|
|
|
7544
8978
|
delete: true,
|
|
7545
8979
|
verbose: false,
|
|
7546
8980
|
global: false,
|
|
7547
|
-
|
|
7548
|
-
|
|
8981
|
+
simulateCommands: false,
|
|
8982
|
+
simulateSubagents: false,
|
|
7549
8983
|
modularMcp: false
|
|
7550
8984
|
},
|
|
7551
8985
|
null,
|
|
@@ -7679,14 +9113,14 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
7679
9113
|
await ensureDir(commandPaths.relativeDirPath);
|
|
7680
9114
|
await ensureDir(subagentPaths.relativeDirPath);
|
|
7681
9115
|
await ensureDir(ignorePaths.relativeDirPath);
|
|
7682
|
-
const ruleFilepath =
|
|
9116
|
+
const ruleFilepath = join79(rulePaths.recommended.relativeDirPath, sampleRuleFile.filename);
|
|
7683
9117
|
if (!await fileExists(ruleFilepath)) {
|
|
7684
9118
|
await writeFileContent(ruleFilepath, sampleRuleFile.content);
|
|
7685
9119
|
logger.success(`Created ${ruleFilepath}`);
|
|
7686
9120
|
} else {
|
|
7687
9121
|
logger.info(`Skipped ${ruleFilepath} (already exists)`);
|
|
7688
9122
|
}
|
|
7689
|
-
const mcpFilepath =
|
|
9123
|
+
const mcpFilepath = join79(
|
|
7690
9124
|
mcpPaths.recommended.relativeDirPath,
|
|
7691
9125
|
mcpPaths.recommended.relativeFilePath
|
|
7692
9126
|
);
|
|
@@ -7696,21 +9130,21 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
7696
9130
|
} else {
|
|
7697
9131
|
logger.info(`Skipped ${mcpFilepath} (already exists)`);
|
|
7698
9132
|
}
|
|
7699
|
-
const commandFilepath =
|
|
9133
|
+
const commandFilepath = join79(commandPaths.relativeDirPath, sampleCommandFile.filename);
|
|
7700
9134
|
if (!await fileExists(commandFilepath)) {
|
|
7701
9135
|
await writeFileContent(commandFilepath, sampleCommandFile.content);
|
|
7702
9136
|
logger.success(`Created ${commandFilepath}`);
|
|
7703
9137
|
} else {
|
|
7704
9138
|
logger.info(`Skipped ${commandFilepath} (already exists)`);
|
|
7705
9139
|
}
|
|
7706
|
-
const subagentFilepath =
|
|
9140
|
+
const subagentFilepath = join79(subagentPaths.relativeDirPath, sampleSubagentFile.filename);
|
|
7707
9141
|
if (!await fileExists(subagentFilepath)) {
|
|
7708
9142
|
await writeFileContent(subagentFilepath, sampleSubagentFile.content);
|
|
7709
9143
|
logger.success(`Created ${subagentFilepath}`);
|
|
7710
9144
|
} else {
|
|
7711
9145
|
logger.info(`Skipped ${subagentFilepath} (already exists)`);
|
|
7712
9146
|
}
|
|
7713
|
-
const ignoreFilepath =
|
|
9147
|
+
const ignoreFilepath = join79(ignorePaths.relativeDirPath, ignorePaths.relativeFilePath);
|
|
7714
9148
|
if (!await fileExists(ignoreFilepath)) {
|
|
7715
9149
|
await writeFileContent(ignoreFilepath, sampleIgnoreFile.content);
|
|
7716
9150
|
logger.success(`Created ${ignoreFilepath}`);
|
|
@@ -7723,12 +9157,12 @@ Attention, again, you are just the planner, so though you can read any files and
|
|
|
7723
9157
|
import { FastMCP } from "fastmcp";
|
|
7724
9158
|
|
|
7725
9159
|
// src/mcp/commands.ts
|
|
7726
|
-
import { basename as
|
|
7727
|
-
import { z as
|
|
9160
|
+
import { basename as basename20, join as join80 } from "path";
|
|
9161
|
+
import { z as z30 } from "zod/mini";
|
|
7728
9162
|
var maxCommandSizeBytes = 1024 * 1024;
|
|
7729
9163
|
var maxCommandsCount = 1e3;
|
|
7730
9164
|
async function listCommands() {
|
|
7731
|
-
const commandsDir =
|
|
9165
|
+
const commandsDir = join80(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
7732
9166
|
try {
|
|
7733
9167
|
const files = await listDirectoryFiles(commandsDir);
|
|
7734
9168
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -7740,7 +9174,7 @@ async function listCommands() {
|
|
|
7740
9174
|
});
|
|
7741
9175
|
const frontmatter = command.getFrontmatter();
|
|
7742
9176
|
return {
|
|
7743
|
-
relativePathFromCwd:
|
|
9177
|
+
relativePathFromCwd: join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, file),
|
|
7744
9178
|
frontmatter
|
|
7745
9179
|
};
|
|
7746
9180
|
} catch (error) {
|
|
@@ -7760,13 +9194,13 @@ async function getCommand({ relativePathFromCwd }) {
|
|
|
7760
9194
|
relativePath: relativePathFromCwd,
|
|
7761
9195
|
intendedRootDir: process.cwd()
|
|
7762
9196
|
});
|
|
7763
|
-
const filename =
|
|
9197
|
+
const filename = basename20(relativePathFromCwd);
|
|
7764
9198
|
try {
|
|
7765
9199
|
const command = await RulesyncCommand.fromFile({
|
|
7766
9200
|
relativeFilePath: filename
|
|
7767
9201
|
});
|
|
7768
9202
|
return {
|
|
7769
|
-
relativePathFromCwd:
|
|
9203
|
+
relativePathFromCwd: join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
7770
9204
|
frontmatter: command.getFrontmatter(),
|
|
7771
9205
|
body: command.getBody()
|
|
7772
9206
|
};
|
|
@@ -7785,7 +9219,7 @@ async function putCommand({
|
|
|
7785
9219
|
relativePath: relativePathFromCwd,
|
|
7786
9220
|
intendedRootDir: process.cwd()
|
|
7787
9221
|
});
|
|
7788
|
-
const filename =
|
|
9222
|
+
const filename = basename20(relativePathFromCwd);
|
|
7789
9223
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
7790
9224
|
if (estimatedSize > maxCommandSizeBytes) {
|
|
7791
9225
|
throw new Error(
|
|
@@ -7795,7 +9229,7 @@ async function putCommand({
|
|
|
7795
9229
|
try {
|
|
7796
9230
|
const existingCommands = await listCommands();
|
|
7797
9231
|
const isUpdate = existingCommands.some(
|
|
7798
|
-
(command2) => command2.relativePathFromCwd ===
|
|
9232
|
+
(command2) => command2.relativePathFromCwd === join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
7799
9233
|
);
|
|
7800
9234
|
if (!isUpdate && existingCommands.length >= maxCommandsCount) {
|
|
7801
9235
|
throw new Error(`Maximum number of commands (${maxCommandsCount}) reached`);
|
|
@@ -7810,11 +9244,11 @@ async function putCommand({
|
|
|
7810
9244
|
fileContent,
|
|
7811
9245
|
validate: true
|
|
7812
9246
|
});
|
|
7813
|
-
const commandsDir =
|
|
9247
|
+
const commandsDir = join80(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH);
|
|
7814
9248
|
await ensureDir(commandsDir);
|
|
7815
9249
|
await writeFileContent(command.getFilePath(), command.getFileContent());
|
|
7816
9250
|
return {
|
|
7817
|
-
relativePathFromCwd:
|
|
9251
|
+
relativePathFromCwd: join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename),
|
|
7818
9252
|
frontmatter: command.getFrontmatter(),
|
|
7819
9253
|
body: command.getBody()
|
|
7820
9254
|
};
|
|
@@ -7829,12 +9263,12 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
7829
9263
|
relativePath: relativePathFromCwd,
|
|
7830
9264
|
intendedRootDir: process.cwd()
|
|
7831
9265
|
});
|
|
7832
|
-
const filename =
|
|
7833
|
-
const fullPath =
|
|
9266
|
+
const filename = basename20(relativePathFromCwd);
|
|
9267
|
+
const fullPath = join80(process.cwd(), RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename);
|
|
7834
9268
|
try {
|
|
7835
9269
|
await removeFile(fullPath);
|
|
7836
9270
|
return {
|
|
7837
|
-
relativePathFromCwd:
|
|
9271
|
+
relativePathFromCwd: join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, filename)
|
|
7838
9272
|
};
|
|
7839
9273
|
} catch (error) {
|
|
7840
9274
|
throw new Error(`Failed to delete command file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -7843,23 +9277,23 @@ async function deleteCommand({ relativePathFromCwd }) {
|
|
|
7843
9277
|
}
|
|
7844
9278
|
}
|
|
7845
9279
|
var commandToolSchemas = {
|
|
7846
|
-
listCommands:
|
|
7847
|
-
getCommand:
|
|
7848
|
-
relativePathFromCwd:
|
|
9280
|
+
listCommands: z30.object({}),
|
|
9281
|
+
getCommand: z30.object({
|
|
9282
|
+
relativePathFromCwd: z30.string()
|
|
7849
9283
|
}),
|
|
7850
|
-
putCommand:
|
|
7851
|
-
relativePathFromCwd:
|
|
9284
|
+
putCommand: z30.object({
|
|
9285
|
+
relativePathFromCwd: z30.string(),
|
|
7852
9286
|
frontmatter: RulesyncCommandFrontmatterSchema,
|
|
7853
|
-
body:
|
|
9287
|
+
body: z30.string()
|
|
7854
9288
|
}),
|
|
7855
|
-
deleteCommand:
|
|
7856
|
-
relativePathFromCwd:
|
|
9289
|
+
deleteCommand: z30.object({
|
|
9290
|
+
relativePathFromCwd: z30.string()
|
|
7857
9291
|
})
|
|
7858
9292
|
};
|
|
7859
9293
|
var commandTools = {
|
|
7860
9294
|
listCommands: {
|
|
7861
9295
|
name: "listCommands",
|
|
7862
|
-
description: `List all commands from ${
|
|
9296
|
+
description: `List all commands from ${join80(RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
7863
9297
|
parameters: commandToolSchemas.listCommands,
|
|
7864
9298
|
execute: async () => {
|
|
7865
9299
|
const commands = await listCommands();
|
|
@@ -7901,11 +9335,11 @@ var commandTools = {
|
|
|
7901
9335
|
};
|
|
7902
9336
|
|
|
7903
9337
|
// src/mcp/ignore.ts
|
|
7904
|
-
import { join as
|
|
7905
|
-
import { z as
|
|
9338
|
+
import { join as join81 } from "path";
|
|
9339
|
+
import { z as z31 } from "zod/mini";
|
|
7906
9340
|
var maxIgnoreFileSizeBytes = 100 * 1024;
|
|
7907
9341
|
async function getIgnoreFile() {
|
|
7908
|
-
const ignoreFilePath =
|
|
9342
|
+
const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
7909
9343
|
try {
|
|
7910
9344
|
const content = await readFileContent(ignoreFilePath);
|
|
7911
9345
|
return {
|
|
@@ -7919,7 +9353,7 @@ async function getIgnoreFile() {
|
|
|
7919
9353
|
}
|
|
7920
9354
|
}
|
|
7921
9355
|
async function putIgnoreFile({ content }) {
|
|
7922
|
-
const ignoreFilePath =
|
|
9356
|
+
const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
7923
9357
|
const contentSizeBytes = Buffer.byteLength(content, "utf8");
|
|
7924
9358
|
if (contentSizeBytes > maxIgnoreFileSizeBytes) {
|
|
7925
9359
|
throw new Error(
|
|
@@ -7940,7 +9374,7 @@ async function putIgnoreFile({ content }) {
|
|
|
7940
9374
|
}
|
|
7941
9375
|
}
|
|
7942
9376
|
async function deleteIgnoreFile() {
|
|
7943
|
-
const ignoreFilePath =
|
|
9377
|
+
const ignoreFilePath = join81(process.cwd(), RULESYNC_IGNORE_RELATIVE_FILE_PATH);
|
|
7944
9378
|
try {
|
|
7945
9379
|
await removeFile(ignoreFilePath);
|
|
7946
9380
|
return {
|
|
@@ -7953,11 +9387,11 @@ async function deleteIgnoreFile() {
|
|
|
7953
9387
|
}
|
|
7954
9388
|
}
|
|
7955
9389
|
var ignoreToolSchemas = {
|
|
7956
|
-
getIgnoreFile:
|
|
7957
|
-
putIgnoreFile:
|
|
7958
|
-
content:
|
|
9390
|
+
getIgnoreFile: z31.object({}),
|
|
9391
|
+
putIgnoreFile: z31.object({
|
|
9392
|
+
content: z31.string()
|
|
7959
9393
|
}),
|
|
7960
|
-
deleteIgnoreFile:
|
|
9394
|
+
deleteIgnoreFile: z31.object({})
|
|
7961
9395
|
};
|
|
7962
9396
|
var ignoreTools = {
|
|
7963
9397
|
getIgnoreFile: {
|
|
@@ -7990,8 +9424,8 @@ var ignoreTools = {
|
|
|
7990
9424
|
};
|
|
7991
9425
|
|
|
7992
9426
|
// src/mcp/mcp.ts
|
|
7993
|
-
import { join as
|
|
7994
|
-
import { z as
|
|
9427
|
+
import { join as join82 } from "path";
|
|
9428
|
+
import { z as z32 } from "zod/mini";
|
|
7995
9429
|
var maxMcpSizeBytes = 1024 * 1024;
|
|
7996
9430
|
async function getMcpFile() {
|
|
7997
9431
|
const config = await ConfigResolver.resolve({});
|
|
@@ -8000,7 +9434,7 @@ async function getMcpFile() {
|
|
|
8000
9434
|
validate: true,
|
|
8001
9435
|
modularMcp: config.getModularMcp()
|
|
8002
9436
|
});
|
|
8003
|
-
const relativePathFromCwd =
|
|
9437
|
+
const relativePathFromCwd = join82(
|
|
8004
9438
|
rulesyncMcp.getRelativeDirPath(),
|
|
8005
9439
|
rulesyncMcp.getRelativeFilePath()
|
|
8006
9440
|
);
|
|
@@ -8033,7 +9467,7 @@ async function putMcpFile({ content }) {
|
|
|
8033
9467
|
const paths = RulesyncMcp.getSettablePaths();
|
|
8034
9468
|
const relativeDirPath = paths.recommended.relativeDirPath;
|
|
8035
9469
|
const relativeFilePath = paths.recommended.relativeFilePath;
|
|
8036
|
-
const fullPath =
|
|
9470
|
+
const fullPath = join82(baseDir, relativeDirPath, relativeFilePath);
|
|
8037
9471
|
const rulesyncMcp = new RulesyncMcp({
|
|
8038
9472
|
baseDir,
|
|
8039
9473
|
relativeDirPath,
|
|
@@ -8042,9 +9476,9 @@ async function putMcpFile({ content }) {
|
|
|
8042
9476
|
validate: true,
|
|
8043
9477
|
modularMcp: config.getModularMcp()
|
|
8044
9478
|
});
|
|
8045
|
-
await ensureDir(
|
|
9479
|
+
await ensureDir(join82(baseDir, relativeDirPath));
|
|
8046
9480
|
await writeFileContent(fullPath, content);
|
|
8047
|
-
const relativePathFromCwd =
|
|
9481
|
+
const relativePathFromCwd = join82(relativeDirPath, relativeFilePath);
|
|
8048
9482
|
return {
|
|
8049
9483
|
relativePathFromCwd,
|
|
8050
9484
|
content: rulesyncMcp.getFileContent()
|
|
@@ -8059,15 +9493,15 @@ async function deleteMcpFile() {
|
|
|
8059
9493
|
try {
|
|
8060
9494
|
const baseDir = process.cwd();
|
|
8061
9495
|
const paths = RulesyncMcp.getSettablePaths();
|
|
8062
|
-
const recommendedPath =
|
|
9496
|
+
const recommendedPath = join82(
|
|
8063
9497
|
baseDir,
|
|
8064
9498
|
paths.recommended.relativeDirPath,
|
|
8065
9499
|
paths.recommended.relativeFilePath
|
|
8066
9500
|
);
|
|
8067
|
-
const legacyPath =
|
|
9501
|
+
const legacyPath = join82(baseDir, paths.legacy.relativeDirPath, paths.legacy.relativeFilePath);
|
|
8068
9502
|
await removeFile(recommendedPath);
|
|
8069
9503
|
await removeFile(legacyPath);
|
|
8070
|
-
const relativePathFromCwd =
|
|
9504
|
+
const relativePathFromCwd = join82(
|
|
8071
9505
|
paths.recommended.relativeDirPath,
|
|
8072
9506
|
paths.recommended.relativeFilePath
|
|
8073
9507
|
);
|
|
@@ -8081,11 +9515,11 @@ async function deleteMcpFile() {
|
|
|
8081
9515
|
}
|
|
8082
9516
|
}
|
|
8083
9517
|
var mcpToolSchemas = {
|
|
8084
|
-
getMcpFile:
|
|
8085
|
-
putMcpFile:
|
|
8086
|
-
content:
|
|
9518
|
+
getMcpFile: z32.object({}),
|
|
9519
|
+
putMcpFile: z32.object({
|
|
9520
|
+
content: z32.string()
|
|
8087
9521
|
}),
|
|
8088
|
-
deleteMcpFile:
|
|
9522
|
+
deleteMcpFile: z32.object({})
|
|
8089
9523
|
};
|
|
8090
9524
|
var mcpTools = {
|
|
8091
9525
|
getMcpFile: {
|
|
@@ -8118,12 +9552,12 @@ var mcpTools = {
|
|
|
8118
9552
|
};
|
|
8119
9553
|
|
|
8120
9554
|
// src/mcp/rules.ts
|
|
8121
|
-
import { basename as
|
|
8122
|
-
import { z as
|
|
9555
|
+
import { basename as basename21, join as join83 } from "path";
|
|
9556
|
+
import { z as z33 } from "zod/mini";
|
|
8123
9557
|
var maxRuleSizeBytes = 1024 * 1024;
|
|
8124
9558
|
var maxRulesCount = 1e3;
|
|
8125
9559
|
async function listRules() {
|
|
8126
|
-
const rulesDir =
|
|
9560
|
+
const rulesDir = join83(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
8127
9561
|
try {
|
|
8128
9562
|
const files = await listDirectoryFiles(rulesDir);
|
|
8129
9563
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -8136,7 +9570,7 @@ async function listRules() {
|
|
|
8136
9570
|
});
|
|
8137
9571
|
const frontmatter = rule.getFrontmatter();
|
|
8138
9572
|
return {
|
|
8139
|
-
relativePathFromCwd:
|
|
9573
|
+
relativePathFromCwd: join83(RULESYNC_RULES_RELATIVE_DIR_PATH, file),
|
|
8140
9574
|
frontmatter
|
|
8141
9575
|
};
|
|
8142
9576
|
} catch (error) {
|
|
@@ -8156,14 +9590,14 @@ async function getRule({ relativePathFromCwd }) {
|
|
|
8156
9590
|
relativePath: relativePathFromCwd,
|
|
8157
9591
|
intendedRootDir: process.cwd()
|
|
8158
9592
|
});
|
|
8159
|
-
const filename =
|
|
9593
|
+
const filename = basename21(relativePathFromCwd);
|
|
8160
9594
|
try {
|
|
8161
9595
|
const rule = await RulesyncRule.fromFile({
|
|
8162
9596
|
relativeFilePath: filename,
|
|
8163
9597
|
validate: true
|
|
8164
9598
|
});
|
|
8165
9599
|
return {
|
|
8166
|
-
relativePathFromCwd:
|
|
9600
|
+
relativePathFromCwd: join83(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
8167
9601
|
frontmatter: rule.getFrontmatter(),
|
|
8168
9602
|
body: rule.getBody()
|
|
8169
9603
|
};
|
|
@@ -8182,7 +9616,7 @@ async function putRule({
|
|
|
8182
9616
|
relativePath: relativePathFromCwd,
|
|
8183
9617
|
intendedRootDir: process.cwd()
|
|
8184
9618
|
});
|
|
8185
|
-
const filename =
|
|
9619
|
+
const filename = basename21(relativePathFromCwd);
|
|
8186
9620
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
8187
9621
|
if (estimatedSize > maxRuleSizeBytes) {
|
|
8188
9622
|
throw new Error(
|
|
@@ -8192,7 +9626,7 @@ async function putRule({
|
|
|
8192
9626
|
try {
|
|
8193
9627
|
const existingRules = await listRules();
|
|
8194
9628
|
const isUpdate = existingRules.some(
|
|
8195
|
-
(rule2) => rule2.relativePathFromCwd ===
|
|
9629
|
+
(rule2) => rule2.relativePathFromCwd === join83(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
8196
9630
|
);
|
|
8197
9631
|
if (!isUpdate && existingRules.length >= maxRulesCount) {
|
|
8198
9632
|
throw new Error(`Maximum number of rules (${maxRulesCount}) reached`);
|
|
@@ -8205,11 +9639,11 @@ async function putRule({
|
|
|
8205
9639
|
body,
|
|
8206
9640
|
validate: true
|
|
8207
9641
|
});
|
|
8208
|
-
const rulesDir =
|
|
9642
|
+
const rulesDir = join83(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH);
|
|
8209
9643
|
await ensureDir(rulesDir);
|
|
8210
9644
|
await writeFileContent(rule.getFilePath(), rule.getFileContent());
|
|
8211
9645
|
return {
|
|
8212
|
-
relativePathFromCwd:
|
|
9646
|
+
relativePathFromCwd: join83(RULESYNC_RULES_RELATIVE_DIR_PATH, filename),
|
|
8213
9647
|
frontmatter: rule.getFrontmatter(),
|
|
8214
9648
|
body: rule.getBody()
|
|
8215
9649
|
};
|
|
@@ -8224,12 +9658,12 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
8224
9658
|
relativePath: relativePathFromCwd,
|
|
8225
9659
|
intendedRootDir: process.cwd()
|
|
8226
9660
|
});
|
|
8227
|
-
const filename =
|
|
8228
|
-
const fullPath =
|
|
9661
|
+
const filename = basename21(relativePathFromCwd);
|
|
9662
|
+
const fullPath = join83(process.cwd(), RULESYNC_RULES_RELATIVE_DIR_PATH, filename);
|
|
8229
9663
|
try {
|
|
8230
9664
|
await removeFile(fullPath);
|
|
8231
9665
|
return {
|
|
8232
|
-
relativePathFromCwd:
|
|
9666
|
+
relativePathFromCwd: join83(RULESYNC_RULES_RELATIVE_DIR_PATH, filename)
|
|
8233
9667
|
};
|
|
8234
9668
|
} catch (error) {
|
|
8235
9669
|
throw new Error(`Failed to delete rule file ${relativePathFromCwd}: ${formatError(error)}`, {
|
|
@@ -8238,23 +9672,23 @@ async function deleteRule({ relativePathFromCwd }) {
|
|
|
8238
9672
|
}
|
|
8239
9673
|
}
|
|
8240
9674
|
var ruleToolSchemas = {
|
|
8241
|
-
listRules:
|
|
8242
|
-
getRule:
|
|
8243
|
-
relativePathFromCwd:
|
|
9675
|
+
listRules: z33.object({}),
|
|
9676
|
+
getRule: z33.object({
|
|
9677
|
+
relativePathFromCwd: z33.string()
|
|
8244
9678
|
}),
|
|
8245
|
-
putRule:
|
|
8246
|
-
relativePathFromCwd:
|
|
9679
|
+
putRule: z33.object({
|
|
9680
|
+
relativePathFromCwd: z33.string(),
|
|
8247
9681
|
frontmatter: RulesyncRuleFrontmatterSchema,
|
|
8248
|
-
body:
|
|
9682
|
+
body: z33.string()
|
|
8249
9683
|
}),
|
|
8250
|
-
deleteRule:
|
|
8251
|
-
relativePathFromCwd:
|
|
9684
|
+
deleteRule: z33.object({
|
|
9685
|
+
relativePathFromCwd: z33.string()
|
|
8252
9686
|
})
|
|
8253
9687
|
};
|
|
8254
9688
|
var ruleTools = {
|
|
8255
9689
|
listRules: {
|
|
8256
9690
|
name: "listRules",
|
|
8257
|
-
description: `List all rules from ${
|
|
9691
|
+
description: `List all rules from ${join83(RULESYNC_RULES_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
8258
9692
|
parameters: ruleToolSchemas.listRules,
|
|
8259
9693
|
execute: async () => {
|
|
8260
9694
|
const rules = await listRules();
|
|
@@ -8296,12 +9730,12 @@ var ruleTools = {
|
|
|
8296
9730
|
};
|
|
8297
9731
|
|
|
8298
9732
|
// src/mcp/subagents.ts
|
|
8299
|
-
import { basename as
|
|
8300
|
-
import { z as
|
|
9733
|
+
import { basename as basename22, join as join84 } from "path";
|
|
9734
|
+
import { z as z34 } from "zod/mini";
|
|
8301
9735
|
var maxSubagentSizeBytes = 1024 * 1024;
|
|
8302
9736
|
var maxSubagentsCount = 1e3;
|
|
8303
9737
|
async function listSubagents() {
|
|
8304
|
-
const subagentsDir =
|
|
9738
|
+
const subagentsDir = join84(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
8305
9739
|
try {
|
|
8306
9740
|
const files = await listDirectoryFiles(subagentsDir);
|
|
8307
9741
|
const mdFiles = files.filter((file) => file.endsWith(".md"));
|
|
@@ -8314,7 +9748,7 @@ async function listSubagents() {
|
|
|
8314
9748
|
});
|
|
8315
9749
|
const frontmatter = subagent.getFrontmatter();
|
|
8316
9750
|
return {
|
|
8317
|
-
relativePathFromCwd:
|
|
9751
|
+
relativePathFromCwd: join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, file),
|
|
8318
9752
|
frontmatter
|
|
8319
9753
|
};
|
|
8320
9754
|
} catch (error) {
|
|
@@ -8336,14 +9770,14 @@ async function getSubagent({ relativePathFromCwd }) {
|
|
|
8336
9770
|
relativePath: relativePathFromCwd,
|
|
8337
9771
|
intendedRootDir: process.cwd()
|
|
8338
9772
|
});
|
|
8339
|
-
const filename =
|
|
9773
|
+
const filename = basename22(relativePathFromCwd);
|
|
8340
9774
|
try {
|
|
8341
9775
|
const subagent = await RulesyncSubagent.fromFile({
|
|
8342
9776
|
relativeFilePath: filename,
|
|
8343
9777
|
validate: true
|
|
8344
9778
|
});
|
|
8345
9779
|
return {
|
|
8346
|
-
relativePathFromCwd:
|
|
9780
|
+
relativePathFromCwd: join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
8347
9781
|
frontmatter: subagent.getFrontmatter(),
|
|
8348
9782
|
body: subagent.getBody()
|
|
8349
9783
|
};
|
|
@@ -8362,7 +9796,7 @@ async function putSubagent({
|
|
|
8362
9796
|
relativePath: relativePathFromCwd,
|
|
8363
9797
|
intendedRootDir: process.cwd()
|
|
8364
9798
|
});
|
|
8365
|
-
const filename =
|
|
9799
|
+
const filename = basename22(relativePathFromCwd);
|
|
8366
9800
|
const estimatedSize = JSON.stringify(frontmatter).length + body.length;
|
|
8367
9801
|
if (estimatedSize > maxSubagentSizeBytes) {
|
|
8368
9802
|
throw new Error(
|
|
@@ -8372,7 +9806,7 @@ async function putSubagent({
|
|
|
8372
9806
|
try {
|
|
8373
9807
|
const existingSubagents = await listSubagents();
|
|
8374
9808
|
const isUpdate = existingSubagents.some(
|
|
8375
|
-
(subagent2) => subagent2.relativePathFromCwd ===
|
|
9809
|
+
(subagent2) => subagent2.relativePathFromCwd === join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
8376
9810
|
);
|
|
8377
9811
|
if (!isUpdate && existingSubagents.length >= maxSubagentsCount) {
|
|
8378
9812
|
throw new Error(`Maximum number of subagents (${maxSubagentsCount}) reached`);
|
|
@@ -8385,11 +9819,11 @@ async function putSubagent({
|
|
|
8385
9819
|
body,
|
|
8386
9820
|
validate: true
|
|
8387
9821
|
});
|
|
8388
|
-
const subagentsDir =
|
|
9822
|
+
const subagentsDir = join84(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH);
|
|
8389
9823
|
await ensureDir(subagentsDir);
|
|
8390
9824
|
await writeFileContent(subagent.getFilePath(), subagent.getFileContent());
|
|
8391
9825
|
return {
|
|
8392
|
-
relativePathFromCwd:
|
|
9826
|
+
relativePathFromCwd: join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename),
|
|
8393
9827
|
frontmatter: subagent.getFrontmatter(),
|
|
8394
9828
|
body: subagent.getBody()
|
|
8395
9829
|
};
|
|
@@ -8404,12 +9838,12 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
8404
9838
|
relativePath: relativePathFromCwd,
|
|
8405
9839
|
intendedRootDir: process.cwd()
|
|
8406
9840
|
});
|
|
8407
|
-
const filename =
|
|
8408
|
-
const fullPath =
|
|
9841
|
+
const filename = basename22(relativePathFromCwd);
|
|
9842
|
+
const fullPath = join84(process.cwd(), RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename);
|
|
8409
9843
|
try {
|
|
8410
9844
|
await removeFile(fullPath);
|
|
8411
9845
|
return {
|
|
8412
|
-
relativePathFromCwd:
|
|
9846
|
+
relativePathFromCwd: join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, filename)
|
|
8413
9847
|
};
|
|
8414
9848
|
} catch (error) {
|
|
8415
9849
|
throw new Error(
|
|
@@ -8421,23 +9855,23 @@ async function deleteSubagent({ relativePathFromCwd }) {
|
|
|
8421
9855
|
}
|
|
8422
9856
|
}
|
|
8423
9857
|
var subagentToolSchemas = {
|
|
8424
|
-
listSubagents:
|
|
8425
|
-
getSubagent:
|
|
8426
|
-
relativePathFromCwd:
|
|
9858
|
+
listSubagents: z34.object({}),
|
|
9859
|
+
getSubagent: z34.object({
|
|
9860
|
+
relativePathFromCwd: z34.string()
|
|
8427
9861
|
}),
|
|
8428
|
-
putSubagent:
|
|
8429
|
-
relativePathFromCwd:
|
|
9862
|
+
putSubagent: z34.object({
|
|
9863
|
+
relativePathFromCwd: z34.string(),
|
|
8430
9864
|
frontmatter: RulesyncSubagentFrontmatterSchema,
|
|
8431
|
-
body:
|
|
9865
|
+
body: z34.string()
|
|
8432
9866
|
}),
|
|
8433
|
-
deleteSubagent:
|
|
8434
|
-
relativePathFromCwd:
|
|
9867
|
+
deleteSubagent: z34.object({
|
|
9868
|
+
relativePathFromCwd: z34.string()
|
|
8435
9869
|
})
|
|
8436
9870
|
};
|
|
8437
9871
|
var subagentTools = {
|
|
8438
9872
|
listSubagents: {
|
|
8439
9873
|
name: "listSubagents",
|
|
8440
|
-
description: `List all subagents from ${
|
|
9874
|
+
description: `List all subagents from ${join84(RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH, "*.md")} with their frontmatter.`,
|
|
8441
9875
|
parameters: subagentToolSchemas.listSubagents,
|
|
8442
9876
|
execute: async () => {
|
|
8443
9877
|
const subagents = await listSubagents();
|
|
@@ -8511,7 +9945,7 @@ async function mcpCommand({ version }) {
|
|
|
8511
9945
|
}
|
|
8512
9946
|
|
|
8513
9947
|
// src/cli/index.ts
|
|
8514
|
-
var getVersion = () => "3.
|
|
9948
|
+
var getVersion = () => "3.25.0";
|
|
8515
9949
|
var main = async () => {
|
|
8516
9950
|
const program = new Command();
|
|
8517
9951
|
const version = getVersion();
|
|
@@ -8577,20 +10011,23 @@ var main = async () => {
|
|
|
8577
10011
|
"-b, --base-dir <paths>",
|
|
8578
10012
|
"Base directories to generate files (comma-separated for multiple paths)"
|
|
8579
10013
|
).option("-V, --verbose", "Verbose output").option("-c, --config <path>", "Path to configuration file").option("-g, --global", "Generate for global(user scope) configuration files").option(
|
|
8580
|
-
"--
|
|
10014
|
+
"--simulate-commands",
|
|
8581
10015
|
"Generate simulated commands. This feature is only available for copilot, cursor and codexcli."
|
|
8582
10016
|
).option(
|
|
8583
|
-
"--
|
|
10017
|
+
"--simulate-subagents",
|
|
8584
10018
|
"Generate simulated subagents. This feature is only available for copilot, cursor and codexcli."
|
|
10019
|
+
).option(
|
|
10020
|
+
"--simulate-skills",
|
|
10021
|
+
"Generate simulated skills. This feature is only available for copilot, cursor and codexcli."
|
|
8585
10022
|
).option(
|
|
8586
10023
|
"--experimental-global",
|
|
8587
10024
|
"Generate for global(user scope) configuration files (deprecated: use --global instead)"
|
|
8588
10025
|
).option(
|
|
8589
10026
|
"--experimental-simulate-commands",
|
|
8590
|
-
"Generate simulated commands (deprecated: use --
|
|
10027
|
+
"Generate simulated commands (deprecated: use --simulate-commands instead)"
|
|
8591
10028
|
).option(
|
|
8592
10029
|
"--experimental-simulate-subagents",
|
|
8593
|
-
"Generate simulated subagents (deprecated: use --
|
|
10030
|
+
"Generate simulated subagents (deprecated: use --simulate-subagents instead)"
|
|
8594
10031
|
).option(
|
|
8595
10032
|
"--modular-mcp",
|
|
8596
10033
|
"Generate modular-mcp configuration for context compression (experimental)"
|
|
@@ -8604,8 +10041,9 @@ var main = async () => {
|
|
|
8604
10041
|
baseDirs: options.baseDirs,
|
|
8605
10042
|
configPath: options.config,
|
|
8606
10043
|
global: options.global,
|
|
8607
|
-
|
|
8608
|
-
|
|
10044
|
+
simulateCommands: options.simulateCommands,
|
|
10045
|
+
simulateSubagents: options.simulateSubagents,
|
|
10046
|
+
simulateSkills: options.simulateSkills,
|
|
8609
10047
|
modularMcp: options.modularMcp,
|
|
8610
10048
|
experimentalGlobal: options.experimentalGlobal,
|
|
8611
10049
|
experimentalSimulateCommands: options.experimentalSimulateCommands,
|