rulesync 14.2.0 → 15.0.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 +44 -39
- package/dist/cli/index.cjs +84 -85
- package/dist/cli/index.js +84 -85
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-CMCy95RI.js → import-BuxzyDyH.js} +1889 -303
- package/dist/import-BuxzyDyH.js.map +1 -0
- package/dist/{import-Ds8vYv6h.cjs → import-DRN7goJ_.cjs} +1932 -316
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +25 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/import-CMCy95RI.js.map +0 -1
|
@@ -20,8 +20,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
20
20
|
enumerable: true
|
|
21
21
|
}) : target, mod));
|
|
22
22
|
//#endregion
|
|
23
|
-
let zod_mini = require("zod/mini");
|
|
24
23
|
let zod = require("zod");
|
|
24
|
+
let zod_mini = require("zod/mini");
|
|
25
25
|
let node_fs_promises = require("node:fs/promises");
|
|
26
26
|
let node_path = require("node:path");
|
|
27
27
|
node_path = __toESM(node_path, 1);
|
|
@@ -39,10 +39,39 @@ let node_util = require("node:util");
|
|
|
39
39
|
let smol_toml = require("smol-toml");
|
|
40
40
|
smol_toml = __toESM(smol_toml, 1);
|
|
41
41
|
let _toon_format_toon = require("@toon-format/toon");
|
|
42
|
+
//#region src/utils/error.ts
|
|
43
|
+
/**
|
|
44
|
+
* Convert various error types to a readable error message
|
|
45
|
+
* @param error Error instance (ZodError, Error, or unknown)
|
|
46
|
+
* @returns Human-readable error message
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // ZodError
|
|
50
|
+
* const result = schema.safeParse(data);
|
|
51
|
+
* if (!result.success) {
|
|
52
|
+
* throw new Error(`Validation failed: ${formatError(result.error)}`);
|
|
53
|
+
* }
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // Standard Error
|
|
57
|
+
* try {
|
|
58
|
+
* // some operation
|
|
59
|
+
* } catch (error) {
|
|
60
|
+
* console.error(formatError(error));
|
|
61
|
+
* }
|
|
62
|
+
*/
|
|
63
|
+
function isZodErrorLike(error) {
|
|
64
|
+
return error !== null && typeof error === "object" && "issues" in error && Array.isArray(error.issues) && error.issues.every((issue) => issue !== null && typeof issue === "object" && "path" in issue && Array.isArray(issue.path) && "message" in issue && typeof issue.message === "string");
|
|
65
|
+
}
|
|
66
|
+
function formatError(error) {
|
|
67
|
+
if (error instanceof zod.ZodError || isZodErrorLike(error)) return `Zod raw error: ${JSON.stringify(error.issues)}`;
|
|
68
|
+
if (error instanceof Error) return `${error.name}: ${error.message}`;
|
|
69
|
+
return String(error);
|
|
70
|
+
}
|
|
71
|
+
//#endregion
|
|
42
72
|
//#region src/types/features.ts
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
"ignore",
|
|
73
|
+
const ACTIVE_FEATURES_BEFORE_IGNORE = ["rules"];
|
|
74
|
+
const ACTIVE_FEATURES_AFTER_IGNORE = [
|
|
46
75
|
"mcp",
|
|
47
76
|
"subagents",
|
|
48
77
|
"commands",
|
|
@@ -51,9 +80,20 @@ const ALL_FEATURES = [
|
|
|
51
80
|
"permissions",
|
|
52
81
|
"checks"
|
|
53
82
|
];
|
|
83
|
+
const ALL_FEATURES = [
|
|
84
|
+
...ACTIVE_FEATURES_BEFORE_IGNORE,
|
|
85
|
+
"ignore",
|
|
86
|
+
...ACTIVE_FEATURES_AFTER_IGNORE
|
|
87
|
+
];
|
|
54
88
|
const ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
|
|
55
|
-
const
|
|
89
|
+
const ACTIVE_FEATURES = [...ACTIVE_FEATURES_BEFORE_IGNORE, ...ACTIVE_FEATURES_AFTER_IGNORE];
|
|
90
|
+
const DeprecatedIgnoreFeatureSchema = zod_mini.z.literal("ignore").check((0, zod_mini.meta)({
|
|
91
|
+
deprecated: true,
|
|
92
|
+
description: "Deprecated: use the permissions feature. Ignore remains supported for compatibility throughout Rulesync 14.x."
|
|
93
|
+
}));
|
|
94
|
+
const FeatureSchema = zod_mini.z.union([zod_mini.z.enum(ACTIVE_FEATURES), DeprecatedIgnoreFeatureSchema]);
|
|
56
95
|
zod_mini.z.array(FeatureSchema);
|
|
96
|
+
const FeatureWithWildcardSchema = zod_mini.z.union([zod_mini.z.enum([...ACTIVE_FEATURES, "*"]), DeprecatedIgnoreFeatureSchema]);
|
|
57
97
|
const GitignoreDestinationSchema = zod_mini.z.enum(["gitignore", "gitattributes"]);
|
|
58
98
|
const FlattenedCommandNamingSchema = zod_mini.z.enum(["basename", "path"]);
|
|
59
99
|
const FeatureOptionsSchema = zod_mini.z.record(zod_mini.z.string(), zod_mini.z.unknown());
|
|
@@ -63,8 +103,8 @@ const FeatureValueSchema = zod_mini.z.union([
|
|
|
63
103
|
GitignoreDestinationSchema
|
|
64
104
|
]);
|
|
65
105
|
const PerFeatureConfigSchema = zod_mini.z.record(zod_mini.z.string(), FeatureValueSchema);
|
|
66
|
-
const PerTargetFeaturesValueSchema = zod_mini.z.union([zod_mini.z.array(
|
|
67
|
-
const RulesyncFeaturesSchema = zod_mini.z.array(
|
|
106
|
+
const PerTargetFeaturesValueSchema = zod_mini.z.union([zod_mini.z.array(FeatureWithWildcardSchema), PerFeatureConfigSchema]);
|
|
107
|
+
const RulesyncFeaturesSchema = zod_mini.z.array(FeatureWithWildcardSchema);
|
|
68
108
|
/**
|
|
69
109
|
* Returns true if a per-feature value enables the feature.
|
|
70
110
|
*
|
|
@@ -86,66 +126,36 @@ const isFeatureValueEnabled = (value) => {
|
|
|
86
126
|
return false;
|
|
87
127
|
};
|
|
88
128
|
//#endregion
|
|
89
|
-
//#region src/utils/error.ts
|
|
90
|
-
/**
|
|
91
|
-
* Convert various error types to a readable error message
|
|
92
|
-
* @param error Error instance (ZodError, Error, or unknown)
|
|
93
|
-
* @returns Human-readable error message
|
|
94
|
-
*
|
|
95
|
-
* @example
|
|
96
|
-
* // ZodError
|
|
97
|
-
* const result = schema.safeParse(data);
|
|
98
|
-
* if (!result.success) {
|
|
99
|
-
* throw new Error(`Validation failed: ${formatError(result.error)}`);
|
|
100
|
-
* }
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* // Standard Error
|
|
104
|
-
* try {
|
|
105
|
-
* // some operation
|
|
106
|
-
* } catch (error) {
|
|
107
|
-
* console.error(formatError(error));
|
|
108
|
-
* }
|
|
109
|
-
*/
|
|
110
|
-
function isZodErrorLike(error) {
|
|
111
|
-
return error !== null && typeof error === "object" && "issues" in error && Array.isArray(error.issues) && error.issues.every((issue) => issue !== null && typeof issue === "object" && "path" in issue && Array.isArray(issue.path) && "message" in issue && typeof issue.message === "string");
|
|
112
|
-
}
|
|
113
|
-
function formatError(error) {
|
|
114
|
-
if (error instanceof zod.ZodError || isZodErrorLike(error)) return `Zod raw error: ${JSON.stringify(error.issues)}`;
|
|
115
|
-
if (error instanceof Error) return `${error.name}: ${error.message}`;
|
|
116
|
-
return String(error);
|
|
117
|
-
}
|
|
118
|
-
//#endregion
|
|
119
129
|
//#region src/constants/rulesync-paths.ts
|
|
120
|
-
const { join: join$
|
|
130
|
+
const { join: join$272 } = node_path.posix;
|
|
121
131
|
const RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
|
|
122
132
|
const RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH = "rulesync.local.jsonc";
|
|
123
133
|
const RULESYNC_RELATIVE_DIR_PATH = ".rulesync";
|
|
124
|
-
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$
|
|
125
|
-
const RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH = join$
|
|
126
|
-
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$
|
|
127
|
-
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$
|
|
128
|
-
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$
|
|
129
|
-
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$
|
|
130
|
-
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$
|
|
131
|
-
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
const
|
|
134
|
+
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "rules");
|
|
135
|
+
const RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH = join$272(RULESYNC_RULES_RELATIVE_DIR_PATH, ".curated");
|
|
136
|
+
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "commands");
|
|
137
|
+
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "subagents");
|
|
138
|
+
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "checks");
|
|
139
|
+
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "mcp.jsonc");
|
|
140
|
+
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "hooks.jsonc");
|
|
141
|
+
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "permissions.jsonc");
|
|
142
|
+
join$272(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
|
|
143
|
+
const RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "hooks.json");
|
|
144
|
+
const RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "permissions.json");
|
|
135
145
|
const RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
|
|
136
|
-
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$
|
|
146
|
+
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
|
|
137
147
|
const RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
|
|
138
148
|
const RULESYNC_OVERVIEW_FILE_NAME = "overview.md";
|
|
139
|
-
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$
|
|
140
|
-
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$
|
|
149
|
+
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$272(RULESYNC_RELATIVE_DIR_PATH, "skills");
|
|
150
|
+
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$272(RULESYNC_SKILLS_RELATIVE_DIR_PATH, ".curated");
|
|
141
151
|
const RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync.lock";
|
|
142
152
|
const RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync-npm.lock.json";
|
|
143
|
-
const RULESYNC_MCP_FILE_NAME = "mcp.
|
|
144
|
-
const RULESYNC_HOOKS_FILE_NAME = "hooks.
|
|
145
|
-
const RULESYNC_PERMISSIONS_FILE_NAME = "permissions.
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
const
|
|
153
|
+
const RULESYNC_MCP_FILE_NAME = "mcp.jsonc";
|
|
154
|
+
const RULESYNC_HOOKS_FILE_NAME = "hooks.jsonc";
|
|
155
|
+
const RULESYNC_PERMISSIONS_FILE_NAME = "permissions.jsonc";
|
|
156
|
+
const RULESYNC_MCP_LEGACY_FILE_NAME = "mcp.json";
|
|
157
|
+
const RULESYNC_HOOKS_LEGACY_FILE_NAME = "hooks.json";
|
|
158
|
+
const RULESYNC_PERMISSIONS_LEGACY_FILE_NAME = "permissions.json";
|
|
149
159
|
const RULESYNC_CONFIG_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/config-schema.json";
|
|
150
160
|
const RULESYNC_MCP_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/mcp-schema.json";
|
|
151
161
|
const RULESYNC_PERMISSIONS_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/permissions-schema.json";
|
|
@@ -158,6 +168,7 @@ const rulesProcessorToolTargetTuple = [
|
|
|
158
168
|
"amp",
|
|
159
169
|
"antigravity-cli",
|
|
160
170
|
"antigravity-ide",
|
|
171
|
+
"antigravity-plugin",
|
|
161
172
|
"augmentcode",
|
|
162
173
|
"augmentcode-legacy",
|
|
163
174
|
"claudecode",
|
|
@@ -174,6 +185,7 @@ const rulesProcessorToolTargetTuple = [
|
|
|
174
185
|
"hermesagent",
|
|
175
186
|
"junie",
|
|
176
187
|
"kilo",
|
|
188
|
+
"kimi-code",
|
|
177
189
|
"kiro",
|
|
178
190
|
"kiro-cli",
|
|
179
191
|
"kiro-ide",
|
|
@@ -217,8 +229,10 @@ const mcpProcessorToolTargetTuple = [
|
|
|
217
229
|
"amp",
|
|
218
230
|
"antigravity-cli",
|
|
219
231
|
"antigravity-ide",
|
|
232
|
+
"antigravity-plugin",
|
|
220
233
|
"augmentcode",
|
|
221
234
|
"claudecode",
|
|
235
|
+
"claudecode-plugin",
|
|
222
236
|
"claudecode-legacy",
|
|
223
237
|
"cline",
|
|
224
238
|
"codexcli",
|
|
@@ -230,6 +244,7 @@ const mcpProcessorToolTargetTuple = [
|
|
|
230
244
|
"goose",
|
|
231
245
|
"grokcli",
|
|
232
246
|
"hermesagent",
|
|
247
|
+
"kimi-code",
|
|
233
248
|
"kilo",
|
|
234
249
|
"kiro",
|
|
235
250
|
"kiro-cli",
|
|
@@ -252,6 +267,7 @@ const commandsProcessorToolTargetTuple = [
|
|
|
252
267
|
"antigravity-ide",
|
|
253
268
|
"augmentcode",
|
|
254
269
|
"claudecode",
|
|
270
|
+
"claudecode-plugin",
|
|
255
271
|
"claudecode-legacy",
|
|
256
272
|
"cline",
|
|
257
273
|
"codexcli",
|
|
@@ -279,6 +295,7 @@ const subagentsProcessorToolTargetTuple = [
|
|
|
279
295
|
"agentsmd",
|
|
280
296
|
"augmentcode",
|
|
281
297
|
"claudecode",
|
|
298
|
+
"claudecode-plugin",
|
|
282
299
|
"claudecode-legacy",
|
|
283
300
|
"cline",
|
|
284
301
|
"codexcli",
|
|
@@ -291,6 +308,7 @@ const subagentsProcessorToolTargetTuple = [
|
|
|
291
308
|
"goose",
|
|
292
309
|
"grokcli",
|
|
293
310
|
"hermesagent",
|
|
311
|
+
"kimi-code",
|
|
294
312
|
"junie",
|
|
295
313
|
"kiro",
|
|
296
314
|
"kiro-cli",
|
|
@@ -310,8 +328,10 @@ const skillsProcessorToolTargetTuple = [
|
|
|
310
328
|
"amp",
|
|
311
329
|
"antigravity-cli",
|
|
312
330
|
"antigravity-ide",
|
|
331
|
+
"antigravity-plugin",
|
|
313
332
|
"augmentcode",
|
|
314
333
|
"claudecode",
|
|
334
|
+
"claudecode-plugin",
|
|
315
335
|
"claudecode-legacy",
|
|
316
336
|
"cline",
|
|
317
337
|
"codexcli",
|
|
@@ -323,6 +343,7 @@ const skillsProcessorToolTargetTuple = [
|
|
|
323
343
|
"goose",
|
|
324
344
|
"grokcli",
|
|
325
345
|
"hermesagent",
|
|
346
|
+
"kimi-code",
|
|
326
347
|
"junie",
|
|
327
348
|
"kilo",
|
|
328
349
|
"kiro",
|
|
@@ -345,9 +366,11 @@ const hooksProcessorToolTargetTuple = [
|
|
|
345
366
|
"amp",
|
|
346
367
|
"antigravity-cli",
|
|
347
368
|
"antigravity-ide",
|
|
369
|
+
"antigravity-plugin",
|
|
348
370
|
"kilo",
|
|
349
371
|
"cursor",
|
|
350
372
|
"claudecode",
|
|
373
|
+
"claudecode-plugin",
|
|
351
374
|
"codexcli",
|
|
352
375
|
"copilot",
|
|
353
376
|
"copilotcli",
|
|
@@ -356,6 +379,7 @@ const hooksProcessorToolTargetTuple = [
|
|
|
356
379
|
"factorydroid",
|
|
357
380
|
"goose",
|
|
358
381
|
"hermesagent",
|
|
382
|
+
"kimi-code",
|
|
359
383
|
"deepagents",
|
|
360
384
|
"kiro",
|
|
361
385
|
"kiro-cli",
|
|
@@ -383,6 +407,7 @@ const permissionsProcessorToolTargetTuple = [
|
|
|
383
407
|
"goose",
|
|
384
408
|
"grokcli",
|
|
385
409
|
"hermesagent",
|
|
410
|
+
"kimi-code",
|
|
386
411
|
"junie",
|
|
387
412
|
"kilo",
|
|
388
413
|
"kiro",
|
|
@@ -413,6 +438,7 @@ const ALL_TOOL_TARGETS = [...new Set([
|
|
|
413
438
|
].flat())];
|
|
414
439
|
const ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
415
440
|
const ToolTargetSchema = zod_mini.z.enum(ALL_TOOL_TARGETS);
|
|
441
|
+
const PACKAGING_TOOL_TARGETS = ["antigravity-plugin", "claudecode-plugin"];
|
|
416
442
|
zod_mini.z.array(ToolTargetSchema);
|
|
417
443
|
const RulesyncTargetsSchema = zod_mini.z.array(zod_mini.z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD));
|
|
418
444
|
const RulesyncConfigTargetsObjectSchema = zod_mini.z.record(zod_mini.z.string(), PerTargetFeaturesValueSchema);
|
|
@@ -568,12 +594,12 @@ async function readFileBuffer(filepath) {
|
|
|
568
594
|
return (0, node_fs_promises.readFile)(filepath);
|
|
569
595
|
}
|
|
570
596
|
/**
|
|
571
|
-
*
|
|
597
|
+
* Normalizes text to LF line endings and adds exactly one trailing newline.
|
|
572
598
|
* Removes any existing trailing whitespace and appends a single newline.
|
|
573
599
|
*/
|
|
574
600
|
function addTrailingNewline(content) {
|
|
575
601
|
if (!content) return "\n";
|
|
576
|
-
return content.trimEnd() + "\n";
|
|
602
|
+
return content.replaceAll("\r\n", "\n").replaceAll("\r", "\n").trimEnd() + "\n";
|
|
577
603
|
}
|
|
578
604
|
async function writeFileContent(filepath, content) {
|
|
579
605
|
await ensureDir((0, node_path.dirname)(filepath));
|
|
@@ -609,7 +635,7 @@ async function listDirectoryFiles(dir) {
|
|
|
609
635
|
}
|
|
610
636
|
}
|
|
611
637
|
async function findFilesByGlobs(globs, options = {}) {
|
|
612
|
-
const { type = "all" } = options;
|
|
638
|
+
const { type = "all", followSymbolicLinks = true } = options;
|
|
613
639
|
const globbyOptions = type === "file" ? {
|
|
614
640
|
onlyFiles: true,
|
|
615
641
|
onlyDirectories: false
|
|
@@ -622,7 +648,7 @@ async function findFilesByGlobs(globs, options = {}) {
|
|
|
622
648
|
};
|
|
623
649
|
const results = (0, globby.globbySync)(Array.isArray(globs) ? globs.map((g) => g.replaceAll("\\", "/")) : globs.replaceAll("\\", "/"), {
|
|
624
650
|
absolute: true,
|
|
625
|
-
followSymbolicLinks
|
|
651
|
+
followSymbolicLinks,
|
|
626
652
|
...globbyOptions
|
|
627
653
|
});
|
|
628
654
|
const seenRealPaths = /* @__PURE__ */ new Set();
|
|
@@ -1035,12 +1061,13 @@ const CONFLICTING_TARGET_PAIRS = [["augmentcode", "augmentcode-legacy"], ["claud
|
|
|
1035
1061
|
*/
|
|
1036
1062
|
const LEGACY_TARGETS = ["augmentcode-legacy", "claudecode-legacy"];
|
|
1037
1063
|
/**
|
|
1038
|
-
* Expand the wildcard target (`*`) to every non-legacy tool target.
|
|
1039
|
-
* targets are excluded because they must be
|
|
1040
|
-
* `Config.getTargets()` and
|
|
1064
|
+
* Expand the wildcard target (`*`) to every ordinary non-legacy tool target.
|
|
1065
|
+
* Legacy aliases and package-root targets are excluded because they must be
|
|
1066
|
+
* requested explicitly. Shared by `Config.getTargets()` and
|
|
1067
|
+
* `extractConfigFileTargets()` so the two never drift.
|
|
1041
1068
|
*/
|
|
1042
1069
|
function expandWildcardTargets() {
|
|
1043
|
-
return ALL_TOOL_TARGETS.filter((target) => !LEGACY_TARGETS.includes(target));
|
|
1070
|
+
return ALL_TOOL_TARGETS.filter((target) => !LEGACY_TARGETS.includes(target) && !PACKAGING_TOOL_TARGETS.includes(target));
|
|
1044
1071
|
}
|
|
1045
1072
|
/**
|
|
1046
1073
|
* Validates that the user-authored config does not double-define the
|
|
@@ -1190,7 +1217,7 @@ var Config = class Config {
|
|
|
1190
1217
|
getTargets() {
|
|
1191
1218
|
if (this.objectFormTargetKeys !== void 0) return this.objectFormTargetKeys;
|
|
1192
1219
|
const arrayTargets = Array.isArray(this.targets) ? this.targets : [];
|
|
1193
|
-
if (arrayTargets.includes("*")) return expandWildcardTargets();
|
|
1220
|
+
if (arrayTargets.includes("*")) return [.../* @__PURE__ */ new Set([...expandWildcardTargets(), ...arrayTargets.filter((target) => target !== "*")])];
|
|
1194
1221
|
return arrayTargets.filter((target) => target !== "*");
|
|
1195
1222
|
}
|
|
1196
1223
|
getConfigFileTargets() {
|
|
@@ -1572,7 +1599,7 @@ function extractConfigFileTargets(targets) {
|
|
|
1572
1599
|
if (targets === void 0) return void 0;
|
|
1573
1600
|
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
1574
1601
|
if (isRulesyncConfigTargetsObject(targets)) return Object.keys(targets).filter((key) => validTargets.has(key));
|
|
1575
|
-
if (targets.includes("*")) return expandWildcardTargets();
|
|
1602
|
+
if (targets.includes("*")) return [.../* @__PURE__ */ new Set([...expandWildcardTargets(), ...targets.filter((key) => key !== "*" && validTargets.has(key))])];
|
|
1576
1603
|
return targets.filter((key) => key !== "*" && validTargets.has(key));
|
|
1577
1604
|
}
|
|
1578
1605
|
//#endregion
|
|
@@ -1968,7 +1995,7 @@ const hasControlChars = (val) => CONTROL_CHARS.some((char) => val.includes(char)
|
|
|
1968
1995
|
const safeString = zod_mini.z.pipe(zod_mini.z.string(), zod_mini.z.custom((val) => typeof val === "string" && !hasControlChars(val), "must not contain newline, carriage return, or NUL characters"));
|
|
1969
1996
|
/**
|
|
1970
1997
|
* Canonical hook definition.
|
|
1971
|
-
* Used in .rulesync/hooks.
|
|
1998
|
+
* Used in .rulesync/hooks.jsonc and mapped to tool-specific formats.
|
|
1972
1999
|
*/
|
|
1973
2000
|
const HookDefinitionSchema = zod_mini.z.looseObject({
|
|
1974
2001
|
command: zod_mini.z.optional(safeString),
|
|
@@ -1982,6 +2009,7 @@ const HookDefinitionSchema = zod_mini.z.looseObject({
|
|
|
1982
2009
|
])),
|
|
1983
2010
|
url: zod_mini.z.optional(safeString),
|
|
1984
2011
|
timeout: zod_mini.z.optional(zod_mini.z.number()),
|
|
2012
|
+
cacheTtl: zod_mini.z.optional(zod_mini.z.number().check((0, zod_mini.nonnegative)())),
|
|
1985
2013
|
matcher: zod_mini.z.optional(safeString),
|
|
1986
2014
|
prompt: zod_mini.z.optional(safeString),
|
|
1987
2015
|
loop_limit: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.number())),
|
|
@@ -2521,6 +2549,51 @@ const GROKCLI_HOOK_EVENTS = [
|
|
|
2521
2549
|
"postCompact"
|
|
2522
2550
|
];
|
|
2523
2551
|
/**
|
|
2552
|
+
* Hook events supported by Kimi Code.
|
|
2553
|
+
*
|
|
2554
|
+
* Kimi Code also exposes `Interrupt`, which has no canonical rulesync event.
|
|
2555
|
+
*
|
|
2556
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/hooks.html
|
|
2557
|
+
*/
|
|
2558
|
+
const KIMI_CODE_HOOK_EVENTS = [
|
|
2559
|
+
"sessionStart",
|
|
2560
|
+
"sessionEnd",
|
|
2561
|
+
"beforeSubmitPrompt",
|
|
2562
|
+
"preToolUse",
|
|
2563
|
+
"postToolUse",
|
|
2564
|
+
"postToolUseFailure",
|
|
2565
|
+
"permissionRequest",
|
|
2566
|
+
"stop",
|
|
2567
|
+
"stopFailure",
|
|
2568
|
+
"notification",
|
|
2569
|
+
"subagentStart",
|
|
2570
|
+
"subagentStop",
|
|
2571
|
+
"preCompact",
|
|
2572
|
+
"postCompact"
|
|
2573
|
+
];
|
|
2574
|
+
const CANONICAL_TO_KIMI_CODE_EVENT_NAMES = {
|
|
2575
|
+
sessionStart: "SessionStart",
|
|
2576
|
+
sessionEnd: "SessionEnd",
|
|
2577
|
+
beforeSubmitPrompt: "UserPromptSubmit",
|
|
2578
|
+
preToolUse: "PreToolUse",
|
|
2579
|
+
postToolUse: "PostToolUse",
|
|
2580
|
+
postToolUseFailure: "PostToolUseFailure",
|
|
2581
|
+
permissionRequest: "PermissionRequest",
|
|
2582
|
+
stop: "Stop",
|
|
2583
|
+
stopFailure: "StopFailure",
|
|
2584
|
+
notification: "Notification",
|
|
2585
|
+
subagentStart: "SubagentStart",
|
|
2586
|
+
subagentStop: "SubagentStop",
|
|
2587
|
+
preCompact: "PreCompact",
|
|
2588
|
+
postCompact: "PostCompact"
|
|
2589
|
+
};
|
|
2590
|
+
const KIMI_CODE_NATIVE_HOOK_EVENTS = [
|
|
2591
|
+
...Object.values(CANONICAL_TO_KIMI_CODE_EVENT_NAMES),
|
|
2592
|
+
"PermissionResult",
|
|
2593
|
+
"Interrupt"
|
|
2594
|
+
];
|
|
2595
|
+
const KIMI_CODE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_KIMI_CODE_EVENT_NAMES).map(([canonical, kimiCode]) => [kimiCode, canonical]));
|
|
2596
|
+
/**
|
|
2524
2597
|
* Hook events supported by Hermes Agent's native Shell Hooks system.
|
|
2525
2598
|
*
|
|
2526
2599
|
* Hermes validates hook events against a fixed `VALID_HOOKS` set:
|
|
@@ -2611,6 +2684,7 @@ const HooksConfigSchema = zod_mini.z.looseObject({
|
|
|
2611
2684
|
vibe: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
2612
2685
|
reasonix: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
2613
2686
|
grokcli: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
2687
|
+
"kimi-code": zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
2614
2688
|
qwencode: zod_mini.z.optional(zod_mini.z.looseObject({
|
|
2615
2689
|
hooks: zod_mini.z.optional(hooksRecordSchema),
|
|
2616
2690
|
disableAllHooks: zod_mini.z.optional(zod_mini.z.boolean())
|
|
@@ -3137,6 +3211,28 @@ function parseJsonc$8(content) {
|
|
|
3137
3211
|
return deepSanitize(result);
|
|
3138
3212
|
}
|
|
3139
3213
|
//#endregion
|
|
3214
|
+
//#region src/utils/rulesync-source-path.ts
|
|
3215
|
+
function getRulesyncSourceCandidates({ paths }) {
|
|
3216
|
+
return [paths.recommended, ...paths.legacy];
|
|
3217
|
+
}
|
|
3218
|
+
async function resolveRulesyncSourceWritePath({ outputRoot, paths }) {
|
|
3219
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3220
|
+
const targetPath = (0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3221
|
+
if (await fileExists(targetPath)) {
|
|
3222
|
+
await assertWritablePathInsideRoot({
|
|
3223
|
+
rootPath: outputRoot,
|
|
3224
|
+
targetPath
|
|
3225
|
+
});
|
|
3226
|
+
return candidate;
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
await assertWritablePathInsideRoot({
|
|
3230
|
+
rootPath: outputRoot,
|
|
3231
|
+
targetPath: (0, node_path.join)(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath)
|
|
3232
|
+
});
|
|
3233
|
+
return paths.recommended;
|
|
3234
|
+
}
|
|
3235
|
+
//#endregion
|
|
3140
3236
|
//#region src/features/hooks/rulesync-hooks.ts
|
|
3141
3237
|
var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
3142
3238
|
json;
|
|
@@ -3150,12 +3246,14 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3150
3246
|
}
|
|
3151
3247
|
static getSettablePaths() {
|
|
3152
3248
|
return {
|
|
3153
|
-
|
|
3154
|
-
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
3155
|
-
jsonc: {
|
|
3249
|
+
recommended: {
|
|
3156
3250
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3157
|
-
relativeFilePath:
|
|
3158
|
-
}
|
|
3251
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME
|
|
3252
|
+
},
|
|
3253
|
+
legacy: [{
|
|
3254
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3255
|
+
relativeFilePath: RULESYNC_HOOKS_LEGACY_FILE_NAME
|
|
3256
|
+
}]
|
|
3159
3257
|
};
|
|
3160
3258
|
}
|
|
3161
3259
|
validate() {
|
|
@@ -3171,11 +3269,7 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3171
3269
|
}
|
|
3172
3270
|
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
3173
3271
|
const paths = RulesyncHooks.getSettablePaths();
|
|
3174
|
-
const
|
|
3175
|
-
relativeDirPath: paths.relativeDirPath,
|
|
3176
|
-
relativeFilePath: paths.relativeFilePath
|
|
3177
|
-
}];
|
|
3178
|
-
for (const candidate of candidates) {
|
|
3272
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3179
3273
|
const filePath = (0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3180
3274
|
if (!await fileExists(filePath)) continue;
|
|
3181
3275
|
const fileContent = await readFileContent(filePath);
|
|
@@ -3187,7 +3281,7 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3187
3281
|
validate
|
|
3188
3282
|
});
|
|
3189
3283
|
}
|
|
3190
|
-
throw new Error(`No ${RULESYNC_HOOKS_RELATIVE_FILE_PATH} or ${
|
|
3284
|
+
throw new Error(`No ${RULESYNC_HOOKS_RELATIVE_FILE_PATH} or ${RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH} found.`);
|
|
3191
3285
|
}
|
|
3192
3286
|
getJson() {
|
|
3193
3287
|
return this.json;
|
|
@@ -3305,8 +3399,8 @@ const RulesyncMcpConfigSchema = zod_mini.z.object({ mcpServers: zod_mini.z.recor
|
|
|
3305
3399
|
* Tool-scoped MCP block: servers that apply only to one tool. A named entry
|
|
3306
3400
|
* replaces/adds the same-named shared server wholesale for that tool; `null`
|
|
3307
3401
|
* removes the shared server for that tool. Mirrors `{toolname}.hooks` in
|
|
3308
|
-
* `.rulesync/hooks.
|
|
3309
|
-
* `.rulesync/permissions.
|
|
3402
|
+
* `.rulesync/hooks.jsonc` and `{toolname}.permission` in
|
|
3403
|
+
* `.rulesync/permissions.jsonc`.
|
|
3310
3404
|
*/
|
|
3311
3405
|
const toolScopedMcpSchema = zod_mini.z.looseObject({ mcpServers: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), zod_mini.z.nullable(RulesyncMcpServerSchema))) });
|
|
3312
3406
|
const RulesyncMcpFileSchema = zod_mini.z.looseObject({
|
|
@@ -3331,6 +3425,7 @@ const RulesyncMcpFileSchema = zod_mini.z.looseObject({
|
|
|
3331
3425
|
hermesagent: zod_mini.z.optional(toolScopedMcpSchema),
|
|
3332
3426
|
junie: zod_mini.z.optional(toolScopedMcpSchema),
|
|
3333
3427
|
kilo: zod_mini.z.optional(toolScopedMcpSchema),
|
|
3428
|
+
"kimi-code": zod_mini.z.optional(toolScopedMcpSchema),
|
|
3334
3429
|
kiro: zod_mini.z.optional(toolScopedMcpSchema),
|
|
3335
3430
|
opencode: zod_mini.z.optional(toolScopedMcpSchema),
|
|
3336
3431
|
qwencode: zod_mini.z.optional(toolScopedMcpSchema),
|
|
@@ -3358,14 +3453,13 @@ var RulesyncMcp = class RulesyncMcp extends RulesyncFile {
|
|
|
3358
3453
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3359
3454
|
relativeFilePath: RULESYNC_MCP_FILE_NAME
|
|
3360
3455
|
},
|
|
3361
|
-
|
|
3456
|
+
legacy: [{
|
|
3362
3457
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3363
|
-
relativeFilePath:
|
|
3364
|
-
},
|
|
3365
|
-
legacy: {
|
|
3458
|
+
relativeFilePath: RULESYNC_MCP_LEGACY_FILE_NAME
|
|
3459
|
+
}, {
|
|
3366
3460
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3367
3461
|
relativeFilePath: ".mcp.json"
|
|
3368
|
-
}
|
|
3462
|
+
}]
|
|
3369
3463
|
};
|
|
3370
3464
|
}
|
|
3371
3465
|
validate() {
|
|
@@ -3381,41 +3475,23 @@ var RulesyncMcp = class RulesyncMcp extends RulesyncFile {
|
|
|
3381
3475
|
}
|
|
3382
3476
|
static async fromFile({ outputRoot = process.cwd(), validate = true, logger }) {
|
|
3383
3477
|
const paths = this.getSettablePaths();
|
|
3384
|
-
const
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
relativeFilePath: paths.jsonc.relativeFilePath,
|
|
3393
|
-
fileContent,
|
|
3394
|
-
validate
|
|
3395
|
-
});
|
|
3396
|
-
}
|
|
3397
|
-
if (await fileExists(recommendedPath)) {
|
|
3398
|
-
const fileContent = await readFileContent(recommendedPath);
|
|
3399
|
-
return new RulesyncMcp({
|
|
3400
|
-
outputRoot,
|
|
3401
|
-
relativeDirPath: paths.recommended.relativeDirPath,
|
|
3402
|
-
relativeFilePath: paths.recommended.relativeFilePath,
|
|
3403
|
-
fileContent,
|
|
3404
|
-
validate
|
|
3405
|
-
});
|
|
3406
|
-
}
|
|
3407
|
-
if (await fileExists(legacyPath)) {
|
|
3408
|
-
logger?.warn(`⚠️ Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`);
|
|
3409
|
-
const fileContent = await readFileContent(legacyPath);
|
|
3478
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3479
|
+
const filePath = (0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3480
|
+
if (!await fileExists(filePath)) continue;
|
|
3481
|
+
if (candidate.relativeFilePath === ".mcp.json") {
|
|
3482
|
+
const recommendedPath = (0, node_path.join)(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath);
|
|
3483
|
+
logger?.warn(`⚠️ Using deprecated path "${filePath}". Please migrate to "${recommendedPath}"`);
|
|
3484
|
+
}
|
|
3485
|
+
const fileContent = await readFileContent(filePath);
|
|
3410
3486
|
return new RulesyncMcp({
|
|
3411
3487
|
outputRoot,
|
|
3412
|
-
relativeDirPath:
|
|
3413
|
-
relativeFilePath:
|
|
3488
|
+
relativeDirPath: candidate.relativeDirPath,
|
|
3489
|
+
relativeFilePath: candidate.relativeFilePath,
|
|
3414
3490
|
fileContent,
|
|
3415
3491
|
validate
|
|
3416
3492
|
});
|
|
3417
3493
|
}
|
|
3418
|
-
const fileContent = await readFileContent(
|
|
3494
|
+
const fileContent = await readFileContent((0, node_path.join)(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath));
|
|
3419
3495
|
return new RulesyncMcp({
|
|
3420
3496
|
outputRoot,
|
|
3421
3497
|
relativeDirPath: paths.recommended.relativeDirPath,
|
|
@@ -3616,7 +3692,7 @@ const PermissionRulesSchema = zod_mini.z.record(zod_mini.z.string(), PermissionA
|
|
|
3616
3692
|
* key it appears under. During generation the categories placed here are
|
|
3617
3693
|
* merged over the shared `permission` block per category (the tool-scoped
|
|
3618
3694
|
* category replaces the shared one wholesale), mirroring how
|
|
3619
|
-
* `.rulesync/hooks.
|
|
3695
|
+
* `.rulesync/hooks.jsonc` merges `{toolname}.hooks` per event.
|
|
3620
3696
|
*
|
|
3621
3697
|
* @example
|
|
3622
3698
|
* { "claudecode": { "permission": { "bash": { "git push *": "deny" } } } }
|
|
@@ -3629,6 +3705,25 @@ const ToolScopedPermissionSchema = zod_mini.z.record(zod_mini.z.string(), Permis
|
|
|
3629
3705
|
* added without a schema break.
|
|
3630
3706
|
*/
|
|
3631
3707
|
const CanonicalPermissionsOverrideSchema = zod_mini.z.looseObject({ permission: zod_mini.z.optional(ToolScopedPermissionSchema) });
|
|
3708
|
+
const KimiCodePermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
3709
|
+
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
3710
|
+
defaultPermissionMode: zod_mini.z.optional(zod_mini.z.enum([
|
|
3711
|
+
"manual",
|
|
3712
|
+
"yolo",
|
|
3713
|
+
"auto"
|
|
3714
|
+
])),
|
|
3715
|
+
rules: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.looseObject({
|
|
3716
|
+
decision: PermissionActionSchema,
|
|
3717
|
+
pattern: zod_mini.z.string(),
|
|
3718
|
+
scope: zod_mini.z.optional(zod_mini.z.enum([
|
|
3719
|
+
"turn-override",
|
|
3720
|
+
"session-runtime",
|
|
3721
|
+
"project",
|
|
3722
|
+
"user"
|
|
3723
|
+
])),
|
|
3724
|
+
reason: zod_mini.z.optional(zod_mini.z.string())
|
|
3725
|
+
})))
|
|
3726
|
+
});
|
|
3632
3727
|
/**
|
|
3633
3728
|
* OpenCode-specific permission value. Unlike the shared canonical block, which
|
|
3634
3729
|
* only accepts a pattern-to-action map, OpenCode also allows a bare action
|
|
@@ -4220,6 +4315,7 @@ const PermissionsConfigSchema = zod_mini.z.looseObject({
|
|
|
4220
4315
|
devin: zod_mini.z.optional(CanonicalPermissionsOverrideSchema),
|
|
4221
4316
|
goose: zod_mini.z.optional(CanonicalPermissionsOverrideSchema),
|
|
4222
4317
|
grokcli: zod_mini.z.optional(CanonicalPermissionsOverrideSchema),
|
|
4318
|
+
"kimi-code": zod_mini.z.optional(KimiCodePermissionsOverrideSchema),
|
|
4223
4319
|
rovodev: zod_mini.z.optional(CanonicalPermissionsOverrideSchema),
|
|
4224
4320
|
zed: zod_mini.z.optional(CanonicalPermissionsOverrideSchema)
|
|
4225
4321
|
});
|
|
@@ -4244,12 +4340,14 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4244
4340
|
}
|
|
4245
4341
|
static getSettablePaths() {
|
|
4246
4342
|
return {
|
|
4247
|
-
|
|
4248
|
-
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
4249
|
-
jsonc: {
|
|
4343
|
+
recommended: {
|
|
4250
4344
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
4251
|
-
relativeFilePath:
|
|
4252
|
-
}
|
|
4345
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME
|
|
4346
|
+
},
|
|
4347
|
+
legacy: [{
|
|
4348
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
4349
|
+
relativeFilePath: RULESYNC_PERMISSIONS_LEGACY_FILE_NAME
|
|
4350
|
+
}]
|
|
4253
4351
|
};
|
|
4254
4352
|
}
|
|
4255
4353
|
validate() {
|
|
@@ -4265,11 +4363,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4265
4363
|
}
|
|
4266
4364
|
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
4267
4365
|
const paths = RulesyncPermissions.getSettablePaths();
|
|
4268
|
-
const
|
|
4269
|
-
relativeDirPath: paths.relativeDirPath,
|
|
4270
|
-
relativeFilePath: paths.relativeFilePath
|
|
4271
|
-
}];
|
|
4272
|
-
for (const candidate of candidates) {
|
|
4366
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
4273
4367
|
const filePath = (0, node_path.join)(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
4274
4368
|
if (!await fileExists(filePath)) continue;
|
|
4275
4369
|
const fileContent = await readFileContent(filePath);
|
|
@@ -4281,7 +4375,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4281
4375
|
validate
|
|
4282
4376
|
});
|
|
4283
4377
|
}
|
|
4284
|
-
throw new Error(`No ${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH} or ${
|
|
4378
|
+
throw new Error(`No ${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH} or ${RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH} found.`);
|
|
4285
4379
|
}
|
|
4286
4380
|
getJson() {
|
|
4287
4381
|
return this.json;
|
|
@@ -4291,7 +4385,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4291
4385
|
* tool-scoped `{toolname}.permission` block over the shared `permission`
|
|
4292
4386
|
* block, per category (the tool-scoped category replaces the shared one
|
|
4293
4387
|
* wholesale — mirroring how `{toolname}.hooks` merges per event in
|
|
4294
|
-
* `.rulesync/hooks.
|
|
4388
|
+
* `.rulesync/hooks.jsonc`). The consumed `permission` key is stripped from
|
|
4295
4389
|
* the override block so verbatim-passthrough translators (e.g. the Hermes
|
|
4296
4390
|
* deep merge or the Codex CLI top-level key whitelist) never see it.
|
|
4297
4391
|
*
|
|
@@ -4656,6 +4750,16 @@ const RulesyncSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
|
4656
4750
|
"disable-model-invocation": zod_mini.z.optional(zod_mini.z.boolean()),
|
|
4657
4751
|
"user-invocable": zod_mini.z.optional(zod_mini.z.boolean())
|
|
4658
4752
|
})),
|
|
4753
|
+
"kimi-code": zod_mini.z.optional(zod_mini.z.looseObject({
|
|
4754
|
+
type: zod_mini.z.optional(zod_mini.z.enum([
|
|
4755
|
+
"prompt",
|
|
4756
|
+
"inline",
|
|
4757
|
+
"flow"
|
|
4758
|
+
])),
|
|
4759
|
+
whenToUse: zod_mini.z.optional(zod_mini.z.string()),
|
|
4760
|
+
disableModelInvocation: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
4761
|
+
arguments: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())]))
|
|
4762
|
+
})),
|
|
4659
4763
|
agentsskills: zod_mini.z.optional(zod_mini.z.looseObject({
|
|
4660
4764
|
license: zod_mini.z.optional(zod_mini.z.string()),
|
|
4661
4765
|
compatibility: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.looseObject({})])),
|
|
@@ -6357,6 +6461,28 @@ var ClaudecodeCommand = class ClaudecodeCommand extends ToolCommand {
|
|
|
6357
6461
|
}
|
|
6358
6462
|
};
|
|
6359
6463
|
//#endregion
|
|
6464
|
+
//#region src/constants/plugin-paths.ts
|
|
6465
|
+
const CLAUDECODE_PLUGIN_COMMANDS_DIR = "commands";
|
|
6466
|
+
const CLAUDECODE_PLUGIN_AGENTS_DIR = "agents";
|
|
6467
|
+
const CLAUDECODE_PLUGIN_SKILLS_DIR = "skills";
|
|
6468
|
+
const CLAUDECODE_PLUGIN_HOOKS_DIR = "hooks";
|
|
6469
|
+
const CLAUDECODE_PLUGIN_HOOKS_FILE_NAME = "hooks.json";
|
|
6470
|
+
const ANTIGRAVITY_PLUGIN_RULES_DIR = "rules";
|
|
6471
|
+
const ANTIGRAVITY_PLUGIN_SKILLS_DIR = "skills";
|
|
6472
|
+
const ANTIGRAVITY_PLUGIN_MCP_FILE_NAME = "mcp_config.json";
|
|
6473
|
+
const ANTIGRAVITY_PLUGIN_HOOKS_FILE_NAME = "hooks.json";
|
|
6474
|
+
//#endregion
|
|
6475
|
+
//#region src/features/commands/claudecode-plugin-command.ts
|
|
6476
|
+
var ClaudecodePluginCommand = class extends ClaudecodeCommand {
|
|
6477
|
+
static isTargetedByRulesyncCommand(rulesyncCommand) {
|
|
6478
|
+
const targets = rulesyncCommand.getFrontmatter().targets;
|
|
6479
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
6480
|
+
}
|
|
6481
|
+
static getSettablePaths() {
|
|
6482
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_COMMANDS_DIR };
|
|
6483
|
+
}
|
|
6484
|
+
};
|
|
6485
|
+
//#endregion
|
|
6360
6486
|
//#region src/constants/cline-paths.ts
|
|
6361
6487
|
const CLINE_DIR = ".cline";
|
|
6362
6488
|
const CLINERULES_DIR = ".clinerules";
|
|
@@ -7372,6 +7498,7 @@ const TAKT_CONFIG_SHARED_FILE_KEY = ".takt/config.yaml";
|
|
|
7372
7498
|
const CODEXCLI_CONFIG_SHARED_FILE_KEY = ".codex/config.toml";
|
|
7373
7499
|
const GROKCLI_CONFIG_SHARED_FILE_KEY = ".grok/config.toml";
|
|
7374
7500
|
const VIBE_CONFIG_SHARED_FILE_KEY = ".vibe/config.toml";
|
|
7501
|
+
const KIMI_CODE_CONFIG_SHARED_FILE_KEY = ".kimi-code/config.toml";
|
|
7375
7502
|
const REASONIX_PROJECT_CONFIG_SHARED_FILE_KEY = "reasonix.toml";
|
|
7376
7503
|
const REASONIX_GLOBAL_CONFIG_SHARED_FILE_KEY = ".reasonix/config.toml";
|
|
7377
7504
|
/**
|
|
@@ -7716,6 +7843,20 @@ const SHARED_CONFIG_OWNERSHIP = {
|
|
|
7716
7843
|
}
|
|
7717
7844
|
}
|
|
7718
7845
|
},
|
|
7846
|
+
[KIMI_CODE_CONFIG_SHARED_FILE_KEY]: {
|
|
7847
|
+
format: "toml",
|
|
7848
|
+
invalidRootPolicy: "error",
|
|
7849
|
+
features: {
|
|
7850
|
+
hooks: {
|
|
7851
|
+
kind: "replace-owned-keys",
|
|
7852
|
+
ownedKeys: ["hooks"]
|
|
7853
|
+
},
|
|
7854
|
+
permissions: {
|
|
7855
|
+
kind: "replace-owned-keys",
|
|
7856
|
+
ownedKeys: ["permission", "default_permission_mode"]
|
|
7857
|
+
}
|
|
7858
|
+
}
|
|
7859
|
+
},
|
|
7719
7860
|
[REASONIX_PROJECT_CONFIG_SHARED_FILE_KEY]: {
|
|
7720
7861
|
format: "toml",
|
|
7721
7862
|
features: {
|
|
@@ -7850,6 +7991,10 @@ const applyPermissions = (params) => {
|
|
|
7850
7991
|
function toolSkillSearchRoots(paths) {
|
|
7851
7992
|
return [paths.relativeDirPath, ...paths.alternativeSkillRoots ?? []];
|
|
7852
7993
|
}
|
|
7994
|
+
/** Ordered import roots: managed roots first, followed by read-only discovery roots. */
|
|
7995
|
+
function toolSkillImportRoots(paths) {
|
|
7996
|
+
return [...toolSkillSearchRoots(paths), ...paths.importOnlySkillRoots ?? []];
|
|
7997
|
+
}
|
|
7853
7998
|
/**
|
|
7854
7999
|
* Abstract base class for AI development tool-specific skill formats.
|
|
7855
8000
|
*
|
|
@@ -7932,6 +8077,13 @@ var ToolSkill = class extends AiDir {
|
|
|
7932
8077
|
throw new Error("Please implement this method in the subclass.");
|
|
7933
8078
|
}
|
|
7934
8079
|
/**
|
|
8080
|
+
* Identity used to resolve duplicates across discovery roots during import.
|
|
8081
|
+
* Most tools identify a skill by its directory name.
|
|
8082
|
+
*/
|
|
8083
|
+
getImportIdentity() {
|
|
8084
|
+
return this.getDirName();
|
|
8085
|
+
}
|
|
8086
|
+
/**
|
|
7935
8087
|
* Load and parse skill directory content.
|
|
7936
8088
|
* This is a helper method that handles the common logic of reading SKILL.md,
|
|
7937
8089
|
* parsing frontmatter, and collecting other files.
|
|
@@ -8683,6 +8835,7 @@ const KIRO_IDE_HOOKS_DIR_PATH = (0, node_path.join)(KIRO_DIR, "hooks");
|
|
|
8683
8835
|
const KIRO_IDE_HOOKS_FILE_NAME = "rulesync.json";
|
|
8684
8836
|
const KIRO_MCP_FILE_NAME = "mcp.json";
|
|
8685
8837
|
const KIRO_IGNORE_FILE_NAME = ".kiroignore";
|
|
8838
|
+
const KIRO_GLOBAL_IGNORE_FILE_NAME = "kiroignore";
|
|
8686
8839
|
//#endregion
|
|
8687
8840
|
//#region src/features/commands/kiro-command.ts
|
|
8688
8841
|
var KiroCommand = class KiroCommand extends ToolCommand {
|
|
@@ -9963,6 +10116,16 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
9963
10116
|
supportsSubdirectory: true
|
|
9964
10117
|
}
|
|
9965
10118
|
}],
|
|
10119
|
+
["claudecode-plugin", {
|
|
10120
|
+
class: ClaudecodePluginCommand,
|
|
10121
|
+
meta: {
|
|
10122
|
+
extension: "md",
|
|
10123
|
+
supportsProject: true,
|
|
10124
|
+
supportsGlobal: false,
|
|
10125
|
+
isSimulated: false,
|
|
10126
|
+
supportsSubdirectory: true
|
|
10127
|
+
}
|
|
10128
|
+
}],
|
|
9966
10129
|
["claudecode-legacy", {
|
|
9967
10130
|
class: ClaudecodeCommand,
|
|
9968
10131
|
meta: {
|
|
@@ -10500,7 +10663,7 @@ var ToolHooks = class extends ToolFile {
|
|
|
10500
10663
|
return new RulesyncHooks({
|
|
10501
10664
|
outputRoot: this.outputRoot,
|
|
10502
10665
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
10503
|
-
relativeFilePath:
|
|
10666
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
10504
10667
|
fileContent: fileContent ?? this.fileContent
|
|
10505
10668
|
});
|
|
10506
10669
|
}
|
|
@@ -10597,7 +10760,7 @@ function isToolMatcherEntry(x) {
|
|
|
10597
10760
|
/**
|
|
10598
10761
|
* Filter the shared canonical hooks to the supported events and merge tool overrides on top.
|
|
10599
10762
|
*/
|
|
10600
|
-
function buildEffectiveHooks$
|
|
10763
|
+
function buildEffectiveHooks$2({ config, toolOverrideHooks, supportedEvents }) {
|
|
10601
10764
|
const supported = new Set(supportedEvents);
|
|
10602
10765
|
const sharedHooks = {};
|
|
10603
10766
|
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) sharedHooks[event] = defs;
|
|
@@ -10727,7 +10890,7 @@ function buildToolHooks({ defs, converterConfig }) {
|
|
|
10727
10890
|
* (e.g. beforeSubmitPrompt → UserPromptSubmit).
|
|
10728
10891
|
*/
|
|
10729
10892
|
function canonicalToToolHooks({ config, toolOverrideHooks, converterConfig, logger }) {
|
|
10730
|
-
const effectiveHooks = buildEffectiveHooks$
|
|
10893
|
+
const effectiveHooks = buildEffectiveHooks$2({
|
|
10731
10894
|
config,
|
|
10732
10895
|
toolOverrideHooks,
|
|
10733
10896
|
supportedEvents: converterConfig.supportedEvents
|
|
@@ -10864,7 +11027,7 @@ function toolMatcherEntryToCanonical({ rawEntry, converterConfig }) {
|
|
|
10864
11027
|
}
|
|
10865
11028
|
/**
|
|
10866
11029
|
* Assemble the canonical hooks config a tool importer writes to
|
|
10867
|
-
* `.rulesync/hooks.
|
|
11030
|
+
* `.rulesync/hooks.jsonc`.
|
|
10868
11031
|
*
|
|
10869
11032
|
* The top-level `hooks` record only accepts canonical event names, so any
|
|
10870
11033
|
* imported native event key without a canonical mapping is moved under the
|
|
@@ -11067,6 +11230,16 @@ var AntigravityCliHooks = class extends AntigravityHooks {
|
|
|
11067
11230
|
}
|
|
11068
11231
|
};
|
|
11069
11232
|
//#endregion
|
|
11233
|
+
//#region src/features/hooks/antigravity-plugin-hooks.ts
|
|
11234
|
+
var AntigravityPluginHooks = class extends AntigravityIdeHooks {
|
|
11235
|
+
static getSettablePaths() {
|
|
11236
|
+
return {
|
|
11237
|
+
relativeDirPath: ".",
|
|
11238
|
+
relativeFilePath: ANTIGRAVITY_PLUGIN_HOOKS_FILE_NAME
|
|
11239
|
+
};
|
|
11240
|
+
}
|
|
11241
|
+
};
|
|
11242
|
+
//#endregion
|
|
11070
11243
|
//#region src/utils/augmentcode-settings.ts
|
|
11071
11244
|
/**
|
|
11072
11245
|
* Top-level keys AugmentCode *replaces* (higher-precedence wins wholesale)
|
|
@@ -11292,7 +11465,7 @@ const CLAUDE_CONVERTER_CONFIG = {
|
|
|
11292
11465
|
tool: "if"
|
|
11293
11466
|
}]
|
|
11294
11467
|
};
|
|
11295
|
-
var ClaudecodeHooks = class
|
|
11468
|
+
var ClaudecodeHooks = class extends ToolHooks {
|
|
11296
11469
|
constructor(params) {
|
|
11297
11470
|
super({
|
|
11298
11471
|
...params,
|
|
@@ -11309,9 +11482,9 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11309
11482
|
};
|
|
11310
11483
|
}
|
|
11311
11484
|
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
11312
|
-
const paths =
|
|
11485
|
+
const paths = this.getSettablePaths({ global });
|
|
11313
11486
|
const fileContent = await readFileContentOrNull((0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath)) ?? "{\"hooks\":{}}";
|
|
11314
|
-
return new
|
|
11487
|
+
return new this({
|
|
11315
11488
|
outputRoot,
|
|
11316
11489
|
relativeDirPath: paths.relativeDirPath,
|
|
11317
11490
|
relativeFilePath: paths.relativeFilePath,
|
|
@@ -11320,7 +11493,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11320
11493
|
});
|
|
11321
11494
|
}
|
|
11322
11495
|
static async fromRulesyncHooks({ outputRoot = process.cwd(), rulesyncHooks, validate = true, global = false, logger }) {
|
|
11323
|
-
const paths =
|
|
11496
|
+
const paths = this.getSettablePaths({ global });
|
|
11324
11497
|
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
11325
11498
|
const existingContent = await readOrInitializeFileContent(filePath, JSON.stringify({}, null, 2));
|
|
11326
11499
|
const config = rulesyncHooks.getJson();
|
|
@@ -11336,7 +11509,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11336
11509
|
}) },
|
|
11337
11510
|
filePath
|
|
11338
11511
|
});
|
|
11339
|
-
return new
|
|
11512
|
+
return new this({
|
|
11340
11513
|
outputRoot,
|
|
11341
11514
|
relativeDirPath: paths.relativeDirPath,
|
|
11342
11515
|
relativeFilePath: paths.relativeFilePath,
|
|
@@ -11367,7 +11540,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11367
11540
|
};
|
|
11368
11541
|
}
|
|
11369
11542
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
11370
|
-
return new
|
|
11543
|
+
return new this({
|
|
11371
11544
|
outputRoot,
|
|
11372
11545
|
relativeDirPath,
|
|
11373
11546
|
relativeFilePath,
|
|
@@ -11377,6 +11550,19 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11377
11550
|
}
|
|
11378
11551
|
};
|
|
11379
11552
|
//#endregion
|
|
11553
|
+
//#region src/features/hooks/claudecode-plugin-hooks.ts
|
|
11554
|
+
var ClaudecodePluginHooks = class extends ClaudecodeHooks {
|
|
11555
|
+
isDeletable() {
|
|
11556
|
+
return true;
|
|
11557
|
+
}
|
|
11558
|
+
static getSettablePaths() {
|
|
11559
|
+
return {
|
|
11560
|
+
relativeDirPath: CLAUDECODE_PLUGIN_HOOKS_DIR,
|
|
11561
|
+
relativeFilePath: CLAUDECODE_PLUGIN_HOOKS_FILE_NAME
|
|
11562
|
+
};
|
|
11563
|
+
}
|
|
11564
|
+
};
|
|
11565
|
+
//#endregion
|
|
11380
11566
|
//#region src/features/hooks/codexcli-hooks.ts
|
|
11381
11567
|
const CODEXCLI_CONVERTER_CONFIG = {
|
|
11382
11568
|
supportedEvents: CODEXCLI_HOOK_EVENTS,
|
|
@@ -12743,7 +12929,7 @@ const HERMESAGENT_MATCHER_EVENTS = /* @__PURE__ */ new Set(["preToolUse", "postT
|
|
|
12743
12929
|
* Filter the shared canonical hooks to the events Hermes understands and merge
|
|
12744
12930
|
* the `hermesagent`-specific override block on top.
|
|
12745
12931
|
*/
|
|
12746
|
-
function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
12932
|
+
function buildEffectiveHooks$1(config, toolOverrideHooks) {
|
|
12747
12933
|
const supported = new Set(HERMESAGENT_HOOK_EVENTS);
|
|
12748
12934
|
const shared = {};
|
|
12749
12935
|
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) shared[event] = defs;
|
|
@@ -12765,7 +12951,7 @@ function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
|
12765
12951
|
* matcher-less lifecycle events.
|
|
12766
12952
|
*/
|
|
12767
12953
|
function canonicalToHermesHooks({ config, toolOverrideHooks, logger }) {
|
|
12768
|
-
const effectiveHooks = buildEffectiveHooks(config, toolOverrideHooks);
|
|
12954
|
+
const effectiveHooks = buildEffectiveHooks$1(config, toolOverrideHooks);
|
|
12769
12955
|
const result = {};
|
|
12770
12956
|
for (const [canonicalEvent, defs] of Object.entries(effectiveHooks)) {
|
|
12771
12957
|
const nativeEvent = CANONICAL_TO_HERMESAGENT_EVENT_NAMES[canonicalEvent];
|
|
@@ -13205,6 +13391,197 @@ var KiloHooks = class KiloHooks extends ToolHooks {
|
|
|
13205
13391
|
}
|
|
13206
13392
|
};
|
|
13207
13393
|
//#endregion
|
|
13394
|
+
//#region src/constants/kimi-code-paths.ts
|
|
13395
|
+
const KIMI_CODE_DIR = ".kimi-code";
|
|
13396
|
+
const KIMI_CODE_RULE_FILE_NAME = "AGENTS.md";
|
|
13397
|
+
const KIMI_CODE_MCP_FILE_NAME = "mcp.json";
|
|
13398
|
+
const KIMI_CODE_CONFIG_FILE_NAME = "config.toml";
|
|
13399
|
+
const KIMI_CODE_SKILLS_DIR_NAME = "skills";
|
|
13400
|
+
const KIMI_CODE_AGENTS_DIR_NAME = "agents";
|
|
13401
|
+
const KIMI_CODE_SKILLS_DIR_PATH = (0, node_path.join)(KIMI_CODE_DIR, KIMI_CODE_SKILLS_DIR_NAME);
|
|
13402
|
+
(0, node_path.join)(KIMI_CODE_DIR, KIMI_CODE_AGENTS_DIR_NAME);
|
|
13403
|
+
const KIMI_CODE_SHARED_SKILLS_DIR_PATH = (0, node_path.join)(".agents", "skills");
|
|
13404
|
+
const KIMI_CODE_SHARED_AGENTS_DIR_PATH = (0, node_path.join)(".agents", "agents");
|
|
13405
|
+
//#endregion
|
|
13406
|
+
//#region src/utils/kimi-code.ts
|
|
13407
|
+
function getKimiCodeHome() {
|
|
13408
|
+
const configuredHome = process.env.KIMI_CODE_HOME?.trim();
|
|
13409
|
+
return configuredHome ? (0, node_path.resolve)(configuredHome) : void 0;
|
|
13410
|
+
}
|
|
13411
|
+
function resolveToolOutputRoot({ outputRoot, toolTarget, global }) {
|
|
13412
|
+
return toolTarget === "kimi-code" && global ? getKimiCodeHome() ?? outputRoot : outputRoot;
|
|
13413
|
+
}
|
|
13414
|
+
function getKimiCodeRelativeDirPath({ global, relativeDirPath = "." }) {
|
|
13415
|
+
return global && getKimiCodeHome() ? relativeDirPath : (0, node_path.join)(KIMI_CODE_DIR, relativeDirPath);
|
|
13416
|
+
}
|
|
13417
|
+
function getKimiCodeRulesyncOutputRoot({ nativeOutputRoot, global }) {
|
|
13418
|
+
return global && getKimiCodeHome() ? getHomeDirectory() : nativeOutputRoot;
|
|
13419
|
+
}
|
|
13420
|
+
//#endregion
|
|
13421
|
+
//#region src/features/hooks/kimi-code-hooks.ts
|
|
13422
|
+
function runFromTrustedDirectory({ command, trustedDirectory }) {
|
|
13423
|
+
if (process.platform === "win32") return `set "RULESYNC_KIMI_HOOK_CWD=1" && cd /d "${trustedDirectory.replaceAll("%", "%%").replaceAll("\"", "\"\"")}" && ${command}`;
|
|
13424
|
+
return `export RULESYNC_KIMI_HOOK_CWD=1 && cd -- '${trustedDirectory.replaceAll("'", `'"'"'`)}' && ${command}`;
|
|
13425
|
+
}
|
|
13426
|
+
function stripTrustedDirectoryWrapper(command) {
|
|
13427
|
+
const posix = command.match(/^export RULESYNC_KIMI_HOOK_CWD=1 && cd -- '(?:[^']|'"'"')*' && ([\s\S]*)$/);
|
|
13428
|
+
if (posix?.[1]) return posix[1];
|
|
13429
|
+
return command.match(/^set "RULESYNC_KIMI_HOOK_CWD=1" && cd \/d "(?:""|[^"])*" && ([\s\S]*)$/)?.[1] ?? command;
|
|
13430
|
+
}
|
|
13431
|
+
function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
13432
|
+
const supported = new Set(KIMI_CODE_HOOK_EVENTS);
|
|
13433
|
+
const shared = {};
|
|
13434
|
+
for (const [event, definitions] of Object.entries(config.hooks)) if (supported.has(event)) shared[event] = definitions;
|
|
13435
|
+
return {
|
|
13436
|
+
...shared,
|
|
13437
|
+
...toolOverrideHooks
|
|
13438
|
+
};
|
|
13439
|
+
}
|
|
13440
|
+
function canonicalToKimiCodeHooks({ config, toolOverrideHooks, trustedDirectory, logger }) {
|
|
13441
|
+
const result = [];
|
|
13442
|
+
const nativeEvents = new Set(KIMI_CODE_NATIVE_HOOK_EVENTS);
|
|
13443
|
+
for (const [event, definitions] of Object.entries(buildEffectiveHooks(config, toolOverrideHooks))) {
|
|
13444
|
+
const nativeEvent = CANONICAL_TO_KIMI_CODE_EVENT_NAMES[event] ?? event;
|
|
13445
|
+
if (!nativeEvents.has(nativeEvent)) {
|
|
13446
|
+
logger?.warn(`Kimi Code hooks: skipping unsupported event "${event}".`);
|
|
13447
|
+
continue;
|
|
13448
|
+
}
|
|
13449
|
+
for (const definition of definitions) {
|
|
13450
|
+
if ((definition.type ?? "command") !== "command" || !definition.command) continue;
|
|
13451
|
+
const timeout = definition.timeout;
|
|
13452
|
+
const validTimeout = timeout === void 0 || Number.isInteger(timeout) && timeout >= 1 && timeout <= 600;
|
|
13453
|
+
if (!validTimeout) logger?.warn(`Kimi Code hooks: omitting invalid timeout for "${event}"; expected an integer from 1 to 600 seconds.`);
|
|
13454
|
+
result.push({
|
|
13455
|
+
event: nativeEvent,
|
|
13456
|
+
command: runFromTrustedDirectory({
|
|
13457
|
+
command: definition.command,
|
|
13458
|
+
trustedDirectory
|
|
13459
|
+
}),
|
|
13460
|
+
...definition.matcher && { matcher: definition.matcher },
|
|
13461
|
+
...validTimeout && timeout !== void 0 && { timeout }
|
|
13462
|
+
});
|
|
13463
|
+
}
|
|
13464
|
+
}
|
|
13465
|
+
return result;
|
|
13466
|
+
}
|
|
13467
|
+
function kimiCodeHooksToCanonical(hooks) {
|
|
13468
|
+
const result = {};
|
|
13469
|
+
if (!Array.isArray(hooks)) return result;
|
|
13470
|
+
for (const raw of hooks) {
|
|
13471
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
13472
|
+
const entry = raw;
|
|
13473
|
+
if (typeof entry.event !== "string" || typeof entry.command !== "string") continue;
|
|
13474
|
+
const event = KIMI_CODE_TO_CANONICAL_EVENT_NAMES[entry.event] ?? entry.event;
|
|
13475
|
+
const definition = {
|
|
13476
|
+
type: "command",
|
|
13477
|
+
command: stripTrustedDirectoryWrapper(entry.command),
|
|
13478
|
+
...typeof entry.matcher === "string" && { matcher: entry.matcher },
|
|
13479
|
+
...typeof entry.timeout === "number" && { timeout: entry.timeout }
|
|
13480
|
+
};
|
|
13481
|
+
(result[event] ??= []).push(definition);
|
|
13482
|
+
}
|
|
13483
|
+
return result;
|
|
13484
|
+
}
|
|
13485
|
+
/**
|
|
13486
|
+
* Kimi Code lifecycle hooks in the shared user `config.toml`.
|
|
13487
|
+
*
|
|
13488
|
+
* Kimi Code documents hooks only at user scope. The config file also contains
|
|
13489
|
+
* models, providers, permissions, and other settings, so the hooks patch is
|
|
13490
|
+
* merged in place and the file is never deleted.
|
|
13491
|
+
*
|
|
13492
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/hooks.html
|
|
13493
|
+
*/
|
|
13494
|
+
var KimiCodeHooks = class KimiCodeHooks extends ToolHooks {
|
|
13495
|
+
constructor(params) {
|
|
13496
|
+
super({
|
|
13497
|
+
...params,
|
|
13498
|
+
...KimiCodeHooks.getSettablePaths({ global: params.global ?? true })
|
|
13499
|
+
});
|
|
13500
|
+
}
|
|
13501
|
+
static getSettablePaths({ global = true } = {}) {
|
|
13502
|
+
return {
|
|
13503
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
13504
|
+
relativeFilePath: KIMI_CODE_CONFIG_FILE_NAME
|
|
13505
|
+
};
|
|
13506
|
+
}
|
|
13507
|
+
validate() {
|
|
13508
|
+
return {
|
|
13509
|
+
success: true,
|
|
13510
|
+
error: null
|
|
13511
|
+
};
|
|
13512
|
+
}
|
|
13513
|
+
isDeletable() {
|
|
13514
|
+
return false;
|
|
13515
|
+
}
|
|
13516
|
+
shouldMergeExistingFileContent() {
|
|
13517
|
+
return true;
|
|
13518
|
+
}
|
|
13519
|
+
setFileContent(fileContent) {
|
|
13520
|
+
const paths = KimiCodeHooks.getSettablePaths({ global: this.global });
|
|
13521
|
+
this.fileContent = applySharedConfigPatch({
|
|
13522
|
+
fileKey: KIMI_CODE_CONFIG_SHARED_FILE_KEY,
|
|
13523
|
+
feature: "hooks",
|
|
13524
|
+
existingContent: fileContent,
|
|
13525
|
+
patch: parseSharedConfig({
|
|
13526
|
+
format: "toml",
|
|
13527
|
+
fileContent: this.fileContent
|
|
13528
|
+
}),
|
|
13529
|
+
filePath: (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath)
|
|
13530
|
+
});
|
|
13531
|
+
}
|
|
13532
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = true }) {
|
|
13533
|
+
const paths = this.getSettablePaths({ global });
|
|
13534
|
+
return new KimiCodeHooks({
|
|
13535
|
+
outputRoot,
|
|
13536
|
+
fileContent: await readFileContent((0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath)),
|
|
13537
|
+
validate,
|
|
13538
|
+
global
|
|
13539
|
+
});
|
|
13540
|
+
}
|
|
13541
|
+
static fromRulesyncHooks({ outputRoot, rulesyncHooks, logger }) {
|
|
13542
|
+
const config = rulesyncHooks.getJson();
|
|
13543
|
+
return new KimiCodeHooks({
|
|
13544
|
+
outputRoot,
|
|
13545
|
+
fileContent: stringifySharedConfig({
|
|
13546
|
+
format: "toml",
|
|
13547
|
+
document: { hooks: canonicalToKimiCodeHooks({
|
|
13548
|
+
config,
|
|
13549
|
+
toolOverrideHooks: config["kimi-code"]?.hooks,
|
|
13550
|
+
trustedDirectory: (0, node_path.resolve)(rulesyncHooks.getOutputRoot()),
|
|
13551
|
+
logger
|
|
13552
|
+
}) }
|
|
13553
|
+
}),
|
|
13554
|
+
global: true
|
|
13555
|
+
});
|
|
13556
|
+
}
|
|
13557
|
+
toRulesyncHooks() {
|
|
13558
|
+
const config = parseSharedConfig({
|
|
13559
|
+
format: "toml",
|
|
13560
|
+
fileContent: this.getFileContent()
|
|
13561
|
+
});
|
|
13562
|
+
return new RulesyncHooks({
|
|
13563
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
13564
|
+
nativeOutputRoot: this.outputRoot,
|
|
13565
|
+
global: this.global
|
|
13566
|
+
}),
|
|
13567
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
13568
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
13569
|
+
fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
13570
|
+
hooks: kimiCodeHooksToCanonical(config.hooks),
|
|
13571
|
+
overrideKey: "kimi-code"
|
|
13572
|
+
}), null, 2)
|
|
13573
|
+
});
|
|
13574
|
+
}
|
|
13575
|
+
static forDeletion({ outputRoot = process.cwd() }) {
|
|
13576
|
+
return new KimiCodeHooks({
|
|
13577
|
+
outputRoot,
|
|
13578
|
+
fileContent: "",
|
|
13579
|
+
validate: false,
|
|
13580
|
+
global: true
|
|
13581
|
+
});
|
|
13582
|
+
}
|
|
13583
|
+
};
|
|
13584
|
+
//#endregion
|
|
13208
13585
|
//#region src/features/hooks/kiro-hooks.ts
|
|
13209
13586
|
/**
|
|
13210
13587
|
* Convert canonical hooks config to Kiro CLI format.
|
|
@@ -13220,6 +13597,7 @@ function buildKiroEntriesForEvent(definitions) {
|
|
|
13220
13597
|
command: def.command,
|
|
13221
13598
|
...def.matcher !== void 0 && def.matcher !== null && def.matcher !== "" && { matcher: def.matcher },
|
|
13222
13599
|
...def.timeout !== void 0 && def.timeout !== null && def.timeout > 0 && { timeout_ms: def.timeout },
|
|
13600
|
+
...def.cacheTtl !== void 0 && { cache_ttl_seconds: def.cacheTtl },
|
|
13223
13601
|
...def.name !== void 0 && def.name !== null && { name: def.name },
|
|
13224
13602
|
...def.description !== void 0 && def.description !== null && { description: def.description }
|
|
13225
13603
|
});
|
|
@@ -13252,9 +13630,14 @@ const KiroHookEntrySchema = zod_mini.z.looseObject({
|
|
|
13252
13630
|
command: zod_mini.z.optional(safeString),
|
|
13253
13631
|
matcher: zod_mini.z.optional(zod_mini.z.string()),
|
|
13254
13632
|
timeout_ms: zod_mini.z.optional(zod_mini.z.number()),
|
|
13633
|
+
cache_ttl_seconds: zod_mini.z.optional(zod_mini.z.number().check((0, zod_mini.nonnegative)())),
|
|
13255
13634
|
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
13256
13635
|
description: zod_mini.z.optional(zod_mini.z.string())
|
|
13257
13636
|
});
|
|
13637
|
+
function importCacheTtl(entry) {
|
|
13638
|
+
if (entry.cache_ttl_seconds === void 0) return {};
|
|
13639
|
+
return { cacheTtl: entry.cache_ttl_seconds };
|
|
13640
|
+
}
|
|
13258
13641
|
/**
|
|
13259
13642
|
* Extract hooks from Kiro CLI agent config into canonical format.
|
|
13260
13643
|
*/
|
|
@@ -13275,6 +13658,7 @@ function kiroHooksToCanonical(kiroHooks) {
|
|
|
13275
13658
|
command: entry.command,
|
|
13276
13659
|
...entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" && { matcher: entry.matcher },
|
|
13277
13660
|
...entry.timeout_ms !== void 0 && entry.timeout_ms !== null && { timeout: entry.timeout_ms },
|
|
13661
|
+
...importCacheTtl(entry),
|
|
13278
13662
|
...entry.name !== void 0 && entry.name !== null && { name: entry.name },
|
|
13279
13663
|
...entry.description !== void 0 && entry.description !== null && { description: entry.description }
|
|
13280
13664
|
});
|
|
@@ -14514,6 +14898,17 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14514
14898
|
supportedHookTypes: ["command"],
|
|
14515
14899
|
supportsMatcher: true
|
|
14516
14900
|
}],
|
|
14901
|
+
["antigravity-plugin", {
|
|
14902
|
+
class: AntigravityPluginHooks,
|
|
14903
|
+
meta: {
|
|
14904
|
+
supportsProject: true,
|
|
14905
|
+
supportsGlobal: false,
|
|
14906
|
+
supportsImport: true
|
|
14907
|
+
},
|
|
14908
|
+
supportedEvents: ANTIGRAVITY_HOOK_EVENTS,
|
|
14909
|
+
supportedHookTypes: ["command"],
|
|
14910
|
+
supportsMatcher: true
|
|
14911
|
+
}],
|
|
14517
14912
|
["cursor", {
|
|
14518
14913
|
class: CursorHooks,
|
|
14519
14914
|
meta: {
|
|
@@ -14542,6 +14937,23 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14542
14937
|
],
|
|
14543
14938
|
supportsMatcher: true
|
|
14544
14939
|
}],
|
|
14940
|
+
["claudecode-plugin", {
|
|
14941
|
+
class: ClaudecodePluginHooks,
|
|
14942
|
+
meta: {
|
|
14943
|
+
supportsProject: true,
|
|
14944
|
+
supportsGlobal: false,
|
|
14945
|
+
supportsImport: true
|
|
14946
|
+
},
|
|
14947
|
+
supportedEvents: CLAUDE_HOOK_EVENTS,
|
|
14948
|
+
supportedHookTypes: [
|
|
14949
|
+
"command",
|
|
14950
|
+
"prompt",
|
|
14951
|
+
"http",
|
|
14952
|
+
"mcp_tool",
|
|
14953
|
+
"agent"
|
|
14954
|
+
],
|
|
14955
|
+
supportsMatcher: true
|
|
14956
|
+
}],
|
|
14545
14957
|
["codexcli", {
|
|
14546
14958
|
class: CodexcliHooks,
|
|
14547
14959
|
meta: {
|
|
@@ -14645,6 +15057,18 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14645
15057
|
supportedHookTypes: ["command"],
|
|
14646
15058
|
supportsMatcher: true
|
|
14647
15059
|
}],
|
|
15060
|
+
["kimi-code", {
|
|
15061
|
+
class: KimiCodeHooks,
|
|
15062
|
+
meta: {
|
|
15063
|
+
supportsProject: false,
|
|
15064
|
+
supportsGlobal: true,
|
|
15065
|
+
supportsImport: true
|
|
15066
|
+
},
|
|
15067
|
+
supportedEvents: KIMI_CODE_HOOK_EVENTS,
|
|
15068
|
+
supportedHookTypes: ["command"],
|
|
15069
|
+
supportsMatcher: true,
|
|
15070
|
+
passthroughOverrideEvents: true
|
|
15071
|
+
}],
|
|
14648
15072
|
["deepagents", {
|
|
14649
15073
|
class: DeepagentsHooks,
|
|
14650
15074
|
meta: {
|
|
@@ -15820,40 +16244,45 @@ var KiloIgnore = class KiloIgnore extends ToolIgnore {
|
|
|
15820
16244
|
//#endregion
|
|
15821
16245
|
//#region src/features/ignore/kiro-ignore.ts
|
|
15822
16246
|
var KiroIgnore = class KiroIgnore extends ToolIgnore {
|
|
15823
|
-
static getSettablePaths() {
|
|
16247
|
+
static getSettablePaths({ global = false } = {}) {
|
|
15824
16248
|
return {
|
|
15825
|
-
relativeDirPath: ".",
|
|
15826
|
-
relativeFilePath: KIRO_IGNORE_FILE_NAME
|
|
16249
|
+
relativeDirPath: global ? KIRO_SETTINGS_DIR_PATH : ".",
|
|
16250
|
+
relativeFilePath: global ? KIRO_GLOBAL_IGNORE_FILE_NAME : KIRO_IGNORE_FILE_NAME
|
|
15827
16251
|
};
|
|
15828
16252
|
}
|
|
15829
16253
|
toRulesyncIgnore() {
|
|
15830
16254
|
return this.toRulesyncIgnoreDefault();
|
|
15831
16255
|
}
|
|
15832
|
-
static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore }) {
|
|
16256
|
+
static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore, global = false }) {
|
|
16257
|
+
const paths = this.getSettablePaths({ global });
|
|
15833
16258
|
return new KiroIgnore({
|
|
15834
16259
|
outputRoot,
|
|
15835
|
-
relativeDirPath:
|
|
15836
|
-
relativeFilePath:
|
|
15837
|
-
fileContent: rulesyncIgnore.getFileContent()
|
|
16260
|
+
relativeDirPath: paths.relativeDirPath,
|
|
16261
|
+
relativeFilePath: paths.relativeFilePath,
|
|
16262
|
+
fileContent: rulesyncIgnore.getFileContent(),
|
|
16263
|
+
global
|
|
15838
16264
|
});
|
|
15839
16265
|
}
|
|
15840
|
-
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
15841
|
-
const
|
|
16266
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
16267
|
+
const paths = this.getSettablePaths({ global });
|
|
16268
|
+
const fileContent = await readFileContent((0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath));
|
|
15842
16269
|
return new KiroIgnore({
|
|
15843
16270
|
outputRoot,
|
|
15844
|
-
relativeDirPath:
|
|
15845
|
-
relativeFilePath:
|
|
16271
|
+
relativeDirPath: paths.relativeDirPath,
|
|
16272
|
+
relativeFilePath: paths.relativeFilePath,
|
|
15846
16273
|
fileContent,
|
|
15847
|
-
validate
|
|
16274
|
+
validate,
|
|
16275
|
+
global
|
|
15848
16276
|
});
|
|
15849
16277
|
}
|
|
15850
|
-
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
16278
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
15851
16279
|
return new KiroIgnore({
|
|
15852
16280
|
outputRoot,
|
|
15853
16281
|
relativeDirPath,
|
|
15854
16282
|
relativeFilePath,
|
|
15855
16283
|
fileContent: "",
|
|
15856
|
-
validate: false
|
|
16284
|
+
validate: false,
|
|
16285
|
+
global
|
|
15857
16286
|
});
|
|
15858
16287
|
}
|
|
15859
16288
|
};
|
|
@@ -16160,6 +16589,11 @@ const toolIgnoreFactories = /* @__PURE__ */ new Map([
|
|
|
16160
16589
|
["zed", { class: ZedIgnore }]
|
|
16161
16590
|
]);
|
|
16162
16591
|
const ignoreProcessorToolTargets = [...toolIgnoreFactories.keys()];
|
|
16592
|
+
const ignoreProcessorGlobalToolTargets = [
|
|
16593
|
+
"kiro",
|
|
16594
|
+
"kiro-cli",
|
|
16595
|
+
"kiro-ide"
|
|
16596
|
+
];
|
|
16163
16597
|
const defaultGetFactory$4 = (target) => {
|
|
16164
16598
|
const factory = toolIgnoreFactories.get(target);
|
|
16165
16599
|
if (!factory) throw new Error(`Unsupported tool target: ${target}`);
|
|
@@ -16169,7 +16603,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16169
16603
|
toolTarget;
|
|
16170
16604
|
getFactory;
|
|
16171
16605
|
featureOptions;
|
|
16172
|
-
|
|
16606
|
+
global;
|
|
16607
|
+
constructor({ outputRoot = process.cwd(), inputRoot = process.cwd(), toolTarget, getFactory = defaultGetFactory$4, global = false, dryRun = false, logger, featureOptions }) {
|
|
16173
16608
|
super({
|
|
16174
16609
|
outputRoot,
|
|
16175
16610
|
inputRoot,
|
|
@@ -16181,6 +16616,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16181
16616
|
this.toolTarget = result.data;
|
|
16182
16617
|
this.getFactory = getFactory;
|
|
16183
16618
|
this.featureOptions = featureOptions;
|
|
16619
|
+
this.global = global;
|
|
16184
16620
|
}
|
|
16185
16621
|
async writeToolIgnoresFromRulesyncIgnores(rulesyncIgnores) {
|
|
16186
16622
|
const toolIgnores = await this.convertRulesyncFilesToToolFiles(rulesyncIgnores);
|
|
@@ -16205,12 +16641,16 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16205
16641
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
16206
16642
|
try {
|
|
16207
16643
|
const factory = this.getFactory(this.toolTarget);
|
|
16208
|
-
const paths = factory.class.getSettablePaths({
|
|
16644
|
+
const paths = factory.class.getSettablePaths({
|
|
16645
|
+
options: this.featureOptions,
|
|
16646
|
+
global: this.global
|
|
16647
|
+
});
|
|
16209
16648
|
if (forDeletion) {
|
|
16210
16649
|
const toolIgnore = factory.class.forDeletion({
|
|
16211
16650
|
outputRoot: this.outputRoot,
|
|
16212
16651
|
relativeDirPath: paths.relativeDirPath,
|
|
16213
|
-
relativeFilePath: paths.relativeFilePath
|
|
16652
|
+
relativeFilePath: paths.relativeFilePath,
|
|
16653
|
+
global: this.global
|
|
16214
16654
|
});
|
|
16215
16655
|
const hasOwnershipGuard = factory.class.canDeleteAuxiliaryFiles !== void 0;
|
|
16216
16656
|
if (!(!hasOwnershipGuard || await factory.class.canDeleteAuxiliaryFiles?.({ outputRoot: this.outputRoot }) === true)) return [];
|
|
@@ -16230,7 +16670,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16230
16670
|
async loadToolIgnores() {
|
|
16231
16671
|
return [await this.getFactory(this.toolTarget).class.fromFile({
|
|
16232
16672
|
outputRoot: this.outputRoot,
|
|
16233
|
-
options: this.featureOptions
|
|
16673
|
+
options: this.featureOptions,
|
|
16674
|
+
global: this.global
|
|
16234
16675
|
})];
|
|
16235
16676
|
}
|
|
16236
16677
|
/**
|
|
@@ -16244,7 +16685,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16244
16685
|
const toolIgnore = await factory.class.fromRulesyncIgnore({
|
|
16245
16686
|
outputRoot: this.outputRoot,
|
|
16246
16687
|
rulesyncIgnore,
|
|
16247
|
-
options: this.featureOptions
|
|
16688
|
+
options: this.featureOptions,
|
|
16689
|
+
global: this.global
|
|
16248
16690
|
});
|
|
16249
16691
|
const auxiliaryFiles = await factory.class.getAuxiliaryFiles?.({
|
|
16250
16692
|
toolIgnore,
|
|
@@ -16266,7 +16708,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16266
16708
|
* Return the tool targets that this processor supports
|
|
16267
16709
|
*/
|
|
16268
16710
|
static getToolTargets({ global = false } = {}) {
|
|
16269
|
-
if (global)
|
|
16711
|
+
if (global) return ignoreProcessorGlobalToolTargets;
|
|
16270
16712
|
return ignoreProcessorToolTargets;
|
|
16271
16713
|
}
|
|
16272
16714
|
};
|
|
@@ -16706,6 +17148,16 @@ var AntigravityIdeMcp = class extends AntigravityMcp {
|
|
|
16706
17148
|
}
|
|
16707
17149
|
};
|
|
16708
17150
|
//#endregion
|
|
17151
|
+
//#region src/features/mcp/antigravity-plugin-mcp.ts
|
|
17152
|
+
var AntigravityPluginMcp = class extends AntigravityIdeMcp {
|
|
17153
|
+
static getSettablePaths() {
|
|
17154
|
+
return {
|
|
17155
|
+
relativeDirPath: ".",
|
|
17156
|
+
relativeFilePath: ANTIGRAVITY_PLUGIN_MCP_FILE_NAME
|
|
17157
|
+
};
|
|
17158
|
+
}
|
|
17159
|
+
};
|
|
17160
|
+
//#endregion
|
|
16709
17161
|
//#region src/features/mcp/augmentcode-mcp.ts
|
|
16710
17162
|
function parseAugmentcodeSettings(fileContent, relativeDirPath, relativeFilePath) {
|
|
16711
17163
|
const configPath = (0, node_path.join)(relativeDirPath, relativeFilePath);
|
|
@@ -17125,7 +17577,7 @@ function convertToCodexFormat(mcpServers) {
|
|
|
17125
17577
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
17126
17578
|
if (!isRecord(config)) continue;
|
|
17127
17579
|
const { codexName, usedFallback } = normalizeCodexMcpServerName(name);
|
|
17128
|
-
if (usedFallback) warnWithFallback(void 0, `MCP server "${name}" cannot be represented as a Codex MCP server name (ASCII [a-zA-Z0-9_-] only), so the stable fallback name "${codexName}" was used. Rename the server in .rulesync/mcp.
|
|
17580
|
+
if (usedFallback) warnWithFallback(void 0, `MCP server "${name}" cannot be represented as a Codex MCP server name (ASCII [a-zA-Z0-9_-] only), so the stable fallback name "${codexName}" was used. Rename the server in .rulesync/mcp.jsonc to choose a readable Codex name.`);
|
|
17129
17581
|
const converted = {};
|
|
17130
17582
|
for (const [key, value] of Object.entries(config)) {
|
|
17131
17583
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
@@ -18934,6 +19386,170 @@ var KiloMcp = class KiloMcp extends ToolMcp {
|
|
|
18934
19386
|
}
|
|
18935
19387
|
};
|
|
18936
19388
|
//#endregion
|
|
19389
|
+
//#region src/features/mcp/kimi-code-mcp.ts
|
|
19390
|
+
function normalizeKimiCodeTransport({ transport, hasCommand }) {
|
|
19391
|
+
if (transport === "local" || transport === "stdio") return "stdio";
|
|
19392
|
+
if (transport === "sse") return "sse";
|
|
19393
|
+
if (transport === "http" || transport === "streamable-http") return "http";
|
|
19394
|
+
return hasCommand ? "stdio" : "http";
|
|
19395
|
+
}
|
|
19396
|
+
function toKimiCodeServer({ name, server, logger }) {
|
|
19397
|
+
const transport = server.transport ?? server.type;
|
|
19398
|
+
if (transport === "ws") {
|
|
19399
|
+
logger?.warn(`Kimi Code MCP: skipping "${name}" because WebSocket transport is unsupported.`);
|
|
19400
|
+
return null;
|
|
19401
|
+
}
|
|
19402
|
+
const command = server.command;
|
|
19403
|
+
const normalizedCommand = Array.isArray(command) ? command[0] : command;
|
|
19404
|
+
const args = [...Array.isArray(command) ? command.slice(1) : [], ...server.args ?? []];
|
|
19405
|
+
const url = server.httpUrl ?? server.url;
|
|
19406
|
+
const normalizedTransport = normalizeKimiCodeTransport({
|
|
19407
|
+
transport,
|
|
19408
|
+
hasCommand: normalizedCommand !== void 0
|
|
19409
|
+
});
|
|
19410
|
+
if (normalizedTransport === "stdio" && !normalizedCommand || normalizedTransport !== "stdio" && !url) {
|
|
19411
|
+
logger?.warn(`Kimi Code MCP: skipping "${name}" because its ${normalizedTransport} configuration is incomplete.`);
|
|
19412
|
+
return null;
|
|
19413
|
+
}
|
|
19414
|
+
const converted = {
|
|
19415
|
+
transport: normalizedTransport,
|
|
19416
|
+
...normalizedCommand && { command: normalizedCommand },
|
|
19417
|
+
...args.length > 0 && { args },
|
|
19418
|
+
...url && { url }
|
|
19419
|
+
};
|
|
19420
|
+
for (const field of [
|
|
19421
|
+
"env",
|
|
19422
|
+
"cwd",
|
|
19423
|
+
"headers",
|
|
19424
|
+
"bearerTokenEnvVar",
|
|
19425
|
+
"enabled",
|
|
19426
|
+
"startupTimeoutMs",
|
|
19427
|
+
"toolTimeoutMs",
|
|
19428
|
+
"enabledTools",
|
|
19429
|
+
"disabledTools"
|
|
19430
|
+
]) if (server[field] !== void 0) converted[field] = server[field];
|
|
19431
|
+
if (server.disabled === true) converted.enabled = false;
|
|
19432
|
+
return converted;
|
|
19433
|
+
}
|
|
19434
|
+
function toKimiCodeServers({ servers, logger }) {
|
|
19435
|
+
const result = {};
|
|
19436
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
19437
|
+
const converted = toKimiCodeServer({
|
|
19438
|
+
name,
|
|
19439
|
+
server,
|
|
19440
|
+
logger
|
|
19441
|
+
});
|
|
19442
|
+
if (converted) result[name] = converted;
|
|
19443
|
+
}
|
|
19444
|
+
return result;
|
|
19445
|
+
}
|
|
19446
|
+
function fromKimiCodeServers(servers) {
|
|
19447
|
+
return Object.fromEntries(Object.entries(servers).map(([name, server]) => {
|
|
19448
|
+
const { transport, enabled, ...rest } = server;
|
|
19449
|
+
const type = transport === "stdio" || transport === "sse" || transport === "http" ? transport : void 0;
|
|
19450
|
+
return [name, {
|
|
19451
|
+
...rest,
|
|
19452
|
+
...type && { type },
|
|
19453
|
+
...enabled === false && { disabled: true }
|
|
19454
|
+
}];
|
|
19455
|
+
}));
|
|
19456
|
+
}
|
|
19457
|
+
/**
|
|
19458
|
+
* Kimi Code MCP configuration.
|
|
19459
|
+
*
|
|
19460
|
+
* Both project and user scope use `.kimi-code/mcp.json`, resolved against the
|
|
19461
|
+
* project root or home directory respectively.
|
|
19462
|
+
*
|
|
19463
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/mcp.html
|
|
19464
|
+
*/
|
|
19465
|
+
var KimiCodeMcp = class KimiCodeMcp extends ToolMcp {
|
|
19466
|
+
json;
|
|
19467
|
+
constructor(params) {
|
|
19468
|
+
super(params);
|
|
19469
|
+
try {
|
|
19470
|
+
this.json = this.fileContent ? JSON.parse(this.fileContent) : {};
|
|
19471
|
+
} catch (error) {
|
|
19472
|
+
throw new Error(`Failed to parse Kimi Code MCP config at ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(error)}`, { cause: error });
|
|
19473
|
+
}
|
|
19474
|
+
}
|
|
19475
|
+
isDeletable() {
|
|
19476
|
+
return !this.global;
|
|
19477
|
+
}
|
|
19478
|
+
static getSettablePaths({ global = false } = {}) {
|
|
19479
|
+
return {
|
|
19480
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
19481
|
+
relativeFilePath: KIMI_CODE_MCP_FILE_NAME
|
|
19482
|
+
};
|
|
19483
|
+
}
|
|
19484
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
19485
|
+
const paths = this.getSettablePaths({ global });
|
|
19486
|
+
const fileContent = await readFileContentOrNull((0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath)) ?? "{\"mcpServers\":{}}";
|
|
19487
|
+
return new KimiCodeMcp({
|
|
19488
|
+
outputRoot,
|
|
19489
|
+
relativeDirPath: paths.relativeDirPath,
|
|
19490
|
+
relativeFilePath: paths.relativeFilePath,
|
|
19491
|
+
fileContent,
|
|
19492
|
+
validate,
|
|
19493
|
+
global
|
|
19494
|
+
});
|
|
19495
|
+
}
|
|
19496
|
+
static async fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, global = false, logger }) {
|
|
19497
|
+
const paths = this.getSettablePaths({ global });
|
|
19498
|
+
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
19499
|
+
const existingContent = await readFileContentOrNull(filePath) ?? "{}";
|
|
19500
|
+
let existing;
|
|
19501
|
+
try {
|
|
19502
|
+
existing = JSON.parse(existingContent);
|
|
19503
|
+
} catch (error) {
|
|
19504
|
+
throw new Error(`Failed to parse Kimi Code MCP config at ${filePath}: ${formatError(error)}`, { cause: error });
|
|
19505
|
+
}
|
|
19506
|
+
return new KimiCodeMcp({
|
|
19507
|
+
outputRoot,
|
|
19508
|
+
relativeDirPath: paths.relativeDirPath,
|
|
19509
|
+
relativeFilePath: paths.relativeFilePath,
|
|
19510
|
+
fileContent: JSON.stringify({
|
|
19511
|
+
...existing,
|
|
19512
|
+
mcpServers: toKimiCodeServers({
|
|
19513
|
+
servers: rulesyncMcp.getMcpServers(),
|
|
19514
|
+
logger
|
|
19515
|
+
})
|
|
19516
|
+
}, null, 2),
|
|
19517
|
+
validate,
|
|
19518
|
+
global
|
|
19519
|
+
});
|
|
19520
|
+
}
|
|
19521
|
+
toRulesyncMcp() {
|
|
19522
|
+
return new RulesyncMcp({
|
|
19523
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
19524
|
+
nativeOutputRoot: this.outputRoot,
|
|
19525
|
+
global: this.global
|
|
19526
|
+
}),
|
|
19527
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
19528
|
+
relativeFilePath: RULESYNC_MCP_FILE_NAME,
|
|
19529
|
+
fileContent: JSON.stringify({
|
|
19530
|
+
...this.json,
|
|
19531
|
+
mcpServers: fromKimiCodeServers(isMcpServers(this.json.mcpServers) ? this.json.mcpServers : {})
|
|
19532
|
+
}, null, 2)
|
|
19533
|
+
});
|
|
19534
|
+
}
|
|
19535
|
+
validate() {
|
|
19536
|
+
return {
|
|
19537
|
+
success: true,
|
|
19538
|
+
error: null
|
|
19539
|
+
};
|
|
19540
|
+
}
|
|
19541
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
19542
|
+
return new KimiCodeMcp({
|
|
19543
|
+
outputRoot,
|
|
19544
|
+
relativeDirPath,
|
|
19545
|
+
relativeFilePath,
|
|
19546
|
+
fileContent: "{}",
|
|
19547
|
+
validate: false,
|
|
19548
|
+
global
|
|
19549
|
+
});
|
|
19550
|
+
}
|
|
19551
|
+
};
|
|
19552
|
+
//#endregion
|
|
18937
19553
|
//#region src/features/mcp/kiro-mcp.ts
|
|
18938
19554
|
var KiroMcp = class KiroMcp extends ToolMcp {
|
|
18939
19555
|
json;
|
|
@@ -19742,7 +20358,7 @@ var RovodevMcp = class RovodevMcp extends ToolMcp {
|
|
|
19742
20358
|
* `workflow_mcp_servers: { stdio, sse, http }`. Without it, workflow-defined MCP
|
|
19743
20359
|
* servers are refused regardless of how they are declared. So this adapter emits
|
|
19744
20360
|
* the transport allowlist derived from the transports present in
|
|
19745
|
-
* `.rulesync/mcp.
|
|
20361
|
+
* `.rulesync/mcp.jsonc`, enabling exactly the transports the user's servers need.
|
|
19746
20362
|
*
|
|
19747
20363
|
* Lossiness (documented, intentional): the per-server names, commands, env, URLs
|
|
19748
20364
|
* and headers are NOT representable in `config.yaml` and are intentionally not
|
|
@@ -20262,6 +20878,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20262
20878
|
supportsDisabledTools: true
|
|
20263
20879
|
}
|
|
20264
20880
|
}],
|
|
20881
|
+
["antigravity-plugin", {
|
|
20882
|
+
class: AntigravityPluginMcp,
|
|
20883
|
+
meta: {
|
|
20884
|
+
supportsProject: true,
|
|
20885
|
+
supportsGlobal: false,
|
|
20886
|
+
supportsEnabledTools: false,
|
|
20887
|
+
supportsDisabledTools: true
|
|
20888
|
+
}
|
|
20889
|
+
}],
|
|
20265
20890
|
["augmentcode", {
|
|
20266
20891
|
class: AugmentcodeMcp,
|
|
20267
20892
|
meta: {
|
|
@@ -20280,6 +20905,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20280
20905
|
supportsDisabledTools: false
|
|
20281
20906
|
}
|
|
20282
20907
|
}],
|
|
20908
|
+
["claudecode-plugin", {
|
|
20909
|
+
class: ClaudecodeMcp,
|
|
20910
|
+
meta: {
|
|
20911
|
+
supportsProject: true,
|
|
20912
|
+
supportsGlobal: false,
|
|
20913
|
+
supportsEnabledTools: false,
|
|
20914
|
+
supportsDisabledTools: false
|
|
20915
|
+
}
|
|
20916
|
+
}],
|
|
20283
20917
|
["claudecode-legacy", {
|
|
20284
20918
|
class: ClaudecodeMcp,
|
|
20285
20919
|
meta: {
|
|
@@ -20379,6 +21013,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20379
21013
|
supportsDisabledTools: false
|
|
20380
21014
|
}
|
|
20381
21015
|
}],
|
|
21016
|
+
["kimi-code", {
|
|
21017
|
+
class: KimiCodeMcp,
|
|
21018
|
+
meta: {
|
|
21019
|
+
supportsProject: true,
|
|
21020
|
+
supportsGlobal: true,
|
|
21021
|
+
supportsEnabledTools: true,
|
|
21022
|
+
supportsDisabledTools: true
|
|
21023
|
+
}
|
|
21024
|
+
}],
|
|
20382
21025
|
["kilo", {
|
|
20383
21026
|
class: KiloMcp,
|
|
20384
21027
|
meta: {
|
|
@@ -20394,7 +21037,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20394
21037
|
supportsProject: true,
|
|
20395
21038
|
supportsGlobal: true,
|
|
20396
21039
|
supportsEnabledTools: false,
|
|
20397
|
-
supportsDisabledTools:
|
|
21040
|
+
supportsDisabledTools: true
|
|
20398
21041
|
}
|
|
20399
21042
|
}],
|
|
20400
21043
|
["kiro-cli", {
|
|
@@ -20403,7 +21046,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20403
21046
|
supportsProject: true,
|
|
20404
21047
|
supportsGlobal: true,
|
|
20405
21048
|
supportsEnabledTools: false,
|
|
20406
|
-
supportsDisabledTools:
|
|
21049
|
+
supportsDisabledTools: true
|
|
20407
21050
|
}
|
|
20408
21051
|
}],
|
|
20409
21052
|
["kiro-ide", {
|
|
@@ -20412,7 +21055,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20412
21055
|
supportsProject: true,
|
|
20413
21056
|
supportsGlobal: true,
|
|
20414
21057
|
supportsEnabledTools: false,
|
|
20415
|
-
supportsDisabledTools:
|
|
21058
|
+
supportsDisabledTools: true
|
|
20416
21059
|
}
|
|
20417
21060
|
}],
|
|
20418
21061
|
["junie", {
|
|
@@ -22979,7 +23622,7 @@ function mergeFilesystemCategoryRules({ categoryRules, logger }) {
|
|
|
22979
23622
|
function buildCodexBashRulesContent(config) {
|
|
22980
23623
|
const bashRules = config.permission.bash ?? {};
|
|
22981
23624
|
const entries = Object.entries(bashRules);
|
|
22982
|
-
const header = ["# Generated by Rulesync from .rulesync/permissions.
|
|
23625
|
+
const header = ["# Generated by Rulesync from .rulesync/permissions.jsonc (permission.bash)", "# https://developers.openai.com/codex/rules"];
|
|
22983
23626
|
if (entries.length === 0) return [...header, "# No bash permission rules were configured."].join("\n");
|
|
22984
23627
|
const ruleBlocks = entries.map(([pattern, action]) => {
|
|
22985
23628
|
const tokens = toCommandPatternTokens(pattern);
|
|
@@ -24439,8 +25082,9 @@ var HermesagentPermissions = class HermesagentPermissions extends ToolPermission
|
|
|
24439
25082
|
});
|
|
24440
25083
|
const permissions = config.permissions && typeof config.permissions === "object" ? config.permissions.rulesync : {};
|
|
24441
25084
|
return new RulesyncPermissions({
|
|
24442
|
-
|
|
24443
|
-
|
|
25085
|
+
outputRoot: this.outputRoot,
|
|
25086
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
25087
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
24444
25088
|
fileContent: JSON.stringify(permissions ?? {}, null, 2)
|
|
24445
25089
|
});
|
|
24446
25090
|
}
|
|
@@ -24862,7 +25506,7 @@ var KiloPermissions = class KiloPermissions extends ToolPermissions {
|
|
|
24862
25506
|
}
|
|
24863
25507
|
if (Object.keys(droppedDenyByKey).length > 0) {
|
|
24864
25508
|
const summary = Object.entries(droppedDenyByKey).map(([key, patterns]) => `${key}: [${patterns.join(", ")}]`).join("; ");
|
|
24865
|
-
logger?.warn(`WARNING: Kilo permissions regeneration drops existing 'deny' rule(s) because rulesync output owns these tool keys. Dropped — ${summary}. To preserve these denies, add them to '.rulesync/permissions.
|
|
25509
|
+
logger?.warn(`WARNING: Kilo permissions regeneration drops existing 'deny' rule(s) because rulesync output owns these tool keys. Dropped — ${summary}. To preserve these denies, add them to '.rulesync/permissions.jsonc'.`);
|
|
24866
25510
|
}
|
|
24867
25511
|
const mergedPermission = {
|
|
24868
25512
|
...existingPermission,
|
|
@@ -24922,6 +25566,227 @@ var KiloPermissions = class KiloPermissions extends ToolPermissions {
|
|
|
24922
25566
|
}
|
|
24923
25567
|
};
|
|
24924
25568
|
//#endregion
|
|
25569
|
+
//#region src/features/permissions/kimi-code-permissions.ts
|
|
25570
|
+
const CATEGORY_TO_KIMI_CODE_TOOL = {
|
|
25571
|
+
bash: "Bash",
|
|
25572
|
+
read: "Read",
|
|
25573
|
+
write: "Write",
|
|
25574
|
+
edit: "Edit",
|
|
25575
|
+
grep: "Grep",
|
|
25576
|
+
glob: "Glob",
|
|
25577
|
+
websearch: "WebSearch",
|
|
25578
|
+
webfetch: "FetchURL",
|
|
25579
|
+
agent: "Agent"
|
|
25580
|
+
};
|
|
25581
|
+
function buildKimiCodePattern(category, pattern) {
|
|
25582
|
+
if (category.startsWith("mcp__")) return pattern === "*" || pattern === "" ? category : null;
|
|
25583
|
+
if (category === "mcp") return pattern === "*" || pattern === "" ? "mcp__*" : `mcp__${pattern}`;
|
|
25584
|
+
const tool = CATEGORY_TO_KIMI_CODE_TOOL[category];
|
|
25585
|
+
if (!tool) return null;
|
|
25586
|
+
return pattern === "*" || pattern === "" ? tool : `${tool}(${pattern})`;
|
|
25587
|
+
}
|
|
25588
|
+
function canonicalToKimiCodeRules({ config, logger }) {
|
|
25589
|
+
const canonicalRules = [];
|
|
25590
|
+
const overrideRules = config["kimi-code"]?.rules ?? [];
|
|
25591
|
+
for (const [category, rules] of Object.entries(config.permission)) {
|
|
25592
|
+
if (!(category === "mcp" || category.startsWith("mcp__") || CATEGORY_TO_KIMI_CODE_TOOL[category] !== void 0)) {
|
|
25593
|
+
if (Object.keys(rules).length > 0) logger?.warn(`Kimi Code permissions: skipping unsupported category "${category}".`);
|
|
25594
|
+
continue;
|
|
25595
|
+
}
|
|
25596
|
+
for (const [pattern, decision] of Object.entries(rules)) {
|
|
25597
|
+
if (category.startsWith("mcp__") && pattern !== "*" && pattern !== "") {
|
|
25598
|
+
if (decision === "deny") {
|
|
25599
|
+
logger?.warn(`Kimi Code permissions: broadening argument-specific deny for "${category}" to the whole MCP tool because Kimi does not match MCP tool arguments.`);
|
|
25600
|
+
canonicalRules.push({
|
|
25601
|
+
decision,
|
|
25602
|
+
pattern: category,
|
|
25603
|
+
scope: "user"
|
|
25604
|
+
});
|
|
25605
|
+
} else logger?.warn(`Kimi Code permissions: skipping argument-specific ${decision} for "${category}" because Kimi does not match MCP tool arguments.`);
|
|
25606
|
+
continue;
|
|
25607
|
+
}
|
|
25608
|
+
const kimiCodePattern = buildKimiCodePattern(category, pattern);
|
|
25609
|
+
if (!kimiCodePattern) continue;
|
|
25610
|
+
canonicalRules.push({
|
|
25611
|
+
decision,
|
|
25612
|
+
pattern: kimiCodePattern,
|
|
25613
|
+
scope: "user"
|
|
25614
|
+
});
|
|
25615
|
+
}
|
|
25616
|
+
}
|
|
25617
|
+
return [...overrideRules, ...sortKimiCodeRulesFailClosed(canonicalRules)];
|
|
25618
|
+
}
|
|
25619
|
+
function getKimiCodePatternSpecificity(pattern) {
|
|
25620
|
+
const opening = pattern.indexOf("(");
|
|
25621
|
+
const hasArguments = opening >= 0 && pattern.endsWith(")");
|
|
25622
|
+
const tool = hasArguments ? pattern.slice(0, opening) : pattern;
|
|
25623
|
+
const argument = hasArguments ? pattern.slice(opening + 1, -1) : "";
|
|
25624
|
+
return {
|
|
25625
|
+
tool,
|
|
25626
|
+
toolLiteralLength: tool.replaceAll("*", "").replaceAll("?", "").length,
|
|
25627
|
+
toolWildcardCount: [...tool].filter((character) => "*?".includes(character)).length,
|
|
25628
|
+
literalLength: argument.replaceAll("*", "").replaceAll("?", "").replaceAll("[", "").replaceAll("]", "").length,
|
|
25629
|
+
wildcardCount: [...argument].filter((character) => "*?[]".includes(character)).length,
|
|
25630
|
+
hasArguments
|
|
25631
|
+
};
|
|
25632
|
+
}
|
|
25633
|
+
function sortKimiCodeRulesFailClosed(rules) {
|
|
25634
|
+
const actionPriority = {
|
|
25635
|
+
deny: 0,
|
|
25636
|
+
ask: 1,
|
|
25637
|
+
allow: 2
|
|
25638
|
+
};
|
|
25639
|
+
return rules.map((rule, index) => ({
|
|
25640
|
+
rule,
|
|
25641
|
+
index,
|
|
25642
|
+
specificity: getKimiCodePatternSpecificity(rule.pattern)
|
|
25643
|
+
})).toSorted((left, right) => {
|
|
25644
|
+
const actionOrder = actionPriority[left.rule.decision] - actionPriority[right.rule.decision];
|
|
25645
|
+
if (actionOrder !== 0) return actionOrder;
|
|
25646
|
+
if (left.specificity.tool.startsWith("mcp__") && right.specificity.tool.startsWith("mcp__")) {
|
|
25647
|
+
const toolLiteralOrder = right.specificity.toolLiteralLength - left.specificity.toolLiteralLength;
|
|
25648
|
+
if (toolLiteralOrder !== 0) return toolLiteralOrder;
|
|
25649
|
+
const toolWildcardOrder = left.specificity.toolWildcardCount - right.specificity.toolWildcardCount;
|
|
25650
|
+
if (toolWildcardOrder !== 0) return toolWildcardOrder;
|
|
25651
|
+
}
|
|
25652
|
+
const toolOrder = left.specificity.tool.localeCompare(right.specificity.tool);
|
|
25653
|
+
if (toolOrder !== 0) return toolOrder;
|
|
25654
|
+
if (left.specificity.hasArguments !== right.specificity.hasArguments) return left.specificity.hasArguments ? -1 : 1;
|
|
25655
|
+
const literalOrder = right.specificity.literalLength - left.specificity.literalLength;
|
|
25656
|
+
if (literalOrder !== 0) return literalOrder;
|
|
25657
|
+
const wildcardOrder = left.specificity.wildcardCount - right.specificity.wildcardCount;
|
|
25658
|
+
if (wildcardOrder !== 0) return wildcardOrder;
|
|
25659
|
+
return left.index - right.index;
|
|
25660
|
+
}).map(({ rule }) => rule);
|
|
25661
|
+
}
|
|
25662
|
+
function preserveKimiCodeRules(rules) {
|
|
25663
|
+
const permission = {};
|
|
25664
|
+
const nativeRules = [];
|
|
25665
|
+
if (!Array.isArray(rules)) return {
|
|
25666
|
+
permission,
|
|
25667
|
+
nativeRules
|
|
25668
|
+
};
|
|
25669
|
+
for (const raw of rules) {
|
|
25670
|
+
if (!isRecord(raw)) continue;
|
|
25671
|
+
const decision = raw.decision;
|
|
25672
|
+
const pattern = raw.pattern;
|
|
25673
|
+
if (decision !== "allow" && decision !== "ask" && decision !== "deny" || typeof pattern !== "string") continue;
|
|
25674
|
+
nativeRules.push({
|
|
25675
|
+
decision,
|
|
25676
|
+
pattern,
|
|
25677
|
+
...typeof raw.scope === "string" && { scope: raw.scope },
|
|
25678
|
+
...typeof raw.reason === "string" && { reason: raw.reason }
|
|
25679
|
+
});
|
|
25680
|
+
}
|
|
25681
|
+
return {
|
|
25682
|
+
permission,
|
|
25683
|
+
nativeRules
|
|
25684
|
+
};
|
|
25685
|
+
}
|
|
25686
|
+
/**
|
|
25687
|
+
* Kimi Code permission rules in the shared user `config.toml`.
|
|
25688
|
+
*
|
|
25689
|
+
* @see https://moonshotai.github.io/kimi-code/en/configuration/config-files.html
|
|
25690
|
+
*/
|
|
25691
|
+
var KimiCodePermissions = class KimiCodePermissions extends ToolPermissions {
|
|
25692
|
+
constructor(params) {
|
|
25693
|
+
super({
|
|
25694
|
+
...params,
|
|
25695
|
+
...KimiCodePermissions.getSettablePaths({ global: params.global ?? true })
|
|
25696
|
+
});
|
|
25697
|
+
}
|
|
25698
|
+
static getSettablePaths({ global = true } = {}) {
|
|
25699
|
+
return {
|
|
25700
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
25701
|
+
relativeFilePath: KIMI_CODE_CONFIG_FILE_NAME
|
|
25702
|
+
};
|
|
25703
|
+
}
|
|
25704
|
+
validate() {
|
|
25705
|
+
return {
|
|
25706
|
+
success: true,
|
|
25707
|
+
error: null
|
|
25708
|
+
};
|
|
25709
|
+
}
|
|
25710
|
+
isDeletable() {
|
|
25711
|
+
return false;
|
|
25712
|
+
}
|
|
25713
|
+
shouldMergeExistingFileContent() {
|
|
25714
|
+
return true;
|
|
25715
|
+
}
|
|
25716
|
+
setFileContent(fileContent) {
|
|
25717
|
+
const paths = KimiCodePermissions.getSettablePaths({ global: this.global });
|
|
25718
|
+
this.fileContent = applySharedConfigPatch({
|
|
25719
|
+
fileKey: KIMI_CODE_CONFIG_SHARED_FILE_KEY,
|
|
25720
|
+
feature: "permissions",
|
|
25721
|
+
existingContent: fileContent,
|
|
25722
|
+
patch: parseSharedConfig({
|
|
25723
|
+
format: "toml",
|
|
25724
|
+
fileContent: this.fileContent
|
|
25725
|
+
}),
|
|
25726
|
+
filePath: (0, node_path.join)(paths.relativeDirPath, paths.relativeFilePath)
|
|
25727
|
+
});
|
|
25728
|
+
}
|
|
25729
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = true }) {
|
|
25730
|
+
const paths = this.getSettablePaths({ global });
|
|
25731
|
+
return new KimiCodePermissions({
|
|
25732
|
+
outputRoot,
|
|
25733
|
+
fileContent: await readFileContent((0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath)),
|
|
25734
|
+
validate,
|
|
25735
|
+
global
|
|
25736
|
+
});
|
|
25737
|
+
}
|
|
25738
|
+
static fromRulesyncPermissions({ outputRoot, rulesyncPermissions, logger }) {
|
|
25739
|
+
const config = rulesyncPermissions.getJson();
|
|
25740
|
+
const defaultPermissionMode = config["kimi-code"]?.defaultPermissionMode;
|
|
25741
|
+
return new KimiCodePermissions({
|
|
25742
|
+
outputRoot,
|
|
25743
|
+
fileContent: stringifySharedConfig({
|
|
25744
|
+
format: "toml",
|
|
25745
|
+
document: {
|
|
25746
|
+
...defaultPermissionMode && { default_permission_mode: defaultPermissionMode },
|
|
25747
|
+
permission: { rules: canonicalToKimiCodeRules({
|
|
25748
|
+
config,
|
|
25749
|
+
logger
|
|
25750
|
+
}) }
|
|
25751
|
+
}
|
|
25752
|
+
}),
|
|
25753
|
+
global: true
|
|
25754
|
+
});
|
|
25755
|
+
}
|
|
25756
|
+
toRulesyncPermissions() {
|
|
25757
|
+
const config = parseSharedConfig({
|
|
25758
|
+
format: "toml",
|
|
25759
|
+
fileContent: this.getFileContent()
|
|
25760
|
+
});
|
|
25761
|
+
const { permission, nativeRules } = preserveKimiCodeRules((isRecord(config.permission) ? config.permission : {}).rules);
|
|
25762
|
+
const defaultPermissionMode = config.default_permission_mode;
|
|
25763
|
+
const toolOverride = {
|
|
25764
|
+
...defaultPermissionMode === "manual" || defaultPermissionMode === "yolo" || defaultPermissionMode === "auto" ? { defaultPermissionMode } : {},
|
|
25765
|
+
...nativeRules.length > 0 && { rules: nativeRules }
|
|
25766
|
+
};
|
|
25767
|
+
return new RulesyncPermissions({
|
|
25768
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
25769
|
+
nativeOutputRoot: this.outputRoot,
|
|
25770
|
+
global: this.global
|
|
25771
|
+
}),
|
|
25772
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
25773
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
25774
|
+
fileContent: JSON.stringify({
|
|
25775
|
+
permission,
|
|
25776
|
+
...Object.keys(toolOverride).length > 0 && { "kimi-code": toolOverride }
|
|
25777
|
+
}, null, 2)
|
|
25778
|
+
});
|
|
25779
|
+
}
|
|
25780
|
+
static forDeletion({ outputRoot = process.cwd() }) {
|
|
25781
|
+
return new KimiCodePermissions({
|
|
25782
|
+
outputRoot,
|
|
25783
|
+
fileContent: "",
|
|
25784
|
+
validate: false,
|
|
25785
|
+
global: true
|
|
25786
|
+
});
|
|
25787
|
+
}
|
|
25788
|
+
};
|
|
25789
|
+
//#endregion
|
|
24925
25790
|
//#region src/features/permissions/kiro-permissions.ts
|
|
24926
25791
|
const KiroAgentSchema = zod_mini.z.looseObject({
|
|
24927
25792
|
allowedTools: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string())),
|
|
@@ -27137,6 +28002,14 @@ const toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
|
27137
28002
|
supportsImport: true
|
|
27138
28003
|
}
|
|
27139
28004
|
}],
|
|
28005
|
+
["kimi-code", {
|
|
28006
|
+
class: KimiCodePermissions,
|
|
28007
|
+
meta: {
|
|
28008
|
+
supportsProject: false,
|
|
28009
|
+
supportsGlobal: true,
|
|
28010
|
+
supportsImport: true
|
|
28011
|
+
}
|
|
28012
|
+
}],
|
|
27140
28013
|
["junie", {
|
|
27141
28014
|
class: JuniePermissions,
|
|
27142
28015
|
meta: {
|
|
@@ -28230,6 +29103,17 @@ var AntigravityIdeSkill = class extends AntigravitySharedSkill {
|
|
|
28230
29103
|
}
|
|
28231
29104
|
};
|
|
28232
29105
|
//#endregion
|
|
29106
|
+
//#region src/features/skills/antigravity-plugin-skill.ts
|
|
29107
|
+
var AntigravityPluginSkill = class extends AntigravityIdeSkill {
|
|
29108
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
29109
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
29110
|
+
return targets.includes("*") || targets.includes("antigravity-plugin");
|
|
29111
|
+
}
|
|
29112
|
+
static getSettablePaths() {
|
|
29113
|
+
return { relativeDirPath: ANTIGRAVITY_PLUGIN_SKILLS_DIR };
|
|
29114
|
+
}
|
|
29115
|
+
};
|
|
29116
|
+
//#endregion
|
|
28233
29117
|
//#region src/features/skills/augmentcode-skill.ts
|
|
28234
29118
|
const AugmentcodeSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
28235
29119
|
name: zod_mini.z.string(),
|
|
@@ -28424,7 +29308,7 @@ function buildClaudecodeSkillFrontmatter({ rulesyncFrontmatter, resolvedDisableM
|
|
|
28424
29308
|
* Unlike subagents and commands, skills are directories containing SKILL.md and other files.
|
|
28425
29309
|
* Extends ToolSkill to inherit directory management and security features from AiDir.
|
|
28426
29310
|
*/
|
|
28427
|
-
var ClaudecodeSkill = class
|
|
29311
|
+
var ClaudecodeSkill = class extends ToolSkill {
|
|
28428
29312
|
constructor({ outputRoot = process.cwd(), relativeDirPath = CLAUDECODE_SKILLS_DIR_PATH, dirName, frontmatter, body, otherFiles = [], validate = true, global = false }) {
|
|
28429
29313
|
super({
|
|
28430
29314
|
outputRoot,
|
|
@@ -28519,9 +29403,9 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28519
29403
|
section: rulesyncFrontmatter.claudecode
|
|
28520
29404
|
})
|
|
28521
29405
|
});
|
|
28522
|
-
const settablePaths =
|
|
29406
|
+
const settablePaths = this.getSettablePaths({ global });
|
|
28523
29407
|
const relativeDirPath = rulesyncFrontmatter.claudecode?.["scheduled-task"] ? CLAUDECODE_SCHEDULED_TASKS_DIR_PATH : settablePaths.relativeDirPath;
|
|
28524
|
-
return new
|
|
29408
|
+
return new this({
|
|
28525
29409
|
outputRoot,
|
|
28526
29410
|
relativeDirPath,
|
|
28527
29411
|
dirName: rulesyncSkill.getDirName(),
|
|
@@ -28541,14 +29425,14 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28541
29425
|
static async fromDir(params) {
|
|
28542
29426
|
const loaded = await this.loadSkillDirContent({
|
|
28543
29427
|
...params,
|
|
28544
|
-
getSettablePaths:
|
|
29428
|
+
getSettablePaths: (options) => this.getSettablePaths(options)
|
|
28545
29429
|
});
|
|
28546
29430
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28547
29431
|
if (!result.success) {
|
|
28548
29432
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28549
29433
|
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28550
29434
|
}
|
|
28551
|
-
return new
|
|
29435
|
+
return new this({
|
|
28552
29436
|
outputRoot: loaded.outputRoot,
|
|
28553
29437
|
relativeDirPath: loaded.relativeDirPath,
|
|
28554
29438
|
dirName: loaded.dirName,
|
|
@@ -28560,7 +29444,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28560
29444
|
});
|
|
28561
29445
|
}
|
|
28562
29446
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
28563
|
-
return new
|
|
29447
|
+
return new this({
|
|
28564
29448
|
outputRoot,
|
|
28565
29449
|
relativeDirPath,
|
|
28566
29450
|
dirName,
|
|
@@ -28576,6 +29460,17 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28576
29460
|
}
|
|
28577
29461
|
};
|
|
28578
29462
|
//#endregion
|
|
29463
|
+
//#region src/features/skills/claudecode-plugin-skill.ts
|
|
29464
|
+
var ClaudecodePluginSkill = class extends ClaudecodeSkill {
|
|
29465
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
29466
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
29467
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
29468
|
+
}
|
|
29469
|
+
static getSettablePaths() {
|
|
29470
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_SKILLS_DIR };
|
|
29471
|
+
}
|
|
29472
|
+
};
|
|
29473
|
+
//#endregion
|
|
28579
29474
|
//#region src/features/skills/cline-skill.ts
|
|
28580
29475
|
const ClineSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
28581
29476
|
name: zod_mini.z.string(),
|
|
@@ -30365,6 +31260,197 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
30365
31260
|
}
|
|
30366
31261
|
};
|
|
30367
31262
|
//#endregion
|
|
31263
|
+
//#region src/features/skills/kimi-code-skill.ts
|
|
31264
|
+
const KimiCodeSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
31265
|
+
name: zod_mini.z.string(),
|
|
31266
|
+
description: zod_mini.z.string(),
|
|
31267
|
+
type: zod_mini.z.optional(zod_mini.z.enum([
|
|
31268
|
+
"prompt",
|
|
31269
|
+
"inline",
|
|
31270
|
+
"flow"
|
|
31271
|
+
])),
|
|
31272
|
+
whenToUse: zod_mini.z.optional(zod_mini.z.string()),
|
|
31273
|
+
disableModelInvocation: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
31274
|
+
arguments: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())]))
|
|
31275
|
+
});
|
|
31276
|
+
const KimiCodeFlatSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
31277
|
+
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
31278
|
+
description: zod_mini.z.optional(zod_mini.z.string()),
|
|
31279
|
+
type: zod_mini.z.optional(zod_mini.z.enum([
|
|
31280
|
+
"prompt",
|
|
31281
|
+
"inline",
|
|
31282
|
+
"flow"
|
|
31283
|
+
])),
|
|
31284
|
+
whenToUse: zod_mini.z.optional(zod_mini.z.string()),
|
|
31285
|
+
disableModelInvocation: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
31286
|
+
arguments: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())]))
|
|
31287
|
+
});
|
|
31288
|
+
function logicalSkillDirName(name) {
|
|
31289
|
+
const normalized = name.toLowerCase();
|
|
31290
|
+
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(normalized) ? normalized : `kimi-${encodeURIComponent(normalized)}`;
|
|
31291
|
+
}
|
|
31292
|
+
/**
|
|
31293
|
+
* Kimi Code Agent Skill.
|
|
31294
|
+
*
|
|
31295
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/skills.html
|
|
31296
|
+
*/
|
|
31297
|
+
var KimiCodeSkill = class KimiCodeSkill extends ToolSkill {
|
|
31298
|
+
constructor({ outputRoot = process.cwd(), relativeDirPath = KIMI_CODE_SKILLS_DIR_PATH, dirName, frontmatter, body, otherFiles = [], validate = true, global = false }) {
|
|
31299
|
+
super({
|
|
31300
|
+
outputRoot,
|
|
31301
|
+
relativeDirPath,
|
|
31302
|
+
dirName,
|
|
31303
|
+
mainFile: {
|
|
31304
|
+
name: SKILL_FILE_NAME,
|
|
31305
|
+
body,
|
|
31306
|
+
frontmatter: { ...frontmatter }
|
|
31307
|
+
},
|
|
31308
|
+
otherFiles,
|
|
31309
|
+
global
|
|
31310
|
+
});
|
|
31311
|
+
if (validate) {
|
|
31312
|
+
const result = this.validate();
|
|
31313
|
+
if (!result.success) throw result.error;
|
|
31314
|
+
}
|
|
31315
|
+
}
|
|
31316
|
+
static getSettablePaths({ global = false } = {}) {
|
|
31317
|
+
const customHome = global ? getKimiCodeHome() : void 0;
|
|
31318
|
+
return {
|
|
31319
|
+
relativeDirPath: getKimiCodeRelativeDirPath({
|
|
31320
|
+
global,
|
|
31321
|
+
relativeDirPath: KIMI_CODE_SKILLS_DIR_NAME
|
|
31322
|
+
}),
|
|
31323
|
+
importOnlySkillRoots: [customHome ? {
|
|
31324
|
+
outputRoot: getHomeDirectory(),
|
|
31325
|
+
relativeDirPath: KIMI_CODE_SHARED_SKILLS_DIR_PATH
|
|
31326
|
+
} : KIMI_CODE_SHARED_SKILLS_DIR_PATH]
|
|
31327
|
+
};
|
|
31328
|
+
}
|
|
31329
|
+
getFrontmatter() {
|
|
31330
|
+
return KimiCodeSkillFrontmatterSchema.parse(this.requireMainFileFrontmatter());
|
|
31331
|
+
}
|
|
31332
|
+
getBody() {
|
|
31333
|
+
return this.mainFile?.body ?? "";
|
|
31334
|
+
}
|
|
31335
|
+
getImportIdentity() {
|
|
31336
|
+
return this.getFrontmatter().name.toLowerCase();
|
|
31337
|
+
}
|
|
31338
|
+
validate() {
|
|
31339
|
+
if (!this.mainFile) return {
|
|
31340
|
+
success: false,
|
|
31341
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
31342
|
+
};
|
|
31343
|
+
const result = KimiCodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
31344
|
+
return result.success ? {
|
|
31345
|
+
success: true,
|
|
31346
|
+
error: null
|
|
31347
|
+
} : {
|
|
31348
|
+
success: false,
|
|
31349
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`)
|
|
31350
|
+
};
|
|
31351
|
+
}
|
|
31352
|
+
toRulesyncSkill() {
|
|
31353
|
+
const { name, description, disableModelInvocation, ...kimiCodeFrontmatter } = this.getFrontmatter();
|
|
31354
|
+
const toolSection = {
|
|
31355
|
+
...kimiCodeFrontmatter,
|
|
31356
|
+
...disableModelInvocation !== void 0 && { disableModelInvocation }
|
|
31357
|
+
};
|
|
31358
|
+
const frontmatter = {
|
|
31359
|
+
name,
|
|
31360
|
+
description,
|
|
31361
|
+
targets: ["*"],
|
|
31362
|
+
...disableModelInvocation !== void 0 && { "disable-model-invocation": disableModelInvocation },
|
|
31363
|
+
...Object.keys(toolSection).length > 0 && { "kimi-code": toolSection }
|
|
31364
|
+
};
|
|
31365
|
+
return new RulesyncSkill({
|
|
31366
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
31367
|
+
nativeOutputRoot: this.outputRoot,
|
|
31368
|
+
global: this.global
|
|
31369
|
+
}),
|
|
31370
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
31371
|
+
dirName: logicalSkillDirName(name),
|
|
31372
|
+
frontmatter,
|
|
31373
|
+
body: this.getBody(),
|
|
31374
|
+
otherFiles: this.getOtherFiles(),
|
|
31375
|
+
validate: true,
|
|
31376
|
+
global: this.global
|
|
31377
|
+
});
|
|
31378
|
+
}
|
|
31379
|
+
static fromRulesyncSkill({ outputRoot = process.cwd(), rulesyncSkill, validate = true, global = false }) {
|
|
31380
|
+
const frontmatter = rulesyncSkill.getFrontmatter();
|
|
31381
|
+
const kimiCodeSection = frontmatter["kimi-code"] ?? {};
|
|
31382
|
+
const kimiCodeFrontmatter = {
|
|
31383
|
+
name: frontmatter.name,
|
|
31384
|
+
description: frontmatter.description,
|
|
31385
|
+
...frontmatter["disable-model-invocation"] !== void 0 && { disableModelInvocation: frontmatter["disable-model-invocation"] },
|
|
31386
|
+
...kimiCodeSection
|
|
31387
|
+
};
|
|
31388
|
+
return new KimiCodeSkill({
|
|
31389
|
+
outputRoot,
|
|
31390
|
+
relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
|
|
31391
|
+
dirName: rulesyncSkill.getDirName(),
|
|
31392
|
+
frontmatter: kimiCodeFrontmatter,
|
|
31393
|
+
body: rulesyncSkill.getBody(),
|
|
31394
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
31395
|
+
validate,
|
|
31396
|
+
global
|
|
31397
|
+
});
|
|
31398
|
+
}
|
|
31399
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
31400
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
31401
|
+
return targets.includes("*") || targets.includes("kimi-code");
|
|
31402
|
+
}
|
|
31403
|
+
static async fromDir(params) {
|
|
31404
|
+
const loaded = await this.loadSkillDirContent({
|
|
31405
|
+
...params,
|
|
31406
|
+
getSettablePaths: KimiCodeSkill.getSettablePaths
|
|
31407
|
+
});
|
|
31408
|
+
const result = KimiCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
31409
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
31410
|
+
return new KimiCodeSkill({
|
|
31411
|
+
...loaded,
|
|
31412
|
+
frontmatter: result.data,
|
|
31413
|
+
validate: true
|
|
31414
|
+
});
|
|
31415
|
+
}
|
|
31416
|
+
static async fromFlatFile({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
31417
|
+
const filePath = (0, node_path.join)(outputRoot, relativeDirPath, relativeFilePath);
|
|
31418
|
+
const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
31419
|
+
const result = KimiCodeFlatSkillFrontmatterSchema.safeParse(frontmatter);
|
|
31420
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
31421
|
+
const fileName = (0, node_path.basename)(relativeFilePath, (0, node_path.extname)(relativeFilePath));
|
|
31422
|
+
const firstBodyLine = body.split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "");
|
|
31423
|
+
const normalizedFrontmatter = {
|
|
31424
|
+
...result.data,
|
|
31425
|
+
name: result.data.name ?? fileName,
|
|
31426
|
+
description: result.data.description ?? firstBodyLine?.slice(0, 240) ?? "No description provided."
|
|
31427
|
+
};
|
|
31428
|
+
return new KimiCodeSkill({
|
|
31429
|
+
outputRoot,
|
|
31430
|
+
relativeDirPath,
|
|
31431
|
+
dirName: fileName,
|
|
31432
|
+
frontmatter: normalizedFrontmatter,
|
|
31433
|
+
body: body.trim(),
|
|
31434
|
+
validate: true,
|
|
31435
|
+
global
|
|
31436
|
+
});
|
|
31437
|
+
}
|
|
31438
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
31439
|
+
return new KimiCodeSkill({
|
|
31440
|
+
outputRoot,
|
|
31441
|
+
relativeDirPath: relativeDirPath ?? this.getSettablePaths({ global }).relativeDirPath,
|
|
31442
|
+
dirName,
|
|
31443
|
+
frontmatter: {
|
|
31444
|
+
name: "",
|
|
31445
|
+
description: ""
|
|
31446
|
+
},
|
|
31447
|
+
body: "",
|
|
31448
|
+
validate: false,
|
|
31449
|
+
global
|
|
31450
|
+
});
|
|
31451
|
+
}
|
|
31452
|
+
};
|
|
31453
|
+
//#endregion
|
|
30368
31454
|
//#region src/features/skills/kiro-skill.ts
|
|
30369
31455
|
const KiroSkillFrontmatterSchema = zod_mini.z.looseObject({
|
|
30370
31456
|
name: zod_mini.z.string(),
|
|
@@ -32091,6 +33177,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32091
33177
|
supportsGlobal: true
|
|
32092
33178
|
}
|
|
32093
33179
|
}],
|
|
33180
|
+
["antigravity-plugin", {
|
|
33181
|
+
class: AntigravityPluginSkill,
|
|
33182
|
+
meta: {
|
|
33183
|
+
supportsProject: true,
|
|
33184
|
+
supportsSimulated: false,
|
|
33185
|
+
supportsGlobal: false
|
|
33186
|
+
}
|
|
33187
|
+
}],
|
|
32094
33188
|
["augmentcode", {
|
|
32095
33189
|
class: AugmentcodeSkill,
|
|
32096
33190
|
meta: {
|
|
@@ -32107,6 +33201,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32107
33201
|
supportsGlobal: true
|
|
32108
33202
|
}
|
|
32109
33203
|
}],
|
|
33204
|
+
["claudecode-plugin", {
|
|
33205
|
+
class: ClaudecodePluginSkill,
|
|
33206
|
+
meta: {
|
|
33207
|
+
supportsProject: true,
|
|
33208
|
+
supportsSimulated: false,
|
|
33209
|
+
supportsGlobal: false
|
|
33210
|
+
}
|
|
33211
|
+
}],
|
|
32110
33212
|
["claudecode-legacy", {
|
|
32111
33213
|
class: ClaudecodeSkill,
|
|
32112
33214
|
meta: {
|
|
@@ -32211,6 +33313,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32211
33313
|
supportsGlobal: true
|
|
32212
33314
|
}
|
|
32213
33315
|
}],
|
|
33316
|
+
["kimi-code", {
|
|
33317
|
+
class: KimiCodeSkill,
|
|
33318
|
+
meta: {
|
|
33319
|
+
supportsProject: true,
|
|
33320
|
+
supportsSimulated: false,
|
|
33321
|
+
supportsGlobal: true
|
|
33322
|
+
}
|
|
33323
|
+
}],
|
|
32214
33324
|
["kiro", {
|
|
32215
33325
|
class: KiroSkill,
|
|
32216
33326
|
meta: {
|
|
@@ -32432,36 +33542,56 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
32432
33542
|
*/
|
|
32433
33543
|
async loadToolDirs() {
|
|
32434
33544
|
const factory = this.getFactory(this.toolTarget);
|
|
32435
|
-
const roots =
|
|
32436
|
-
const
|
|
32437
|
-
const
|
|
33545
|
+
const roots = toolSkillImportRoots(factory.class.getSettablePaths({ global: this.global }));
|
|
33546
|
+
const seenSkillNames = /* @__PURE__ */ new Set();
|
|
33547
|
+
const toolSkills = [];
|
|
32438
33548
|
for (const root of roots) {
|
|
32439
|
-
const
|
|
33549
|
+
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
33550
|
+
const relativeDirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
33551
|
+
const skillsDirPath = (0, node_path.join)(rootOutputRoot, relativeDirPath);
|
|
32440
33552
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
32441
33553
|
const dirPaths = await findFilesByGlobs((0, node_path.join)(skillsDirPath, "*"), { type: "dir" });
|
|
33554
|
+
const ownedDirNames = [];
|
|
32442
33555
|
for (const dirPath of dirPaths) {
|
|
32443
33556
|
const dirName = (0, node_path.basename)(dirPath);
|
|
32444
|
-
if (seenDirNames.has(dirName)) continue;
|
|
32445
33557
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
32446
|
-
outputRoot:
|
|
32447
|
-
relativeDirPath
|
|
33558
|
+
outputRoot: rootOutputRoot,
|
|
33559
|
+
relativeDirPath,
|
|
32448
33560
|
dirName,
|
|
32449
33561
|
inputRoot: this.inputRoot
|
|
32450
33562
|
})) continue;
|
|
32451
|
-
|
|
32452
|
-
|
|
32453
|
-
|
|
32454
|
-
|
|
32455
|
-
|
|
33563
|
+
ownedDirNames.push(dirName);
|
|
33564
|
+
}
|
|
33565
|
+
const directorySkills = await Promise.all(ownedDirNames.map((dirName) => factory.class.fromDir({
|
|
33566
|
+
outputRoot: rootOutputRoot,
|
|
33567
|
+
relativeDirPath,
|
|
33568
|
+
dirName,
|
|
33569
|
+
global: this.global
|
|
33570
|
+
})));
|
|
33571
|
+
for (const skill of directorySkills) {
|
|
33572
|
+
const skillName = skill.getImportIdentity();
|
|
33573
|
+
if (seenSkillNames.has(skillName)) continue;
|
|
33574
|
+
seenSkillNames.add(skillName);
|
|
33575
|
+
toolSkills.push(skill);
|
|
33576
|
+
}
|
|
33577
|
+
if (!factory.class.fromFlatFile) continue;
|
|
33578
|
+
const fromFlatFile = factory.class.fromFlatFile;
|
|
33579
|
+
const directoryStems = new Set(ownedDirNames);
|
|
33580
|
+
const flatFilePaths = (await findFilesByGlobs((0, node_path.join)(skillsDirPath, "*.md"), { type: "file" })).filter((filePath) => !directoryStems.has((0, node_path.basename)(filePath, ".md")));
|
|
33581
|
+
const flatSkills = await Promise.all(flatFilePaths.map((filePath) => fromFlatFile({
|
|
33582
|
+
outputRoot: rootOutputRoot,
|
|
33583
|
+
relativeDirPath,
|
|
33584
|
+
relativeFilePath: (0, node_path.basename)(filePath),
|
|
33585
|
+
global: this.global
|
|
33586
|
+
})));
|
|
33587
|
+
for (const skill of flatSkills) {
|
|
33588
|
+
const skillName = skill.getImportIdentity();
|
|
33589
|
+
if (seenSkillNames.has(skillName)) continue;
|
|
33590
|
+
seenSkillNames.add(skillName);
|
|
33591
|
+
toolSkills.push(skill);
|
|
32456
33592
|
}
|
|
32457
33593
|
}
|
|
32458
|
-
|
|
32459
|
-
outputRoot: this.outputRoot,
|
|
32460
|
-
relativeDirPath: root,
|
|
32461
|
-
dirName,
|
|
32462
|
-
global: this.global
|
|
32463
|
-
})));
|
|
32464
|
-
this.logger.debug(`Successfully loaded ${toolSkills.length} skills from ${roots.length} root(s): ${roots.join(", ")}`);
|
|
33594
|
+
this.logger.debug(`Successfully loaded ${toolSkills.length} skills from ${roots.length} root(s)`);
|
|
32465
33595
|
return toolSkills;
|
|
32466
33596
|
}
|
|
32467
33597
|
async loadToolDirsToDelete() {
|
|
@@ -32471,8 +33601,19 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
32471
33601
|
for (const root of roots) {
|
|
32472
33602
|
const skillsDirPath = (0, node_path.join)(this.outputRoot, root);
|
|
32473
33603
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
32474
|
-
|
|
33604
|
+
await assertWritablePathInsideRoot({
|
|
33605
|
+
rootPath: this.outputRoot,
|
|
33606
|
+
targetPath: skillsDirPath
|
|
33607
|
+
});
|
|
33608
|
+
const dirPaths = await findFilesByGlobs((0, node_path.join)(skillsDirPath, "*"), {
|
|
33609
|
+
type: "dir",
|
|
33610
|
+
followSymbolicLinks: false
|
|
33611
|
+
});
|
|
32475
33612
|
for (const dirPath of dirPaths) {
|
|
33613
|
+
await assertWritablePathInsideRoot({
|
|
33614
|
+
rootPath: skillsDirPath,
|
|
33615
|
+
targetPath: dirPath
|
|
33616
|
+
});
|
|
32476
33617
|
const dirName = (0, node_path.basename)(dirPath);
|
|
32477
33618
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
32478
33619
|
outputRoot: this.outputRoot,
|
|
@@ -32562,6 +33703,10 @@ var ToolSubagent = class extends ToolFile {
|
|
|
32562
33703
|
static fromRulesyncSubagent(_params) {
|
|
32563
33704
|
throw new Error("Please implement this method in the subclass.");
|
|
32564
33705
|
}
|
|
33706
|
+
/** Identity used to resolve duplicate imports across discovery roots. */
|
|
33707
|
+
getImportIdentity() {
|
|
33708
|
+
return this.getRelativeFilePath();
|
|
33709
|
+
}
|
|
32565
33710
|
static isTargetedByRulesyncSubagent(_rulesyncSubagent) {
|
|
32566
33711
|
throw new Error("Please implement this method in the subclass.");
|
|
32567
33712
|
}
|
|
@@ -33223,6 +34368,17 @@ var ClaudecodeSubagent = class ClaudecodeSubagent extends ToolSubagent {
|
|
|
33223
34368
|
}
|
|
33224
34369
|
};
|
|
33225
34370
|
//#endregion
|
|
34371
|
+
//#region src/features/subagents/claudecode-plugin-subagent.ts
|
|
34372
|
+
var ClaudecodePluginSubagent = class extends ClaudecodeSubagent {
|
|
34373
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
34374
|
+
const targets = rulesyncSubagent.getFrontmatter().targets;
|
|
34375
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
34376
|
+
}
|
|
34377
|
+
static getSettablePaths() {
|
|
34378
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_AGENTS_DIR };
|
|
34379
|
+
}
|
|
34380
|
+
};
|
|
34381
|
+
//#endregion
|
|
33226
34382
|
//#region src/features/subagents/cline-subagent.ts
|
|
33227
34383
|
const ClineSubagentFrontmatterSchema = zod_mini.z.looseObject({
|
|
33228
34384
|
name: zod_mini.z.string(),
|
|
@@ -35210,9 +36366,153 @@ var KiloSubagent = class KiloSubagent extends OpenCodeStyleSubagent {
|
|
|
35210
36366
|
}
|
|
35211
36367
|
};
|
|
35212
36368
|
//#endregion
|
|
36369
|
+
//#region src/features/subagents/kimi-code-subagent.ts
|
|
36370
|
+
const KimiCodeAgentNameSchema = zod_mini.z.pipe(zod_mini.z.string(), zod_mini.z.custom((value) => typeof value === "string" && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value), "must be a kebab-case name"));
|
|
36371
|
+
const KimiCodeSubagentFrontmatterSchema = zod_mini.z.looseObject({
|
|
36372
|
+
name: zod_mini.z.optional(KimiCodeAgentNameSchema),
|
|
36373
|
+
description: zod_mini.z.string(),
|
|
36374
|
+
whenToUse: zod_mini.z.optional(zod_mini.z.string()),
|
|
36375
|
+
override: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
36376
|
+
tools: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())])),
|
|
36377
|
+
disallowedTools: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())])),
|
|
36378
|
+
subagents: zod_mini.z.optional(zod_mini.z.union([zod_mini.z.string(), zod_mini.z.array(zod_mini.z.string())]))
|
|
36379
|
+
});
|
|
36380
|
+
/**
|
|
36381
|
+
* Kimi Code custom agent.
|
|
36382
|
+
*
|
|
36383
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/agents.html
|
|
36384
|
+
*/
|
|
36385
|
+
var KimiCodeSubagent = class KimiCodeSubagent extends ToolSubagent {
|
|
36386
|
+
frontmatter;
|
|
36387
|
+
body;
|
|
36388
|
+
constructor({ frontmatter, body, fileContent, ...rest }) {
|
|
36389
|
+
if (rest.validate !== false) {
|
|
36390
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
36391
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
36392
|
+
}
|
|
36393
|
+
super({
|
|
36394
|
+
...rest,
|
|
36395
|
+
fileContent: fileContent ?? stringifyFrontmatter(body, frontmatter)
|
|
36396
|
+
});
|
|
36397
|
+
this.frontmatter = frontmatter;
|
|
36398
|
+
this.body = body;
|
|
36399
|
+
}
|
|
36400
|
+
static getSettablePaths({ global = false } = {}) {
|
|
36401
|
+
const customHome = global ? getKimiCodeHome() : void 0;
|
|
36402
|
+
return {
|
|
36403
|
+
relativeDirPath: getKimiCodeRelativeDirPath({
|
|
36404
|
+
global,
|
|
36405
|
+
relativeDirPath: KIMI_CODE_AGENTS_DIR_NAME
|
|
36406
|
+
}),
|
|
36407
|
+
importDirPaths: [customHome ? {
|
|
36408
|
+
outputRoot: getHomeDirectory(),
|
|
36409
|
+
relativeDirPath: KIMI_CODE_SHARED_AGENTS_DIR_PATH
|
|
36410
|
+
} : KIMI_CODE_SHARED_AGENTS_DIR_PATH]
|
|
36411
|
+
};
|
|
36412
|
+
}
|
|
36413
|
+
getFrontmatter() {
|
|
36414
|
+
return this.frontmatter;
|
|
36415
|
+
}
|
|
36416
|
+
getBody() {
|
|
36417
|
+
return this.body;
|
|
36418
|
+
}
|
|
36419
|
+
getImportIdentity() {
|
|
36420
|
+
const fileName = (0, node_path.basename)(this.getRelativeFilePath(), (0, node_path.extname)(this.getRelativeFilePath()));
|
|
36421
|
+
return KimiCodeAgentNameSchema.parse(this.frontmatter.name ?? fileName).toLowerCase();
|
|
36422
|
+
}
|
|
36423
|
+
toRulesyncSubagent() {
|
|
36424
|
+
const { name: _name, description, ...rest } = this.frontmatter;
|
|
36425
|
+
const resolvedName = this.getImportIdentity();
|
|
36426
|
+
const frontmatter = {
|
|
36427
|
+
targets: ["*"],
|
|
36428
|
+
name: resolvedName,
|
|
36429
|
+
description,
|
|
36430
|
+
...Object.keys(rest).length > 0 && { "kimi-code": rest }
|
|
36431
|
+
};
|
|
36432
|
+
return new RulesyncSubagent({
|
|
36433
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
36434
|
+
nativeOutputRoot: this.outputRoot,
|
|
36435
|
+
global: this.global
|
|
36436
|
+
}),
|
|
36437
|
+
relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
|
|
36438
|
+
relativeFilePath: `${resolvedName}.md`,
|
|
36439
|
+
frontmatter,
|
|
36440
|
+
body: this.body,
|
|
36441
|
+
validate: true,
|
|
36442
|
+
global: this.global
|
|
36443
|
+
});
|
|
36444
|
+
}
|
|
36445
|
+
static fromRulesyncSubagent({ outputRoot = process.cwd(), rulesyncSubagent, validate = true, global = false }) {
|
|
36446
|
+
const frontmatter = rulesyncSubagent.getFrontmatter();
|
|
36447
|
+
const toolSection = frontmatter["kimi-code"] ?? {};
|
|
36448
|
+
const kimiCodeFrontmatter = KimiCodeSubagentFrontmatterSchema.parse({
|
|
36449
|
+
name: frontmatter.name,
|
|
36450
|
+
description: frontmatter.description,
|
|
36451
|
+
...toolSection
|
|
36452
|
+
});
|
|
36453
|
+
const body = rulesyncSubagent.getBody();
|
|
36454
|
+
return new KimiCodeSubagent({
|
|
36455
|
+
outputRoot,
|
|
36456
|
+
relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
|
|
36457
|
+
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
36458
|
+
frontmatter: kimiCodeFrontmatter,
|
|
36459
|
+
body,
|
|
36460
|
+
fileContent: stringifyFrontmatter(body, kimiCodeFrontmatter, { avoidBlockScalars: true }),
|
|
36461
|
+
validate,
|
|
36462
|
+
global
|
|
36463
|
+
});
|
|
36464
|
+
}
|
|
36465
|
+
validate() {
|
|
36466
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
36467
|
+
return result.success ? {
|
|
36468
|
+
success: true,
|
|
36469
|
+
error: null
|
|
36470
|
+
} : {
|
|
36471
|
+
success: false,
|
|
36472
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
36473
|
+
};
|
|
36474
|
+
}
|
|
36475
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
36476
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
36477
|
+
rulesyncSubagent,
|
|
36478
|
+
toolTarget: "kimi-code"
|
|
36479
|
+
});
|
|
36480
|
+
}
|
|
36481
|
+
static async fromFile({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, validate = true, global = false }) {
|
|
36482
|
+
const actualRelativeDirPath = relativeDirPath ?? this.getSettablePaths({ global }).relativeDirPath;
|
|
36483
|
+
const filePath = (0, node_path.join)(outputRoot, actualRelativeDirPath, relativeFilePath);
|
|
36484
|
+
const fileContent = await readFileContent(filePath);
|
|
36485
|
+
const { frontmatter, body } = parseFrontmatter(fileContent, filePath);
|
|
36486
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
36487
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
36488
|
+
return new KimiCodeSubagent({
|
|
36489
|
+
outputRoot,
|
|
36490
|
+
relativeDirPath: actualRelativeDirPath,
|
|
36491
|
+
relativeFilePath,
|
|
36492
|
+
frontmatter: result.data,
|
|
36493
|
+
body: body.trim(),
|
|
36494
|
+
fileContent,
|
|
36495
|
+
validate,
|
|
36496
|
+
global
|
|
36497
|
+
});
|
|
36498
|
+
}
|
|
36499
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
36500
|
+
return new KimiCodeSubagent({
|
|
36501
|
+
outputRoot,
|
|
36502
|
+
relativeDirPath,
|
|
36503
|
+
relativeFilePath,
|
|
36504
|
+
frontmatter: { description: "" },
|
|
36505
|
+
body: "",
|
|
36506
|
+
fileContent: "",
|
|
36507
|
+
validate: false,
|
|
36508
|
+
global
|
|
36509
|
+
});
|
|
36510
|
+
}
|
|
36511
|
+
};
|
|
36512
|
+
//#endregion
|
|
35213
36513
|
//#region src/features/subagents/kiro-subagent.ts
|
|
35214
36514
|
const KiroCliSubagentJsonSchema = zod_mini.z.looseObject({
|
|
35215
|
-
name: zod_mini.z.string(),
|
|
36515
|
+
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
35216
36516
|
description: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.string())),
|
|
35217
36517
|
prompt: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.string())),
|
|
35218
36518
|
tools: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.array(zod_mini.z.string()))),
|
|
@@ -35227,7 +36527,7 @@ const KiroCliSubagentJsonSchema = zod_mini.z.looseObject({
|
|
|
35227
36527
|
allowedTools: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.array(zod_mini.z.string()))),
|
|
35228
36528
|
includeMcpJson: zod_mini.z.optional(zod_mini.z.nullable(zod_mini.z.boolean()))
|
|
35229
36529
|
});
|
|
35230
|
-
var KiroSubagent = class
|
|
36530
|
+
var KiroSubagent = class extends ToolSubagent {
|
|
35231
36531
|
body;
|
|
35232
36532
|
constructor({ body, ...rest }) {
|
|
35233
36533
|
if (rest.validate !== false) try {
|
|
@@ -35245,6 +36545,9 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35245
36545
|
getBody() {
|
|
35246
36546
|
return this.body;
|
|
35247
36547
|
}
|
|
36548
|
+
static getToolTarget() {
|
|
36549
|
+
return "kiro";
|
|
36550
|
+
}
|
|
35248
36551
|
toRulesyncSubagent() {
|
|
35249
36552
|
let parsed;
|
|
35250
36553
|
try {
|
|
@@ -35253,12 +36556,13 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35253
36556
|
throw new Error(`Failed to parse JSON in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
35254
36557
|
}
|
|
35255
36558
|
const { name, description, prompt, ...restFields } = parsed;
|
|
36559
|
+
const toolTarget = this.constructor.getToolTarget();
|
|
35256
36560
|
const kiroSection = { ...restFields };
|
|
35257
36561
|
return new RulesyncSubagent({
|
|
35258
36562
|
outputRoot: ".",
|
|
35259
36563
|
frontmatter: {
|
|
35260
|
-
targets: [
|
|
35261
|
-
name,
|
|
36564
|
+
targets: [toolTarget],
|
|
36565
|
+
name: name ?? (0, node_path.basename)(this.getRelativeFilePath(), ".json"),
|
|
35262
36566
|
description: description ?? void 0,
|
|
35263
36567
|
...Object.keys(kiroSection).length > 0 && { kiro: kiroSection }
|
|
35264
36568
|
},
|
|
@@ -35285,7 +36589,7 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35285
36589
|
const body = JSON.stringify(json, null, 2);
|
|
35286
36590
|
const paths = this.getSettablePaths({ global });
|
|
35287
36591
|
const relativeFilePath = rulesyncSubagent.getRelativeFilePath().replace(/\.md$/, ".json");
|
|
35288
|
-
return new
|
|
36592
|
+
return new this({
|
|
35289
36593
|
outputRoot,
|
|
35290
36594
|
body,
|
|
35291
36595
|
relativeDirPath: paths.relativeDirPath,
|
|
@@ -35313,14 +36617,14 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35313
36617
|
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
35314
36618
|
return this.isTargetedByRulesyncSubagentDefault({
|
|
35315
36619
|
rulesyncSubagent,
|
|
35316
|
-
toolTarget:
|
|
36620
|
+
toolTarget: this.getToolTarget()
|
|
35317
36621
|
});
|
|
35318
36622
|
}
|
|
35319
36623
|
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
35320
36624
|
const paths = this.getSettablePaths({ global });
|
|
35321
36625
|
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
35322
36626
|
const fileContent = await readFileContent(filePath);
|
|
35323
|
-
const subagent = new
|
|
36627
|
+
const subagent = new this({
|
|
35324
36628
|
outputRoot,
|
|
35325
36629
|
relativeDirPath: paths.relativeDirPath,
|
|
35326
36630
|
relativeFilePath,
|
|
@@ -35336,7 +36640,7 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35336
36640
|
return subagent;
|
|
35337
36641
|
}
|
|
35338
36642
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
35339
|
-
return new
|
|
36643
|
+
return new this({
|
|
35340
36644
|
outputRoot,
|
|
35341
36645
|
relativeDirPath,
|
|
35342
36646
|
relativeFilePath,
|
|
@@ -35358,11 +36662,8 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35358
36662
|
* {@link import("./kiro-ide-subagent.js").KiroIdeSubagent}.)
|
|
35359
36663
|
*/
|
|
35360
36664
|
var KiroCliSubagent = class extends KiroSubagent {
|
|
35361
|
-
static
|
|
35362
|
-
return
|
|
35363
|
-
rulesyncSubagent,
|
|
35364
|
-
toolTarget: "kiro-cli"
|
|
35365
|
-
});
|
|
36665
|
+
static getToolTarget() {
|
|
36666
|
+
return "kiro-cli";
|
|
35366
36667
|
}
|
|
35367
36668
|
};
|
|
35368
36669
|
//#endregion
|
|
@@ -36349,6 +37650,14 @@ const toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
|
36349
37650
|
filePattern: "*.md"
|
|
36350
37651
|
}
|
|
36351
37652
|
}],
|
|
37653
|
+
["claudecode-plugin", {
|
|
37654
|
+
class: ClaudecodePluginSubagent,
|
|
37655
|
+
meta: {
|
|
37656
|
+
supportsSimulated: false,
|
|
37657
|
+
supportsGlobal: false,
|
|
37658
|
+
filePattern: "*.md"
|
|
37659
|
+
}
|
|
37660
|
+
}],
|
|
36352
37661
|
["claudecode-legacy", {
|
|
36353
37662
|
class: ClaudecodeSubagent,
|
|
36354
37663
|
meta: {
|
|
@@ -36485,6 +37794,14 @@ const toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
|
36485
37794
|
filePattern: "*.md"
|
|
36486
37795
|
}
|
|
36487
37796
|
}],
|
|
37797
|
+
["kimi-code", {
|
|
37798
|
+
class: KimiCodeSubagent,
|
|
37799
|
+
meta: {
|
|
37800
|
+
supportsSimulated: false,
|
|
37801
|
+
supportsGlobal: true,
|
|
37802
|
+
filePattern: (0, node_path.join)("**", "*.md")
|
|
37803
|
+
}
|
|
37804
|
+
}],
|
|
36488
37805
|
["opencode", {
|
|
36489
37806
|
class: OpenCodeSubagent,
|
|
36490
37807
|
meta: {
|
|
@@ -36606,7 +37923,18 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36606
37923
|
}
|
|
36607
37924
|
rulesyncSubagents.push(toolSubagent.toRulesyncSubagent());
|
|
36608
37925
|
}
|
|
36609
|
-
|
|
37926
|
+
const uniqueRulesyncSubagents = [];
|
|
37927
|
+
const seenOutputPaths = /* @__PURE__ */ new Set();
|
|
37928
|
+
for (const rulesyncSubagent of rulesyncSubagents) {
|
|
37929
|
+
const outputPath = (0, node_path.join)(rulesyncSubagent.getRelativeDirPath(), rulesyncSubagent.getRelativeFilePath());
|
|
37930
|
+
if (seenOutputPaths.has(outputPath)) {
|
|
37931
|
+
this.logger.warn(`Multiple ${this.toolTarget} subagents resolve to "${outputPath}"; keeping the first and ignoring this copy.`);
|
|
37932
|
+
continue;
|
|
37933
|
+
}
|
|
37934
|
+
seenOutputPaths.add(outputPath);
|
|
37935
|
+
uniqueRulesyncSubagents.push(rulesyncSubagent);
|
|
37936
|
+
}
|
|
37937
|
+
return uniqueRulesyncSubagents;
|
|
36610
37938
|
}
|
|
36611
37939
|
/**
|
|
36612
37940
|
* Implementation of abstract method from Processor
|
|
@@ -36654,25 +37982,35 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36654
37982
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
36655
37983
|
const factory = this.getFactory(this.toolTarget);
|
|
36656
37984
|
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
36657
|
-
const
|
|
37985
|
+
const roots = forDeletion ? [paths.relativeDirPath] : [paths.relativeDirPath, ...paths.importDirPaths ?? []];
|
|
36658
37986
|
const toolSubagents = [];
|
|
36659
37987
|
const seenRelativeFilePaths = /* @__PURE__ */ new Set();
|
|
36660
|
-
for (const
|
|
36661
|
-
const
|
|
36662
|
-
const
|
|
37988
|
+
for (const root of roots) {
|
|
37989
|
+
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
37990
|
+
const dirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
37991
|
+
const baseDir = (0, node_path.join)(rootOutputRoot, dirPath);
|
|
37992
|
+
if (forDeletion && await directoryExists(baseDir)) await assertWritablePathInsideRoot({
|
|
37993
|
+
rootPath: rootOutputRoot,
|
|
37994
|
+
targetPath: baseDir
|
|
37995
|
+
});
|
|
37996
|
+
const subagentFilePaths = await findFilesByGlobs((0, node_path.join)(baseDir, factory.meta.filePattern), { followSymbolicLinks: !forDeletion });
|
|
36663
37997
|
const toRelativeFilePath = (path) => (0, node_path.relative)(baseDir, path);
|
|
36664
37998
|
let ownedFilePaths = subagentFilePaths;
|
|
36665
37999
|
if (factory.class.isFileOwned) {
|
|
36666
38000
|
const ownership = await Promise.all(subagentFilePaths.map((path) => factory.class.isFileOwned({
|
|
36667
|
-
outputRoot:
|
|
38001
|
+
outputRoot: rootOutputRoot,
|
|
36668
38002
|
relativeDirPath: dirPath,
|
|
36669
38003
|
relativeFilePath: toRelativeFilePath(path)
|
|
36670
38004
|
})));
|
|
36671
38005
|
ownedFilePaths = subagentFilePaths.filter((_, index) => ownership[index]);
|
|
36672
38006
|
}
|
|
36673
38007
|
if (forDeletion) {
|
|
38008
|
+
await Promise.all(ownedFilePaths.map((path) => assertWritablePathInsideRoot({
|
|
38009
|
+
rootPath: baseDir,
|
|
38010
|
+
targetPath: path
|
|
38011
|
+
})));
|
|
36674
38012
|
toolSubagents.push(...ownedFilePaths.map((path) => factory.class.forDeletion({
|
|
36675
|
-
outputRoot:
|
|
38013
|
+
outputRoot: rootOutputRoot,
|
|
36676
38014
|
relativeDirPath: dirPath,
|
|
36677
38015
|
relativeFilePath: toRelativeFilePath(path),
|
|
36678
38016
|
global: this.global
|
|
@@ -36680,14 +38018,14 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36680
38018
|
continue;
|
|
36681
38019
|
}
|
|
36682
38020
|
const loaded = await Promise.all(ownedFilePaths.map((path) => factory.class.fromFile({
|
|
36683
|
-
outputRoot:
|
|
38021
|
+
outputRoot: rootOutputRoot,
|
|
36684
38022
|
relativeDirPath: dirPath,
|
|
36685
38023
|
relativeFilePath: toRelativeFilePath(path),
|
|
36686
38024
|
global: this.global
|
|
36687
38025
|
})));
|
|
36688
38026
|
const deduped = [];
|
|
36689
38027
|
for (const subagent of loaded) {
|
|
36690
|
-
const key = subagent.
|
|
38028
|
+
const key = subagent.getImportIdentity();
|
|
36691
38029
|
if (seenRelativeFilePaths.has(key)) {
|
|
36692
38030
|
this.logger.warn(`Duplicate ${this.toolTarget} subagent "${key}" found in ${dirPath}; keeping the one from a higher-precedence directory and ignoring this copy.`);
|
|
36693
38031
|
continue;
|
|
@@ -36703,7 +38041,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36703
38041
|
global: this.global
|
|
36704
38042
|
});
|
|
36705
38043
|
for (const subagent of additionalSubagents) {
|
|
36706
|
-
const key = subagent.
|
|
38044
|
+
const key = subagent.getImportIdentity();
|
|
36707
38045
|
if (seenRelativeFilePaths.has(key)) {
|
|
36708
38046
|
this.logger.warn(`Duplicate ${this.toolTarget} subagent "${key}" defined inline; keeping the standalone file and ignoring the inline copy.`);
|
|
36709
38047
|
continue;
|
|
@@ -36712,7 +38050,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36712
38050
|
toolSubagents.push(subagent);
|
|
36713
38051
|
}
|
|
36714
38052
|
}
|
|
36715
|
-
this.logger.debug(`Successfully loaded ${toolSubagents.length} ${this.toolTarget} subagents from ${
|
|
38053
|
+
this.logger.debug(`Successfully loaded ${toolSubagents.length} ${this.toolTarget} subagents from ${roots.length} root(s)`);
|
|
36716
38054
|
return toolSubagents;
|
|
36717
38055
|
}
|
|
36718
38056
|
/**
|
|
@@ -37376,17 +38714,18 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37376
38714
|
};
|
|
37377
38715
|
}
|
|
37378
38716
|
static getSettablePaths({ global = false, excludeToolDir } = {}) {
|
|
37379
|
-
if (global) return { root:
|
|
38717
|
+
if (global) return { root: this.getGlobalRootPath(excludeToolDir) };
|
|
37380
38718
|
return {
|
|
37381
|
-
root:
|
|
38719
|
+
root: this.getProjectRootPath(),
|
|
37382
38720
|
nonRoot: { relativeDirPath: buildToolPath(ANTIGRAVITY_IDE_AGENTS_DIR, "rules", excludeToolDir) }
|
|
37383
38721
|
};
|
|
37384
38722
|
}
|
|
37385
38723
|
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
38724
|
+
const paths = this.getSettablePaths({ global });
|
|
37386
38725
|
if (global) {
|
|
37387
|
-
const rootPath =
|
|
38726
|
+
const rootPath = paths.root;
|
|
37388
38727
|
const fileContent = await readFileContent((0, node_path.join)(outputRoot, rootPath.relativeDirPath, rootPath.relativeFilePath));
|
|
37389
|
-
return new
|
|
38728
|
+
return new this({
|
|
37390
38729
|
outputRoot,
|
|
37391
38730
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37392
38731
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37396,10 +38735,10 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37396
38735
|
root: true
|
|
37397
38736
|
});
|
|
37398
38737
|
}
|
|
37399
|
-
if (relativeFilePath ===
|
|
37400
|
-
const rootPath =
|
|
38738
|
+
if (relativeFilePath === paths.root.relativeFilePath) {
|
|
38739
|
+
const rootPath = paths.root;
|
|
37401
38740
|
const rootContent = await readFileContent((0, node_path.join)(outputRoot, rootPath.relativeDirPath, rootPath.relativeFilePath));
|
|
37402
|
-
return new
|
|
38741
|
+
return new this({
|
|
37403
38742
|
outputRoot,
|
|
37404
38743
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37405
38744
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37409,7 +38748,8 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37409
38748
|
root: true
|
|
37410
38749
|
});
|
|
37411
38750
|
}
|
|
37412
|
-
|
|
38751
|
+
if (!("nonRoot" in paths) || !paths.nonRoot) throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
|
|
38752
|
+
const nonRootDirPath = paths.nonRoot.relativeDirPath;
|
|
37413
38753
|
const filePath = (0, node_path.join)(outputRoot, nonRootDirPath, relativeFilePath);
|
|
37414
38754
|
const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
37415
38755
|
let parsedFrontmatter;
|
|
@@ -37418,7 +38758,7 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37418
38758
|
if (result.success) parsedFrontmatter = result.data;
|
|
37419
38759
|
else throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
37420
38760
|
} else parsedFrontmatter = frontmatter;
|
|
37421
|
-
return new
|
|
38761
|
+
return new this({
|
|
37422
38762
|
outputRoot,
|
|
37423
38763
|
relativeDirPath: nonRootDirPath,
|
|
37424
38764
|
relativeFilePath,
|
|
@@ -37429,9 +38769,10 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37429
38769
|
});
|
|
37430
38770
|
}
|
|
37431
38771
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
38772
|
+
const paths = this.getSettablePaths({ global });
|
|
37432
38773
|
if (global) {
|
|
37433
|
-
const rootPath =
|
|
37434
|
-
return new
|
|
38774
|
+
const rootPath = paths.root;
|
|
38775
|
+
return new this({
|
|
37435
38776
|
outputRoot,
|
|
37436
38777
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37437
38778
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37442,8 +38783,8 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37442
38783
|
});
|
|
37443
38784
|
}
|
|
37444
38785
|
if (rulesyncRule.getFrontmatter().root) {
|
|
37445
|
-
const rootPath =
|
|
37446
|
-
return new
|
|
38786
|
+
const rootPath = paths.root;
|
|
38787
|
+
return new this({
|
|
37447
38788
|
outputRoot,
|
|
37448
38789
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37449
38790
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37460,10 +38801,11 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37460
38801
|
const strategy = STRATEGIES$1.find((s) => s.canHandle(storedTrigger));
|
|
37461
38802
|
if (!strategy) throw new Error(`No strategy found for trigger: ${storedTrigger}`);
|
|
37462
38803
|
const frontmatter = strategy.generateFrontmatter(normalized, rulesyncFrontmatter);
|
|
38804
|
+
if (!("nonRoot" in paths) || !paths.nonRoot) throw new Error(`nonRoot path is not set for ${rulesyncRule.getRelativeFilePath()}`);
|
|
37463
38805
|
const kebabCaseFilename = toKebabCaseFilename(rulesyncRule.getRelativeFilePath());
|
|
37464
|
-
return new
|
|
38806
|
+
return new this({
|
|
37465
38807
|
outputRoot,
|
|
37466
|
-
relativeDirPath:
|
|
38808
|
+
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
37467
38809
|
relativeFilePath: kebabCaseFilename,
|
|
37468
38810
|
frontmatter,
|
|
37469
38811
|
body: rulesyncRule.getBody(),
|
|
@@ -37532,6 +38874,23 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37532
38874
|
}
|
|
37533
38875
|
};
|
|
37534
38876
|
//#endregion
|
|
38877
|
+
//#region src/features/rules/antigravity-plugin-rule.ts
|
|
38878
|
+
var AntigravityPluginRule = class extends AntigravityIdeRule {
|
|
38879
|
+
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
38880
|
+
const targets = rulesyncRule.getFrontmatter().targets;
|
|
38881
|
+
return targets.includes("*") || targets.includes("antigravity-plugin");
|
|
38882
|
+
}
|
|
38883
|
+
static getSettablePaths() {
|
|
38884
|
+
return {
|
|
38885
|
+
root: {
|
|
38886
|
+
relativeDirPath: ANTIGRAVITY_PLUGIN_RULES_DIR,
|
|
38887
|
+
relativeFilePath: "AGENTS.md"
|
|
38888
|
+
},
|
|
38889
|
+
nonRoot: { relativeDirPath: ANTIGRAVITY_PLUGIN_RULES_DIR }
|
|
38890
|
+
};
|
|
38891
|
+
}
|
|
38892
|
+
};
|
|
38893
|
+
//#endregion
|
|
37535
38894
|
//#region src/features/rules/augmentcode-legacy-rule.ts
|
|
37536
38895
|
var AugmentcodeLegacyRule = class AugmentcodeLegacyRule extends ToolRule {
|
|
37537
38896
|
toRulesyncRule() {
|
|
@@ -39481,13 +40840,17 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
39481
40840
|
if (global) {
|
|
39482
40841
|
const paths = this.getSettablePaths({ global: true });
|
|
39483
40842
|
if (!("root" in paths) || !paths.root) throw new Error("JunieRule global settable paths must include a root path");
|
|
39484
|
-
|
|
39485
|
-
return new JunieRule(
|
|
40843
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
40844
|
+
return new JunieRule({
|
|
39486
40845
|
outputRoot,
|
|
39487
|
-
|
|
40846
|
+
relativeDirPath: paths.root.relativeDirPath,
|
|
40847
|
+
relativeFilePath: paths.root.relativeFilePath,
|
|
40848
|
+
fileContent: rulesyncRule.getBody(),
|
|
39488
40849
|
validate,
|
|
39489
|
-
|
|
39490
|
-
|
|
40850
|
+
root: frontmatter.root ?? false,
|
|
40851
|
+
description: frontmatter.description,
|
|
40852
|
+
globs: frontmatter.globs
|
|
40853
|
+
});
|
|
39491
40854
|
}
|
|
39492
40855
|
const { root } = this.getSettablePaths();
|
|
39493
40856
|
return new JunieRule({
|
|
@@ -39608,6 +40971,97 @@ var KiloRule = class KiloRule extends ToolRule {
|
|
|
39608
40971
|
}
|
|
39609
40972
|
};
|
|
39610
40973
|
//#endregion
|
|
40974
|
+
//#region src/features/rules/kimi-code-rule.ts
|
|
40975
|
+
/**
|
|
40976
|
+
* Kimi Code instruction file.
|
|
40977
|
+
*
|
|
40978
|
+
* Kimi Code discovers `.kimi-code/AGENTS.md` at project scope and
|
|
40979
|
+
* `~/.kimi-code/AGENTS.md` at user scope. Rulesync's topic rules have no
|
|
40980
|
+
* dedicated Kimi rule directory, so the processor folds them into this root
|
|
40981
|
+
* instruction file.
|
|
40982
|
+
*
|
|
40983
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/agents.html
|
|
40984
|
+
*/
|
|
40985
|
+
var KimiCodeRule = class KimiCodeRule extends ToolRule {
|
|
40986
|
+
constructor({ fileContent, root, ...rest }) {
|
|
40987
|
+
super({
|
|
40988
|
+
...rest,
|
|
40989
|
+
fileContent,
|
|
40990
|
+
root: root ?? false
|
|
40991
|
+
});
|
|
40992
|
+
}
|
|
40993
|
+
static getSettablePaths({ global = false } = {}) {
|
|
40994
|
+
return { root: {
|
|
40995
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
40996
|
+
relativeFilePath: KIMI_CODE_RULE_FILE_NAME
|
|
40997
|
+
} };
|
|
40998
|
+
}
|
|
40999
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
41000
|
+
const { root } = this.getSettablePaths({ global });
|
|
41001
|
+
const fileContent = await readFileContent((0, node_path.join)(outputRoot, root.relativeDirPath, root.relativeFilePath));
|
|
41002
|
+
return new KimiCodeRule({
|
|
41003
|
+
outputRoot,
|
|
41004
|
+
relativeDirPath: root.relativeDirPath,
|
|
41005
|
+
relativeFilePath: root.relativeFilePath,
|
|
41006
|
+
fileContent,
|
|
41007
|
+
validate,
|
|
41008
|
+
global,
|
|
41009
|
+
root: true
|
|
41010
|
+
});
|
|
41011
|
+
}
|
|
41012
|
+
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
41013
|
+
const { root } = this.getSettablePaths({ global });
|
|
41014
|
+
return new KimiCodeRule({
|
|
41015
|
+
outputRoot,
|
|
41016
|
+
relativeDirPath: root.relativeDirPath,
|
|
41017
|
+
relativeFilePath: root.relativeFilePath,
|
|
41018
|
+
fileContent: rulesyncRule.getBody(),
|
|
41019
|
+
validate,
|
|
41020
|
+
global,
|
|
41021
|
+
root: rulesyncRule.getFrontmatter().root ?? false
|
|
41022
|
+
});
|
|
41023
|
+
}
|
|
41024
|
+
toRulesyncRule() {
|
|
41025
|
+
return new RulesyncRule({
|
|
41026
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
41027
|
+
nativeOutputRoot: this.outputRoot,
|
|
41028
|
+
global: this.global
|
|
41029
|
+
}),
|
|
41030
|
+
relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
|
|
41031
|
+
relativeFilePath: RULESYNC_OVERVIEW_FILE_NAME,
|
|
41032
|
+
frontmatter: {
|
|
41033
|
+
root: true,
|
|
41034
|
+
targets: ["*"],
|
|
41035
|
+
globs: ["**/*"]
|
|
41036
|
+
},
|
|
41037
|
+
body: this.getFileContent()
|
|
41038
|
+
});
|
|
41039
|
+
}
|
|
41040
|
+
validate() {
|
|
41041
|
+
return {
|
|
41042
|
+
success: true,
|
|
41043
|
+
error: null
|
|
41044
|
+
};
|
|
41045
|
+
}
|
|
41046
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
41047
|
+
return new KimiCodeRule({
|
|
41048
|
+
outputRoot,
|
|
41049
|
+
relativeDirPath,
|
|
41050
|
+
relativeFilePath,
|
|
41051
|
+
fileContent: "",
|
|
41052
|
+
validate: false,
|
|
41053
|
+
global,
|
|
41054
|
+
root: relativeDirPath === getKimiCodeRelativeDirPath({ global }) && relativeFilePath === "AGENTS.md"
|
|
41055
|
+
});
|
|
41056
|
+
}
|
|
41057
|
+
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
41058
|
+
return this.isTargetedByRulesyncRuleDefault({
|
|
41059
|
+
rulesyncRule,
|
|
41060
|
+
toolTarget: "kimi-code"
|
|
41061
|
+
});
|
|
41062
|
+
}
|
|
41063
|
+
};
|
|
41064
|
+
//#endregion
|
|
39611
41065
|
//#region src/features/rules/kiro-rule.ts
|
|
39612
41066
|
const WILDCARD_GLOBS = /* @__PURE__ */ new Set([
|
|
39613
41067
|
"**/*",
|
|
@@ -41058,6 +42512,14 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
41058
42512
|
ruleDiscoveryMode: "auto"
|
|
41059
42513
|
}
|
|
41060
42514
|
}],
|
|
42515
|
+
["antigravity-plugin", {
|
|
42516
|
+
class: AntigravityPluginRule,
|
|
42517
|
+
meta: {
|
|
42518
|
+
extension: "md",
|
|
42519
|
+
supportsGlobal: false,
|
|
42520
|
+
ruleDiscoveryMode: "auto"
|
|
42521
|
+
}
|
|
42522
|
+
}],
|
|
41061
42523
|
["augmentcode", {
|
|
41062
42524
|
class: AugmentcodeRule,
|
|
41063
42525
|
meta: {
|
|
@@ -41197,6 +42659,15 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
41197
42659
|
mcpInstructionsRegistrar: KiloMcp
|
|
41198
42660
|
}
|
|
41199
42661
|
}],
|
|
42662
|
+
["kimi-code", {
|
|
42663
|
+
class: KimiCodeRule,
|
|
42664
|
+
meta: {
|
|
42665
|
+
extension: "md",
|
|
42666
|
+
supportsGlobal: true,
|
|
42667
|
+
ruleDiscoveryMode: "auto",
|
|
42668
|
+
foldsNonRootIntoRoot: true
|
|
42669
|
+
}
|
|
42670
|
+
}],
|
|
41200
42671
|
["kiro", {
|
|
41201
42672
|
class: KiroRule,
|
|
41202
42673
|
meta: {
|
|
@@ -41670,7 +43141,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
41670
43141
|
if (targetedLocalRootRules.length > 0 && targetedRootRules.length === 0) throw new Error(`localRoot: true requires a root: true rule to exist for target '${this.toolTarget}' (found in ${formatRulePaths(targetedLocalRootRules)})`);
|
|
41671
43142
|
if (this.global) {
|
|
41672
43143
|
const globalPaths = factory.class.getSettablePaths({ global: true });
|
|
41673
|
-
const supportsGlobalNonRoot = "nonRoot" in globalPaths && globalPaths.nonRoot !== null;
|
|
43144
|
+
const supportsGlobalNonRoot = "nonRoot" in globalPaths && globalPaths.nonRoot !== null || factory.meta.supportsGlobal && factory.meta.foldsNonRootIntoRoot === true;
|
|
41674
43145
|
const nonRootRules = rulesyncRules.filter((rule) => !rule.getFrontmatter().root && !rule.getFrontmatter().localRoot && factory.class.isTargetedByRulesyncRule(rule));
|
|
41675
43146
|
if (nonRootRules.length > 0 && !supportsGlobalNonRoot) this.logger.warn(`${nonRootRules.length} non-root rulesync rules found, but it's in global mode, so ignoring them: ${formatRulePaths(nonRootRules)}`);
|
|
41676
43147
|
if (targetedLocalRootRules.length > 0) this.logger.warn(`${targetedLocalRootRules.length} localRoot rules found, but localRoot is not supported in global mode, ignoring them: ${formatRulePaths(targetedLocalRootRules)}`);
|
|
@@ -41873,12 +43344,25 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
41873
43344
|
}
|
|
41874
43345
|
};
|
|
41875
43346
|
//#endregion
|
|
43347
|
+
//#region src/utils/plugin-root.ts
|
|
43348
|
+
function isPackagingToolTarget(toolTarget) {
|
|
43349
|
+
return PACKAGING_TOOL_TARGETS.includes(toolTarget);
|
|
43350
|
+
}
|
|
43351
|
+
async function assertPluginRootSafe(params) {
|
|
43352
|
+
if (!isPackagingToolTarget(params.toolTarget)) return;
|
|
43353
|
+
await assertDirectoryIfExists(params.outputRoot);
|
|
43354
|
+
if (!await directoryExists(params.outputRoot)) throw new Error(`Plugin output root must be an existing directory: ${params.outputRoot}.`);
|
|
43355
|
+
await assertTreeContainsNoSymlinks(params.outputRoot);
|
|
43356
|
+
}
|
|
43357
|
+
//#endregion
|
|
41876
43358
|
//#region src/lib/convert.ts
|
|
41877
43359
|
/**
|
|
41878
43360
|
* Convert configuration files between AI tools without writing intermediate
|
|
41879
43361
|
* `.rulesync/` files to disk. Rulesync file instances live in memory only.
|
|
41880
43362
|
*/
|
|
41881
43363
|
async function convertFromTool(params) {
|
|
43364
|
+
const packagingTarget = [params.fromTool, ...params.toTools].find(isPackagingToolTarget);
|
|
43365
|
+
if (packagingTarget) throw new Error(`Plugin packaging target '${packagingTarget}' is not supported by convert. Use import and generate with explicit plugin directories.`);
|
|
41882
43366
|
const ctx = params;
|
|
41883
43367
|
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount, checksCount] = [
|
|
41884
43368
|
await runFeatureConvert(ctx, buildRulesStrategy(ctx)),
|
|
@@ -41957,7 +43441,11 @@ function buildRulesStrategy(ctx) {
|
|
|
41957
43441
|
itemLabel: "rule file(s)",
|
|
41958
43442
|
allTargets: RulesProcessor.getToolTargets({ global }),
|
|
41959
43443
|
createProcessor: ({ toolTarget, dryRun }) => new RulesProcessor({
|
|
41960
|
-
outputRoot
|
|
43444
|
+
outputRoot: resolveToolOutputRoot({
|
|
43445
|
+
outputRoot,
|
|
43446
|
+
toolTarget,
|
|
43447
|
+
global
|
|
43448
|
+
}),
|
|
41961
43449
|
toolTarget,
|
|
41962
43450
|
global,
|
|
41963
43451
|
dryRun,
|
|
@@ -41971,18 +43459,20 @@ function buildRulesStrategy(ctx) {
|
|
|
41971
43459
|
}
|
|
41972
43460
|
function buildIgnoreStrategy(ctx) {
|
|
41973
43461
|
const { config, logger } = ctx;
|
|
41974
|
-
|
|
41975
|
-
logger.debug("Skipping ignore conversion (not supported in global mode)");
|
|
41976
|
-
return null;
|
|
41977
|
-
}
|
|
43462
|
+
const global = config.getGlobal();
|
|
41978
43463
|
const outputRoot = getOutputRoot(config);
|
|
41979
43464
|
return {
|
|
41980
43465
|
feature: "ignore",
|
|
41981
43466
|
itemLabel: "ignore file(s)",
|
|
41982
|
-
allTargets: IgnoreProcessor.getToolTargets(),
|
|
43467
|
+
allTargets: IgnoreProcessor.getToolTargets({ global }),
|
|
41983
43468
|
createProcessor: ({ toolTarget, dryRun }) => new IgnoreProcessor({
|
|
41984
|
-
outputRoot
|
|
43469
|
+
outputRoot: resolveToolOutputRoot({
|
|
43470
|
+
outputRoot,
|
|
43471
|
+
toolTarget,
|
|
43472
|
+
global
|
|
43473
|
+
}),
|
|
41985
43474
|
toolTarget,
|
|
43475
|
+
global,
|
|
41986
43476
|
dryRun,
|
|
41987
43477
|
logger,
|
|
41988
43478
|
featureOptions: config.getFeatureOptions(toolTarget, "ignore")
|
|
@@ -42002,7 +43492,11 @@ function buildMcpStrategy(ctx) {
|
|
|
42002
43492
|
itemLabel: "MCP file(s)",
|
|
42003
43493
|
allTargets: McpProcessor.getToolTargets({ global }),
|
|
42004
43494
|
createProcessor: ({ toolTarget, dryRun }) => new McpProcessor({
|
|
42005
|
-
outputRoot
|
|
43495
|
+
outputRoot: resolveToolOutputRoot({
|
|
43496
|
+
outputRoot,
|
|
43497
|
+
toolTarget,
|
|
43498
|
+
global
|
|
43499
|
+
}),
|
|
42006
43500
|
toolTarget,
|
|
42007
43501
|
global,
|
|
42008
43502
|
dryRun,
|
|
@@ -42051,7 +43545,11 @@ function buildSubagentsStrategy(ctx) {
|
|
|
42051
43545
|
includeSimulated: false
|
|
42052
43546
|
}),
|
|
42053
43547
|
createProcessor: ({ toolTarget, dryRun }) => new SubagentsProcessor({
|
|
42054
|
-
outputRoot
|
|
43548
|
+
outputRoot: resolveToolOutputRoot({
|
|
43549
|
+
outputRoot,
|
|
43550
|
+
toolTarget,
|
|
43551
|
+
global
|
|
43552
|
+
}),
|
|
42055
43553
|
toolTarget,
|
|
42056
43554
|
global,
|
|
42057
43555
|
dryRun,
|
|
@@ -42072,7 +43570,11 @@ function buildSkillsStrategy(ctx) {
|
|
|
42072
43570
|
itemLabel: "skill(s)",
|
|
42073
43571
|
allTargets: SkillsProcessor.getToolTargets({ global }),
|
|
42074
43572
|
createProcessor: ({ toolTarget, dryRun }) => new SkillsProcessor({
|
|
42075
|
-
outputRoot
|
|
43573
|
+
outputRoot: resolveToolOutputRoot({
|
|
43574
|
+
outputRoot,
|
|
43575
|
+
toolTarget,
|
|
43576
|
+
global
|
|
43577
|
+
}),
|
|
42076
43578
|
toolTarget,
|
|
42077
43579
|
global,
|
|
42078
43580
|
dryRun,
|
|
@@ -42097,7 +43599,11 @@ function buildHooksStrategy(ctx) {
|
|
|
42097
43599
|
importOnly: true
|
|
42098
43600
|
}),
|
|
42099
43601
|
createProcessor: ({ toolTarget, dryRun }) => new HooksProcessor({
|
|
42100
|
-
outputRoot
|
|
43602
|
+
outputRoot: resolveToolOutputRoot({
|
|
43603
|
+
outputRoot,
|
|
43604
|
+
toolTarget,
|
|
43605
|
+
global
|
|
43606
|
+
}),
|
|
42101
43607
|
toolTarget,
|
|
42102
43608
|
global,
|
|
42103
43609
|
dryRun,
|
|
@@ -42122,7 +43628,11 @@ function buildPermissionsStrategy(ctx) {
|
|
|
42122
43628
|
importOnly: true
|
|
42123
43629
|
}),
|
|
42124
43630
|
createProcessor: ({ toolTarget, dryRun }) => new PermissionsProcessor({
|
|
42125
|
-
outputRoot
|
|
43631
|
+
outputRoot: resolveToolOutputRoot({
|
|
43632
|
+
outputRoot,
|
|
43633
|
+
toolTarget,
|
|
43634
|
+
global
|
|
43635
|
+
}),
|
|
42126
43636
|
toolTarget,
|
|
42127
43637
|
global,
|
|
42128
43638
|
dryRun,
|
|
@@ -42623,6 +44133,10 @@ async function warnSkillSubagentNameCollisions(params) {
|
|
|
42623
44133
|
*/
|
|
42624
44134
|
async function generate(params) {
|
|
42625
44135
|
const { config, logger } = params;
|
|
44136
|
+
for (const toolTarget of config.getTargets()) for (const outputRoot of config.getOutputRoots(toolTarget)) await assertPluginRootSafe({
|
|
44137
|
+
toolTarget,
|
|
44138
|
+
outputRoot
|
|
44139
|
+
});
|
|
42626
44140
|
await warnSkillSubagentNameCollisions({
|
|
42627
44141
|
config,
|
|
42628
44142
|
logger
|
|
@@ -42742,7 +44256,11 @@ async function generateRulesCore(params) {
|
|
|
42742
44256
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42743
44257
|
if (!config.getFeatures(toolTarget).includes("rules")) continue;
|
|
42744
44258
|
const processor = new RulesProcessor({
|
|
42745
|
-
outputRoot
|
|
44259
|
+
outputRoot: resolveToolOutputRoot({
|
|
44260
|
+
outputRoot,
|
|
44261
|
+
toolTarget,
|
|
44262
|
+
global: config.getGlobal()
|
|
44263
|
+
}),
|
|
42746
44264
|
inputRoot: config.getInputRoot(),
|
|
42747
44265
|
toolTarget,
|
|
42748
44266
|
global: config.getGlobal(),
|
|
@@ -42777,18 +44295,14 @@ async function generateRulesCore(params) {
|
|
|
42777
44295
|
}
|
|
42778
44296
|
async function generateIgnoreCore(params) {
|
|
42779
44297
|
const { config, logger } = params;
|
|
42780
|
-
const
|
|
44298
|
+
const global = config.getGlobal();
|
|
44299
|
+
const supportedIgnoreTargets = IgnoreProcessor.getToolTargets({ global });
|
|
42781
44300
|
warnUnsupportedTargets({
|
|
42782
44301
|
config,
|
|
42783
44302
|
supportedTargets: supportedIgnoreTargets,
|
|
42784
44303
|
featureName: "ignore",
|
|
42785
44304
|
logger
|
|
42786
44305
|
});
|
|
42787
|
-
if (config.getGlobal()) return {
|
|
42788
|
-
count: 0,
|
|
42789
|
-
paths: [],
|
|
42790
|
-
hasDiff: false
|
|
42791
|
-
};
|
|
42792
44306
|
let totalCount = 0;
|
|
42793
44307
|
const allPaths = [];
|
|
42794
44308
|
let hasDiff = false;
|
|
@@ -42799,6 +44313,7 @@ async function generateIgnoreCore(params) {
|
|
|
42799
44313
|
outputRoot,
|
|
42800
44314
|
inputRoot: config.getInputRoot(),
|
|
42801
44315
|
toolTarget,
|
|
44316
|
+
global,
|
|
42802
44317
|
dryRun: config.isPreviewMode(),
|
|
42803
44318
|
logger,
|
|
42804
44319
|
featureOptions: config.getFeatureOptions(toolTarget, "ignore")
|
|
@@ -42838,7 +44353,11 @@ async function generateMcpCore(params) {
|
|
|
42838
44353
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42839
44354
|
if (!config.getFeatures(toolTarget).includes("mcp")) continue;
|
|
42840
44355
|
const processor = new McpProcessor({
|
|
42841
|
-
outputRoot
|
|
44356
|
+
outputRoot: resolveToolOutputRoot({
|
|
44357
|
+
outputRoot,
|
|
44358
|
+
toolTarget,
|
|
44359
|
+
global: config.getGlobal()
|
|
44360
|
+
}),
|
|
42842
44361
|
inputRoot: config.getInputRoot(),
|
|
42843
44362
|
toolTarget,
|
|
42844
44363
|
global: config.getGlobal(),
|
|
@@ -42923,7 +44442,11 @@ async function generateSubagentsCore(params) {
|
|
|
42923
44442
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42924
44443
|
if (!config.getFeatures(toolTarget).includes("subagents")) continue;
|
|
42925
44444
|
const processor = new SubagentsProcessor({
|
|
42926
|
-
outputRoot
|
|
44445
|
+
outputRoot: resolveToolOutputRoot({
|
|
44446
|
+
outputRoot,
|
|
44447
|
+
toolTarget,
|
|
44448
|
+
global: config.getGlobal()
|
|
44449
|
+
}),
|
|
42927
44450
|
inputRoot: config.getInputRoot(),
|
|
42928
44451
|
toolTarget,
|
|
42929
44452
|
global: config.getGlobal(),
|
|
@@ -42966,7 +44489,11 @@ async function generateSkillsCore(params) {
|
|
|
42966
44489
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42967
44490
|
if (!config.getFeatures(toolTarget).includes("skills")) continue;
|
|
42968
44491
|
const processor = new SkillsProcessor({
|
|
42969
|
-
outputRoot
|
|
44492
|
+
outputRoot: resolveToolOutputRoot({
|
|
44493
|
+
outputRoot,
|
|
44494
|
+
toolTarget,
|
|
44495
|
+
global: config.getGlobal()
|
|
44496
|
+
}),
|
|
42970
44497
|
inputRoot: config.getInputRoot(),
|
|
42971
44498
|
toolTarget,
|
|
42972
44499
|
global: config.getGlobal(),
|
|
@@ -43007,7 +44534,11 @@ async function generateHooksCore(params) {
|
|
|
43007
44534
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
43008
44535
|
if (!config.getFeatures(toolTarget).includes("hooks")) continue;
|
|
43009
44536
|
const processor = new HooksProcessor({
|
|
43010
|
-
outputRoot
|
|
44537
|
+
outputRoot: resolveToolOutputRoot({
|
|
44538
|
+
outputRoot,
|
|
44539
|
+
toolTarget,
|
|
44540
|
+
global: config.getGlobal()
|
|
44541
|
+
}),
|
|
43011
44542
|
inputRoot: config.getInputRoot(),
|
|
43012
44543
|
toolTarget,
|
|
43013
44544
|
global: config.getGlobal(),
|
|
@@ -43045,7 +44576,11 @@ async function generatePermissionsCore(params) {
|
|
|
43045
44576
|
if (!config.getFeatures(toolTarget).includes("permissions")) continue;
|
|
43046
44577
|
try {
|
|
43047
44578
|
const processor = new PermissionsProcessor({
|
|
43048
|
-
outputRoot
|
|
44579
|
+
outputRoot: resolveToolOutputRoot({
|
|
44580
|
+
outputRoot,
|
|
44581
|
+
toolTarget,
|
|
44582
|
+
global: config.getGlobal()
|
|
44583
|
+
}),
|
|
43049
44584
|
inputRoot: config.getInputRoot(),
|
|
43050
44585
|
toolTarget,
|
|
43051
44586
|
global: config.getGlobal(),
|
|
@@ -43111,21 +44646,41 @@ async function generateChecksCore(params) {
|
|
|
43111
44646
|
}
|
|
43112
44647
|
//#endregion
|
|
43113
44648
|
//#region src/lib/import.ts
|
|
43114
|
-
|
|
43115
|
-
|
|
43116
|
-
|
|
43117
|
-
|
|
43118
|
-
|
|
43119
|
-
|
|
43120
|
-
|
|
43121
|
-
|
|
43122
|
-
|
|
44649
|
+
async function applyRulesyncSourcePath({ files, paths, sourceClass, outputRoot }) {
|
|
44650
|
+
const first = files[0];
|
|
44651
|
+
if (!first) return files;
|
|
44652
|
+
const destinationOutputRoot = outputRoot ?? first.getOutputRoot();
|
|
44653
|
+
const destination = await resolveRulesyncSourceWritePath({
|
|
44654
|
+
outputRoot: destinationOutputRoot,
|
|
44655
|
+
paths
|
|
44656
|
+
});
|
|
44657
|
+
return files.map((file) => new sourceClass({
|
|
44658
|
+
outputRoot: destinationOutputRoot,
|
|
44659
|
+
relativeDirPath: destination.relativeDirPath,
|
|
44660
|
+
relativeFilePath: destination.relativeFilePath,
|
|
44661
|
+
fileContent: file.getFileContent(),
|
|
44662
|
+
validate: true
|
|
44663
|
+
}));
|
|
44664
|
+
}
|
|
44665
|
+
function getToolOutputRoot({ config, tool }) {
|
|
44666
|
+
return resolveToolOutputRoot({
|
|
44667
|
+
outputRoot: config.getOutputRoots(tool)[0] ?? ".",
|
|
44668
|
+
toolTarget: tool,
|
|
44669
|
+
global: config.getGlobal()
|
|
44670
|
+
});
|
|
43123
44671
|
}
|
|
43124
44672
|
/**
|
|
43125
44673
|
* Import configuration files from AI tools.
|
|
43126
44674
|
*/
|
|
43127
44675
|
async function importFromTool(params) {
|
|
43128
44676
|
const { config, tool, logger } = params;
|
|
44677
|
+
await assertPluginRootSafe({
|
|
44678
|
+
toolTarget: tool,
|
|
44679
|
+
outputRoot: getToolOutputRoot({
|
|
44680
|
+
config,
|
|
44681
|
+
tool
|
|
44682
|
+
})
|
|
44683
|
+
});
|
|
43129
44684
|
return {
|
|
43130
44685
|
rulesCount: await importRulesCore({
|
|
43131
44686
|
config,
|
|
@@ -43180,7 +44735,10 @@ async function importRulesCore(params) {
|
|
|
43180
44735
|
const global = config.getGlobal();
|
|
43181
44736
|
if (!RulesProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43182
44737
|
const rulesProcessor = new RulesProcessor({
|
|
43183
|
-
outputRoot:
|
|
44738
|
+
outputRoot: getToolOutputRoot({
|
|
44739
|
+
config,
|
|
44740
|
+
tool
|
|
44741
|
+
}),
|
|
43184
44742
|
toolTarget: tool,
|
|
43185
44743
|
global,
|
|
43186
44744
|
logger
|
|
@@ -43198,14 +44756,15 @@ async function importRulesCore(params) {
|
|
|
43198
44756
|
async function importIgnoreCore(params) {
|
|
43199
44757
|
const { config, tool, logger } = params;
|
|
43200
44758
|
if (!config.getFeatures(tool).includes("ignore")) return 0;
|
|
43201
|
-
|
|
43202
|
-
|
|
43203
|
-
return 0;
|
|
43204
|
-
}
|
|
43205
|
-
if (!IgnoreProcessor.getToolTargets().includes(tool)) return 0;
|
|
44759
|
+
const global = config.getGlobal();
|
|
44760
|
+
if (!IgnoreProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43206
44761
|
const ignoreProcessor = new IgnoreProcessor({
|
|
43207
|
-
outputRoot:
|
|
44762
|
+
outputRoot: getToolOutputRoot({
|
|
44763
|
+
config,
|
|
44764
|
+
tool
|
|
44765
|
+
}),
|
|
43208
44766
|
toolTarget: tool,
|
|
44767
|
+
global,
|
|
43209
44768
|
logger,
|
|
43210
44769
|
featureOptions: config.getFeatureOptions(tool, "ignore")
|
|
43211
44770
|
});
|
|
@@ -43226,7 +44785,10 @@ async function importMcpCore(params) {
|
|
|
43226
44785
|
const global = config.getGlobal();
|
|
43227
44786
|
if (!McpProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43228
44787
|
const mcpProcessor = new McpProcessor({
|
|
43229
|
-
outputRoot:
|
|
44788
|
+
outputRoot: getToolOutputRoot({
|
|
44789
|
+
config,
|
|
44790
|
+
tool
|
|
44791
|
+
}),
|
|
43230
44792
|
toolTarget: tool,
|
|
43231
44793
|
global,
|
|
43232
44794
|
logger
|
|
@@ -43236,14 +44798,13 @@ async function importMcpCore(params) {
|
|
|
43236
44798
|
logger.warn(`No MCP files found for ${tool}. Skipping import.`);
|
|
43237
44799
|
return 0;
|
|
43238
44800
|
}
|
|
43239
|
-
const rulesyncFiles = await
|
|
43240
|
-
|
|
43241
|
-
|
|
43242
|
-
|
|
43243
|
-
|
|
43244
|
-
jsoncRelativePath: RULESYNC_MCP_JSONC_RELATIVE_FILE_PATH,
|
|
43245
|
-
logger
|
|
44801
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44802
|
+
files: await mcpProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44803
|
+
paths: RulesyncMcp.getSettablePaths(),
|
|
44804
|
+
sourceClass: RulesyncMcp,
|
|
44805
|
+
outputRoot: isPackagingToolTarget(tool) ? process.cwd() : void 0
|
|
43246
44806
|
});
|
|
44807
|
+
const { count: writtenCount } = await mcpProcessor.writeAiFiles(rulesyncFiles);
|
|
43247
44808
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} MCP files`);
|
|
43248
44809
|
return writtenCount;
|
|
43249
44810
|
}
|
|
@@ -43256,7 +44817,10 @@ async function importCommandsCore(params) {
|
|
|
43256
44817
|
includeSimulated: false
|
|
43257
44818
|
}).includes(tool)) return 0;
|
|
43258
44819
|
const commandsProcessor = new CommandsProcessor({
|
|
43259
|
-
outputRoot:
|
|
44820
|
+
outputRoot: getToolOutputRoot({
|
|
44821
|
+
config,
|
|
44822
|
+
tool
|
|
44823
|
+
}),
|
|
43260
44824
|
toolTarget: tool,
|
|
43261
44825
|
global,
|
|
43262
44826
|
logger
|
|
@@ -43280,7 +44844,10 @@ async function importSubagentsCore(params) {
|
|
|
43280
44844
|
includeSimulated: false
|
|
43281
44845
|
}).includes(tool)) return 0;
|
|
43282
44846
|
const subagentsProcessor = new SubagentsProcessor({
|
|
43283
|
-
outputRoot:
|
|
44847
|
+
outputRoot: getToolOutputRoot({
|
|
44848
|
+
config,
|
|
44849
|
+
tool
|
|
44850
|
+
}),
|
|
43284
44851
|
toolTarget: tool,
|
|
43285
44852
|
global: config.getGlobal(),
|
|
43286
44853
|
logger
|
|
@@ -43301,7 +44868,10 @@ async function importSkillsCore(params) {
|
|
|
43301
44868
|
const global = config.getGlobal();
|
|
43302
44869
|
if (!SkillsProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43303
44870
|
const skillsProcessor = new SkillsProcessor({
|
|
43304
|
-
outputRoot:
|
|
44871
|
+
outputRoot: getToolOutputRoot({
|
|
44872
|
+
config,
|
|
44873
|
+
tool
|
|
44874
|
+
}),
|
|
43305
44875
|
toolTarget: tool,
|
|
43306
44876
|
global,
|
|
43307
44877
|
logger
|
|
@@ -43311,8 +44881,21 @@ async function importSkillsCore(params) {
|
|
|
43311
44881
|
logger.warn(`No skill directories found for ${tool}. Skipping import.`);
|
|
43312
44882
|
return 0;
|
|
43313
44883
|
}
|
|
43314
|
-
const
|
|
43315
|
-
|
|
44884
|
+
const rebasedRulesyncDirs = (await skillsProcessor.convertToolDirsToRulesyncDirs(toolDirs)).map((dir) => {
|
|
44885
|
+
if (!isPackagingToolTarget(tool)) return dir;
|
|
44886
|
+
if (!(dir instanceof RulesyncSkill)) return dir;
|
|
44887
|
+
return new RulesyncSkill({
|
|
44888
|
+
outputRoot: process.cwd(),
|
|
44889
|
+
relativeDirPath: dir.getRelativeDirPath(),
|
|
44890
|
+
dirName: dir.getDirName(),
|
|
44891
|
+
frontmatter: dir.getFrontmatter(),
|
|
44892
|
+
body: dir.getBody(),
|
|
44893
|
+
otherFiles: dir.getOtherFiles(),
|
|
44894
|
+
validate: true,
|
|
44895
|
+
global: false
|
|
44896
|
+
});
|
|
44897
|
+
});
|
|
44898
|
+
const { count: writtenCount } = await skillsProcessor.writeAiDirs(rebasedRulesyncDirs);
|
|
43316
44899
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} skill directories`);
|
|
43317
44900
|
return writtenCount;
|
|
43318
44901
|
}
|
|
@@ -43331,7 +44914,10 @@ async function importHooksCore(params) {
|
|
|
43331
44914
|
return 0;
|
|
43332
44915
|
}
|
|
43333
44916
|
const hooksProcessor = new HooksProcessor({
|
|
43334
|
-
outputRoot:
|
|
44917
|
+
outputRoot: getToolOutputRoot({
|
|
44918
|
+
config,
|
|
44919
|
+
tool
|
|
44920
|
+
}),
|
|
43335
44921
|
toolTarget: tool,
|
|
43336
44922
|
global,
|
|
43337
44923
|
logger
|
|
@@ -43341,14 +44927,13 @@ async function importHooksCore(params) {
|
|
|
43341
44927
|
logger.warn(`No hooks files found for ${tool}. Skipping import.`);
|
|
43342
44928
|
return 0;
|
|
43343
44929
|
}
|
|
43344
|
-
const rulesyncFiles = await
|
|
43345
|
-
|
|
43346
|
-
|
|
43347
|
-
|
|
43348
|
-
|
|
43349
|
-
jsoncRelativePath: RULESYNC_HOOKS_JSONC_RELATIVE_FILE_PATH,
|
|
43350
|
-
logger
|
|
44930
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44931
|
+
files: await hooksProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44932
|
+
paths: RulesyncHooks.getSettablePaths(),
|
|
44933
|
+
sourceClass: RulesyncHooks,
|
|
44934
|
+
outputRoot: isPackagingToolTarget(tool) ? process.cwd() : void 0
|
|
43351
44935
|
});
|
|
44936
|
+
const { count: writtenCount } = await hooksProcessor.writeAiFiles(rulesyncFiles);
|
|
43352
44937
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} hooks file(s)`);
|
|
43353
44938
|
return writtenCount;
|
|
43354
44939
|
}
|
|
@@ -43366,7 +44951,10 @@ async function importPermissionsCore(params) {
|
|
|
43366
44951
|
return 0;
|
|
43367
44952
|
}
|
|
43368
44953
|
const permissionsProcessor = new PermissionsProcessor({
|
|
43369
|
-
outputRoot:
|
|
44954
|
+
outputRoot: getToolOutputRoot({
|
|
44955
|
+
config,
|
|
44956
|
+
tool
|
|
44957
|
+
}),
|
|
43370
44958
|
toolTarget: tool,
|
|
43371
44959
|
global: config.getGlobal(),
|
|
43372
44960
|
logger
|
|
@@ -43376,14 +44964,12 @@ async function importPermissionsCore(params) {
|
|
|
43376
44964
|
logger.warn(`No permissions files found for ${tool}. Skipping import.`);
|
|
43377
44965
|
return 0;
|
|
43378
44966
|
}
|
|
43379
|
-
const rulesyncFiles = await
|
|
43380
|
-
|
|
43381
|
-
|
|
43382
|
-
|
|
43383
|
-
jsonRelativePath: RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH,
|
|
43384
|
-
jsoncRelativePath: RULESYNC_PERMISSIONS_JSONC_RELATIVE_FILE_PATH,
|
|
43385
|
-
logger
|
|
44967
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44968
|
+
files: await permissionsProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44969
|
+
paths: RulesyncPermissions.getSettablePaths(),
|
|
44970
|
+
sourceClass: RulesyncPermissions
|
|
43386
44971
|
});
|
|
44972
|
+
const { count: writtenCount } = await permissionsProcessor.writeAiFiles(rulesyncFiles);
|
|
43387
44973
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} permissions file(s)`);
|
|
43388
44974
|
return writtenCount;
|
|
43389
44975
|
}
|
|
@@ -43547,6 +45133,12 @@ Object.defineProperty(exports, "McpProcessor", {
|
|
|
43547
45133
|
return McpProcessor;
|
|
43548
45134
|
}
|
|
43549
45135
|
});
|
|
45136
|
+
Object.defineProperty(exports, "PACKAGING_TOOL_TARGETS", {
|
|
45137
|
+
enumerable: true,
|
|
45138
|
+
get: function() {
|
|
45139
|
+
return PACKAGING_TOOL_TARGETS;
|
|
45140
|
+
}
|
|
45141
|
+
});
|
|
43550
45142
|
Object.defineProperty(exports, "RULESYNC_AIIGNORE_FILE_NAME", {
|
|
43551
45143
|
enumerable: true,
|
|
43552
45144
|
get: function() {
|
|
@@ -43601,10 +45193,10 @@ Object.defineProperty(exports, "RULESYNC_HOOKS_FILE_NAME", {
|
|
|
43601
45193
|
return RULESYNC_HOOKS_FILE_NAME;
|
|
43602
45194
|
}
|
|
43603
45195
|
});
|
|
43604
|
-
Object.defineProperty(exports, "
|
|
45196
|
+
Object.defineProperty(exports, "RULESYNC_HOOKS_LEGACY_FILE_NAME", {
|
|
43605
45197
|
enumerable: true,
|
|
43606
45198
|
get: function() {
|
|
43607
|
-
return
|
|
45199
|
+
return RULESYNC_HOOKS_LEGACY_FILE_NAME;
|
|
43608
45200
|
}
|
|
43609
45201
|
});
|
|
43610
45202
|
Object.defineProperty(exports, "RULESYNC_HOOKS_RELATIVE_FILE_PATH", {
|
|
@@ -43631,10 +45223,10 @@ Object.defineProperty(exports, "RULESYNC_MCP_FILE_NAME", {
|
|
|
43631
45223
|
return RULESYNC_MCP_FILE_NAME;
|
|
43632
45224
|
}
|
|
43633
45225
|
});
|
|
43634
|
-
Object.defineProperty(exports, "
|
|
45226
|
+
Object.defineProperty(exports, "RULESYNC_MCP_LEGACY_FILE_NAME", {
|
|
43635
45227
|
enumerable: true,
|
|
43636
45228
|
get: function() {
|
|
43637
|
-
return
|
|
45229
|
+
return RULESYNC_MCP_LEGACY_FILE_NAME;
|
|
43638
45230
|
}
|
|
43639
45231
|
});
|
|
43640
45232
|
Object.defineProperty(exports, "RULESYNC_MCP_RELATIVE_FILE_PATH", {
|
|
@@ -43661,10 +45253,10 @@ Object.defineProperty(exports, "RULESYNC_PERMISSIONS_FILE_NAME", {
|
|
|
43661
45253
|
return RULESYNC_PERMISSIONS_FILE_NAME;
|
|
43662
45254
|
}
|
|
43663
45255
|
});
|
|
43664
|
-
Object.defineProperty(exports, "
|
|
45256
|
+
Object.defineProperty(exports, "RULESYNC_PERMISSIONS_LEGACY_FILE_NAME", {
|
|
43665
45257
|
enumerable: true,
|
|
43666
45258
|
get: function() {
|
|
43667
|
-
return
|
|
45259
|
+
return RULESYNC_PERMISSIONS_LEGACY_FILE_NAME;
|
|
43668
45260
|
}
|
|
43669
45261
|
});
|
|
43670
45262
|
Object.defineProperty(exports, "RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH", {
|
|
@@ -43949,12 +45541,24 @@ Object.defineProperty(exports, "getProcessorRegistryEntry", {
|
|
|
43949
45541
|
return getProcessorRegistryEntry;
|
|
43950
45542
|
}
|
|
43951
45543
|
});
|
|
45544
|
+
Object.defineProperty(exports, "getRulesyncSourceCandidates", {
|
|
45545
|
+
enumerable: true,
|
|
45546
|
+
get: function() {
|
|
45547
|
+
return getRulesyncSourceCandidates;
|
|
45548
|
+
}
|
|
45549
|
+
});
|
|
43952
45550
|
Object.defineProperty(exports, "importFromTool", {
|
|
43953
45551
|
enumerable: true,
|
|
43954
45552
|
get: function() {
|
|
43955
45553
|
return importFromTool;
|
|
43956
45554
|
}
|
|
43957
45555
|
});
|
|
45556
|
+
Object.defineProperty(exports, "isPackagingToolTarget", {
|
|
45557
|
+
enumerable: true,
|
|
45558
|
+
get: function() {
|
|
45559
|
+
return isPackagingToolTarget;
|
|
45560
|
+
}
|
|
45561
|
+
});
|
|
43958
45562
|
Object.defineProperty(exports, "isSymlink", {
|
|
43959
45563
|
enumerable: true,
|
|
43960
45564
|
get: function() {
|
|
@@ -43973,6 +45577,12 @@ Object.defineProperty(exports, "loadYaml", {
|
|
|
43973
45577
|
return loadYaml;
|
|
43974
45578
|
}
|
|
43975
45579
|
});
|
|
45580
|
+
Object.defineProperty(exports, "parseJsonc", {
|
|
45581
|
+
enumerable: true,
|
|
45582
|
+
get: function() {
|
|
45583
|
+
return parseJsonc$8;
|
|
45584
|
+
}
|
|
45585
|
+
});
|
|
43976
45586
|
Object.defineProperty(exports, "readFileContent", {
|
|
43977
45587
|
enumerable: true,
|
|
43978
45588
|
get: function() {
|
|
@@ -44021,6 +45631,12 @@ Object.defineProperty(exports, "resolvePath", {
|
|
|
44021
45631
|
return resolvePath;
|
|
44022
45632
|
}
|
|
44023
45633
|
});
|
|
45634
|
+
Object.defineProperty(exports, "resolveRulesyncSourceWritePath", {
|
|
45635
|
+
enumerable: true,
|
|
45636
|
+
get: function() {
|
|
45637
|
+
return resolveRulesyncSourceWritePath;
|
|
45638
|
+
}
|
|
45639
|
+
});
|
|
44024
45640
|
Object.defineProperty(exports, "runWithDirectoryRollback", {
|
|
44025
45641
|
enumerable: true,
|
|
44026
45642
|
get: function() {
|