rulesync 14.2.0 → 15.0.1
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
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { minLength, optional, refine, z } from "zod/mini";
|
|
2
1
|
import { ZodError } from "zod";
|
|
2
|
+
import { meta, minLength, nonnegative, optional, refine, z } from "zod/mini";
|
|
3
3
|
import { cp, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rm, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import path, { basename, dirname, extname, isAbsolute, join, posix, relative, resolve, sep, win32 } from "node:path";
|
|
5
5
|
import { parse, printParseErrorCode } from "jsonc-parser";
|
|
@@ -14,10 +14,39 @@ import { isDeepStrictEqual } from "node:util";
|
|
|
14
14
|
import * as smolToml from "smol-toml";
|
|
15
15
|
import { parse as parse$1, stringify } from "smol-toml";
|
|
16
16
|
import { encode } from "@toon-format/toon";
|
|
17
|
+
//#region src/utils/error.ts
|
|
18
|
+
/**
|
|
19
|
+
* Convert various error types to a readable error message
|
|
20
|
+
* @param error Error instance (ZodError, Error, or unknown)
|
|
21
|
+
* @returns Human-readable error message
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // ZodError
|
|
25
|
+
* const result = schema.safeParse(data);
|
|
26
|
+
* if (!result.success) {
|
|
27
|
+
* throw new Error(`Validation failed: ${formatError(result.error)}`);
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Standard Error
|
|
32
|
+
* try {
|
|
33
|
+
* // some operation
|
|
34
|
+
* } catch (error) {
|
|
35
|
+
* console.error(formatError(error));
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
function isZodErrorLike(error) {
|
|
39
|
+
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");
|
|
40
|
+
}
|
|
41
|
+
function formatError(error) {
|
|
42
|
+
if (error instanceof ZodError || isZodErrorLike(error)) return `Zod raw error: ${JSON.stringify(error.issues)}`;
|
|
43
|
+
if (error instanceof Error) return `${error.name}: ${error.message}`;
|
|
44
|
+
return String(error);
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
17
47
|
//#region src/types/features.ts
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
"ignore",
|
|
48
|
+
const ACTIVE_FEATURES_BEFORE_IGNORE = ["rules"];
|
|
49
|
+
const ACTIVE_FEATURES_AFTER_IGNORE = [
|
|
21
50
|
"mcp",
|
|
22
51
|
"subagents",
|
|
23
52
|
"commands",
|
|
@@ -26,9 +55,20 @@ const ALL_FEATURES = [
|
|
|
26
55
|
"permissions",
|
|
27
56
|
"checks"
|
|
28
57
|
];
|
|
58
|
+
const ALL_FEATURES = [
|
|
59
|
+
...ACTIVE_FEATURES_BEFORE_IGNORE,
|
|
60
|
+
"ignore",
|
|
61
|
+
...ACTIVE_FEATURES_AFTER_IGNORE
|
|
62
|
+
];
|
|
29
63
|
const ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
|
|
30
|
-
const
|
|
64
|
+
const ACTIVE_FEATURES = [...ACTIVE_FEATURES_BEFORE_IGNORE, ...ACTIVE_FEATURES_AFTER_IGNORE];
|
|
65
|
+
const DeprecatedIgnoreFeatureSchema = z.literal("ignore").check(meta({
|
|
66
|
+
deprecated: true,
|
|
67
|
+
description: "Deprecated: use the permissions feature. Ignore remains supported for compatibility throughout Rulesync 14.x."
|
|
68
|
+
}));
|
|
69
|
+
const FeatureSchema = z.union([z.enum(ACTIVE_FEATURES), DeprecatedIgnoreFeatureSchema]);
|
|
31
70
|
z.array(FeatureSchema);
|
|
71
|
+
const FeatureWithWildcardSchema = z.union([z.enum([...ACTIVE_FEATURES, "*"]), DeprecatedIgnoreFeatureSchema]);
|
|
32
72
|
const GitignoreDestinationSchema = z.enum(["gitignore", "gitattributes"]);
|
|
33
73
|
const FlattenedCommandNamingSchema = z.enum(["basename", "path"]);
|
|
34
74
|
const FeatureOptionsSchema = z.record(z.string(), z.unknown());
|
|
@@ -38,8 +78,8 @@ const FeatureValueSchema = z.union([
|
|
|
38
78
|
GitignoreDestinationSchema
|
|
39
79
|
]);
|
|
40
80
|
const PerFeatureConfigSchema = z.record(z.string(), FeatureValueSchema);
|
|
41
|
-
const PerTargetFeaturesValueSchema = z.union([z.array(
|
|
42
|
-
const RulesyncFeaturesSchema = z.array(
|
|
81
|
+
const PerTargetFeaturesValueSchema = z.union([z.array(FeatureWithWildcardSchema), PerFeatureConfigSchema]);
|
|
82
|
+
const RulesyncFeaturesSchema = z.array(FeatureWithWildcardSchema);
|
|
43
83
|
/**
|
|
44
84
|
* Returns true if a per-feature value enables the feature.
|
|
45
85
|
*
|
|
@@ -61,36 +101,6 @@ const isFeatureValueEnabled = (value) => {
|
|
|
61
101
|
return false;
|
|
62
102
|
};
|
|
63
103
|
//#endregion
|
|
64
|
-
//#region src/utils/error.ts
|
|
65
|
-
/**
|
|
66
|
-
* Convert various error types to a readable error message
|
|
67
|
-
* @param error Error instance (ZodError, Error, or unknown)
|
|
68
|
-
* @returns Human-readable error message
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* // ZodError
|
|
72
|
-
* const result = schema.safeParse(data);
|
|
73
|
-
* if (!result.success) {
|
|
74
|
-
* throw new Error(`Validation failed: ${formatError(result.error)}`);
|
|
75
|
-
* }
|
|
76
|
-
*
|
|
77
|
-
* @example
|
|
78
|
-
* // Standard Error
|
|
79
|
-
* try {
|
|
80
|
-
* // some operation
|
|
81
|
-
* } catch (error) {
|
|
82
|
-
* console.error(formatError(error));
|
|
83
|
-
* }
|
|
84
|
-
*/
|
|
85
|
-
function isZodErrorLike(error) {
|
|
86
|
-
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");
|
|
87
|
-
}
|
|
88
|
-
function formatError(error) {
|
|
89
|
-
if (error instanceof ZodError || isZodErrorLike(error)) return `Zod raw error: ${JSON.stringify(error.issues)}`;
|
|
90
|
-
if (error instanceof Error) return `${error.name}: ${error.message}`;
|
|
91
|
-
return String(error);
|
|
92
|
-
}
|
|
93
|
-
//#endregion
|
|
94
104
|
//#region src/constants/rulesync-paths.ts
|
|
95
105
|
const { join: join$1 } = posix;
|
|
96
106
|
const RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
|
|
@@ -101,12 +111,12 @@ const RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH = join$1(RULESYNC_RULES_RELATIVE_
|
|
|
101
111
|
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "commands");
|
|
102
112
|
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "subagents");
|
|
103
113
|
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "checks");
|
|
104
|
-
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "mcp.
|
|
105
|
-
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "hooks.
|
|
106
|
-
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "permissions.
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
const
|
|
114
|
+
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "mcp.jsonc");
|
|
115
|
+
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "hooks.jsonc");
|
|
116
|
+
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "permissions.jsonc");
|
|
117
|
+
join$1(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
|
|
118
|
+
const RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "hooks.json");
|
|
119
|
+
const RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "permissions.json");
|
|
110
120
|
const RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
|
|
111
121
|
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
|
|
112
122
|
const RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
|
|
@@ -115,12 +125,12 @@ const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "sk
|
|
|
115
125
|
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$1(RULESYNC_SKILLS_RELATIVE_DIR_PATH, ".curated");
|
|
116
126
|
const RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync.lock";
|
|
117
127
|
const RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync-npm.lock.json";
|
|
118
|
-
const RULESYNC_MCP_FILE_NAME = "mcp.
|
|
119
|
-
const RULESYNC_HOOKS_FILE_NAME = "hooks.
|
|
120
|
-
const RULESYNC_PERMISSIONS_FILE_NAME = "permissions.
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
128
|
+
const RULESYNC_MCP_FILE_NAME = "mcp.jsonc";
|
|
129
|
+
const RULESYNC_HOOKS_FILE_NAME = "hooks.jsonc";
|
|
130
|
+
const RULESYNC_PERMISSIONS_FILE_NAME = "permissions.jsonc";
|
|
131
|
+
const RULESYNC_MCP_LEGACY_FILE_NAME = "mcp.json";
|
|
132
|
+
const RULESYNC_HOOKS_LEGACY_FILE_NAME = "hooks.json";
|
|
133
|
+
const RULESYNC_PERMISSIONS_LEGACY_FILE_NAME = "permissions.json";
|
|
124
134
|
const RULESYNC_CONFIG_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/config-schema.json";
|
|
125
135
|
const RULESYNC_MCP_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/mcp-schema.json";
|
|
126
136
|
const RULESYNC_PERMISSIONS_SCHEMA_URL = "https://github.com/dyoshikawa/rulesync/releases/latest/download/permissions-schema.json";
|
|
@@ -133,6 +143,7 @@ const rulesProcessorToolTargetTuple = [
|
|
|
133
143
|
"amp",
|
|
134
144
|
"antigravity-cli",
|
|
135
145
|
"antigravity-ide",
|
|
146
|
+
"antigravity-plugin",
|
|
136
147
|
"augmentcode",
|
|
137
148
|
"augmentcode-legacy",
|
|
138
149
|
"claudecode",
|
|
@@ -149,6 +160,7 @@ const rulesProcessorToolTargetTuple = [
|
|
|
149
160
|
"hermesagent",
|
|
150
161
|
"junie",
|
|
151
162
|
"kilo",
|
|
163
|
+
"kimi-code",
|
|
152
164
|
"kiro",
|
|
153
165
|
"kiro-cli",
|
|
154
166
|
"kiro-ide",
|
|
@@ -192,8 +204,10 @@ const mcpProcessorToolTargetTuple = [
|
|
|
192
204
|
"amp",
|
|
193
205
|
"antigravity-cli",
|
|
194
206
|
"antigravity-ide",
|
|
207
|
+
"antigravity-plugin",
|
|
195
208
|
"augmentcode",
|
|
196
209
|
"claudecode",
|
|
210
|
+
"claudecode-plugin",
|
|
197
211
|
"claudecode-legacy",
|
|
198
212
|
"cline",
|
|
199
213
|
"codexcli",
|
|
@@ -205,6 +219,7 @@ const mcpProcessorToolTargetTuple = [
|
|
|
205
219
|
"goose",
|
|
206
220
|
"grokcli",
|
|
207
221
|
"hermesagent",
|
|
222
|
+
"kimi-code",
|
|
208
223
|
"kilo",
|
|
209
224
|
"kiro",
|
|
210
225
|
"kiro-cli",
|
|
@@ -227,6 +242,7 @@ const commandsProcessorToolTargetTuple = [
|
|
|
227
242
|
"antigravity-ide",
|
|
228
243
|
"augmentcode",
|
|
229
244
|
"claudecode",
|
|
245
|
+
"claudecode-plugin",
|
|
230
246
|
"claudecode-legacy",
|
|
231
247
|
"cline",
|
|
232
248
|
"codexcli",
|
|
@@ -254,6 +270,7 @@ const subagentsProcessorToolTargetTuple = [
|
|
|
254
270
|
"agentsmd",
|
|
255
271
|
"augmentcode",
|
|
256
272
|
"claudecode",
|
|
273
|
+
"claudecode-plugin",
|
|
257
274
|
"claudecode-legacy",
|
|
258
275
|
"cline",
|
|
259
276
|
"codexcli",
|
|
@@ -266,6 +283,7 @@ const subagentsProcessorToolTargetTuple = [
|
|
|
266
283
|
"goose",
|
|
267
284
|
"grokcli",
|
|
268
285
|
"hermesagent",
|
|
286
|
+
"kimi-code",
|
|
269
287
|
"junie",
|
|
270
288
|
"kiro",
|
|
271
289
|
"kiro-cli",
|
|
@@ -285,8 +303,10 @@ const skillsProcessorToolTargetTuple = [
|
|
|
285
303
|
"amp",
|
|
286
304
|
"antigravity-cli",
|
|
287
305
|
"antigravity-ide",
|
|
306
|
+
"antigravity-plugin",
|
|
288
307
|
"augmentcode",
|
|
289
308
|
"claudecode",
|
|
309
|
+
"claudecode-plugin",
|
|
290
310
|
"claudecode-legacy",
|
|
291
311
|
"cline",
|
|
292
312
|
"codexcli",
|
|
@@ -298,6 +318,7 @@ const skillsProcessorToolTargetTuple = [
|
|
|
298
318
|
"goose",
|
|
299
319
|
"grokcli",
|
|
300
320
|
"hermesagent",
|
|
321
|
+
"kimi-code",
|
|
301
322
|
"junie",
|
|
302
323
|
"kilo",
|
|
303
324
|
"kiro",
|
|
@@ -320,9 +341,11 @@ const hooksProcessorToolTargetTuple = [
|
|
|
320
341
|
"amp",
|
|
321
342
|
"antigravity-cli",
|
|
322
343
|
"antigravity-ide",
|
|
344
|
+
"antigravity-plugin",
|
|
323
345
|
"kilo",
|
|
324
346
|
"cursor",
|
|
325
347
|
"claudecode",
|
|
348
|
+
"claudecode-plugin",
|
|
326
349
|
"codexcli",
|
|
327
350
|
"copilot",
|
|
328
351
|
"copilotcli",
|
|
@@ -331,6 +354,7 @@ const hooksProcessorToolTargetTuple = [
|
|
|
331
354
|
"factorydroid",
|
|
332
355
|
"goose",
|
|
333
356
|
"hermesagent",
|
|
357
|
+
"kimi-code",
|
|
334
358
|
"deepagents",
|
|
335
359
|
"kiro",
|
|
336
360
|
"kiro-cli",
|
|
@@ -358,6 +382,7 @@ const permissionsProcessorToolTargetTuple = [
|
|
|
358
382
|
"goose",
|
|
359
383
|
"grokcli",
|
|
360
384
|
"hermesagent",
|
|
385
|
+
"kimi-code",
|
|
361
386
|
"junie",
|
|
362
387
|
"kilo",
|
|
363
388
|
"kiro",
|
|
@@ -388,6 +413,7 @@ const ALL_TOOL_TARGETS = [...new Set([
|
|
|
388
413
|
].flat())];
|
|
389
414
|
const ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
390
415
|
const ToolTargetSchema = z.enum(ALL_TOOL_TARGETS);
|
|
416
|
+
const PACKAGING_TOOL_TARGETS = ["antigravity-plugin", "claudecode-plugin"];
|
|
391
417
|
z.array(ToolTargetSchema);
|
|
392
418
|
const RulesyncTargetsSchema = z.array(z.enum(ALL_TOOL_TARGETS_WITH_WILDCARD));
|
|
393
419
|
const RulesyncConfigTargetsObjectSchema = z.record(z.string(), PerTargetFeaturesValueSchema);
|
|
@@ -543,12 +569,12 @@ async function readFileBuffer(filepath) {
|
|
|
543
569
|
return readFile(filepath);
|
|
544
570
|
}
|
|
545
571
|
/**
|
|
546
|
-
*
|
|
572
|
+
* Normalizes text to LF line endings and adds exactly one trailing newline.
|
|
547
573
|
* Removes any existing trailing whitespace and appends a single newline.
|
|
548
574
|
*/
|
|
549
575
|
function addTrailingNewline(content) {
|
|
550
576
|
if (!content) return "\n";
|
|
551
|
-
return content.trimEnd() + "\n";
|
|
577
|
+
return content.replaceAll("\r\n", "\n").replaceAll("\r", "\n").trimEnd() + "\n";
|
|
552
578
|
}
|
|
553
579
|
async function writeFileContent(filepath, content) {
|
|
554
580
|
await ensureDir(dirname(filepath));
|
|
@@ -584,7 +610,7 @@ async function listDirectoryFiles(dir) {
|
|
|
584
610
|
}
|
|
585
611
|
}
|
|
586
612
|
async function findFilesByGlobs(globs, options = {}) {
|
|
587
|
-
const { type = "all" } = options;
|
|
613
|
+
const { type = "all", followSymbolicLinks = true } = options;
|
|
588
614
|
const globbyOptions = type === "file" ? {
|
|
589
615
|
onlyFiles: true,
|
|
590
616
|
onlyDirectories: false
|
|
@@ -597,7 +623,7 @@ async function findFilesByGlobs(globs, options = {}) {
|
|
|
597
623
|
};
|
|
598
624
|
const results = globbySync(Array.isArray(globs) ? globs.map((g) => g.replaceAll("\\", "/")) : globs.replaceAll("\\", "/"), {
|
|
599
625
|
absolute: true,
|
|
600
|
-
followSymbolicLinks
|
|
626
|
+
followSymbolicLinks,
|
|
601
627
|
...globbyOptions
|
|
602
628
|
});
|
|
603
629
|
const seenRealPaths = /* @__PURE__ */ new Set();
|
|
@@ -1010,12 +1036,13 @@ const CONFLICTING_TARGET_PAIRS = [["augmentcode", "augmentcode-legacy"], ["claud
|
|
|
1010
1036
|
*/
|
|
1011
1037
|
const LEGACY_TARGETS = ["augmentcode-legacy", "claudecode-legacy"];
|
|
1012
1038
|
/**
|
|
1013
|
-
* Expand the wildcard target (`*`) to every non-legacy tool target.
|
|
1014
|
-
* targets are excluded because they must be
|
|
1015
|
-
* `Config.getTargets()` and
|
|
1039
|
+
* Expand the wildcard target (`*`) to every ordinary non-legacy tool target.
|
|
1040
|
+
* Legacy aliases and package-root targets are excluded because they must be
|
|
1041
|
+
* requested explicitly. Shared by `Config.getTargets()` and
|
|
1042
|
+
* `extractConfigFileTargets()` so the two never drift.
|
|
1016
1043
|
*/
|
|
1017
1044
|
function expandWildcardTargets() {
|
|
1018
|
-
return ALL_TOOL_TARGETS.filter((target) => !LEGACY_TARGETS.includes(target));
|
|
1045
|
+
return ALL_TOOL_TARGETS.filter((target) => !LEGACY_TARGETS.includes(target) && !PACKAGING_TOOL_TARGETS.includes(target));
|
|
1019
1046
|
}
|
|
1020
1047
|
/**
|
|
1021
1048
|
* Validates that the user-authored config does not double-define the
|
|
@@ -1165,7 +1192,7 @@ var Config = class Config {
|
|
|
1165
1192
|
getTargets() {
|
|
1166
1193
|
if (this.objectFormTargetKeys !== void 0) return this.objectFormTargetKeys;
|
|
1167
1194
|
const arrayTargets = Array.isArray(this.targets) ? this.targets : [];
|
|
1168
|
-
if (arrayTargets.includes("*")) return expandWildcardTargets();
|
|
1195
|
+
if (arrayTargets.includes("*")) return [.../* @__PURE__ */ new Set([...expandWildcardTargets(), ...arrayTargets.filter((target) => target !== "*")])];
|
|
1169
1196
|
return arrayTargets.filter((target) => target !== "*");
|
|
1170
1197
|
}
|
|
1171
1198
|
getConfigFileTargets() {
|
|
@@ -1547,7 +1574,7 @@ function extractConfigFileTargets(targets) {
|
|
|
1547
1574
|
if (targets === void 0) return void 0;
|
|
1548
1575
|
const validTargets = new Set(ALL_TOOL_TARGETS);
|
|
1549
1576
|
if (isRulesyncConfigTargetsObject(targets)) return Object.keys(targets).filter((key) => validTargets.has(key));
|
|
1550
|
-
if (targets.includes("*")) return expandWildcardTargets();
|
|
1577
|
+
if (targets.includes("*")) return [.../* @__PURE__ */ new Set([...expandWildcardTargets(), ...targets.filter((key) => key !== "*" && validTargets.has(key))])];
|
|
1551
1578
|
return targets.filter((key) => key !== "*" && validTargets.has(key));
|
|
1552
1579
|
}
|
|
1553
1580
|
//#endregion
|
|
@@ -1943,7 +1970,7 @@ const hasControlChars = (val) => CONTROL_CHARS.some((char) => val.includes(char)
|
|
|
1943
1970
|
const safeString = z.pipe(z.string(), z.custom((val) => typeof val === "string" && !hasControlChars(val), "must not contain newline, carriage return, or NUL characters"));
|
|
1944
1971
|
/**
|
|
1945
1972
|
* Canonical hook definition.
|
|
1946
|
-
* Used in .rulesync/hooks.
|
|
1973
|
+
* Used in .rulesync/hooks.jsonc and mapped to tool-specific formats.
|
|
1947
1974
|
*/
|
|
1948
1975
|
const HookDefinitionSchema = z.looseObject({
|
|
1949
1976
|
command: z.optional(safeString),
|
|
@@ -1957,6 +1984,7 @@ const HookDefinitionSchema = z.looseObject({
|
|
|
1957
1984
|
])),
|
|
1958
1985
|
url: z.optional(safeString),
|
|
1959
1986
|
timeout: z.optional(z.number()),
|
|
1987
|
+
cacheTtl: z.optional(z.number().check(nonnegative())),
|
|
1960
1988
|
matcher: z.optional(safeString),
|
|
1961
1989
|
prompt: z.optional(safeString),
|
|
1962
1990
|
loop_limit: z.optional(z.nullable(z.number())),
|
|
@@ -2496,6 +2524,51 @@ const GROKCLI_HOOK_EVENTS = [
|
|
|
2496
2524
|
"postCompact"
|
|
2497
2525
|
];
|
|
2498
2526
|
/**
|
|
2527
|
+
* Hook events supported by Kimi Code.
|
|
2528
|
+
*
|
|
2529
|
+
* Kimi Code also exposes `Interrupt`, which has no canonical rulesync event.
|
|
2530
|
+
*
|
|
2531
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/hooks.html
|
|
2532
|
+
*/
|
|
2533
|
+
const KIMI_CODE_HOOK_EVENTS = [
|
|
2534
|
+
"sessionStart",
|
|
2535
|
+
"sessionEnd",
|
|
2536
|
+
"beforeSubmitPrompt",
|
|
2537
|
+
"preToolUse",
|
|
2538
|
+
"postToolUse",
|
|
2539
|
+
"postToolUseFailure",
|
|
2540
|
+
"permissionRequest",
|
|
2541
|
+
"stop",
|
|
2542
|
+
"stopFailure",
|
|
2543
|
+
"notification",
|
|
2544
|
+
"subagentStart",
|
|
2545
|
+
"subagentStop",
|
|
2546
|
+
"preCompact",
|
|
2547
|
+
"postCompact"
|
|
2548
|
+
];
|
|
2549
|
+
const CANONICAL_TO_KIMI_CODE_EVENT_NAMES = {
|
|
2550
|
+
sessionStart: "SessionStart",
|
|
2551
|
+
sessionEnd: "SessionEnd",
|
|
2552
|
+
beforeSubmitPrompt: "UserPromptSubmit",
|
|
2553
|
+
preToolUse: "PreToolUse",
|
|
2554
|
+
postToolUse: "PostToolUse",
|
|
2555
|
+
postToolUseFailure: "PostToolUseFailure",
|
|
2556
|
+
permissionRequest: "PermissionRequest",
|
|
2557
|
+
stop: "Stop",
|
|
2558
|
+
stopFailure: "StopFailure",
|
|
2559
|
+
notification: "Notification",
|
|
2560
|
+
subagentStart: "SubagentStart",
|
|
2561
|
+
subagentStop: "SubagentStop",
|
|
2562
|
+
preCompact: "PreCompact",
|
|
2563
|
+
postCompact: "PostCompact"
|
|
2564
|
+
};
|
|
2565
|
+
const KIMI_CODE_NATIVE_HOOK_EVENTS = [
|
|
2566
|
+
...Object.values(CANONICAL_TO_KIMI_CODE_EVENT_NAMES),
|
|
2567
|
+
"PermissionResult",
|
|
2568
|
+
"Interrupt"
|
|
2569
|
+
];
|
|
2570
|
+
const KIMI_CODE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_KIMI_CODE_EVENT_NAMES).map(([canonical, kimiCode]) => [kimiCode, canonical]));
|
|
2571
|
+
/**
|
|
2499
2572
|
* Hook events supported by Hermes Agent's native Shell Hooks system.
|
|
2500
2573
|
*
|
|
2501
2574
|
* Hermes validates hook events against a fixed `VALID_HOOKS` set:
|
|
@@ -2586,6 +2659,7 @@ const HooksConfigSchema = z.looseObject({
|
|
|
2586
2659
|
vibe: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
2587
2660
|
reasonix: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
2588
2661
|
grokcli: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
2662
|
+
"kimi-code": z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
2589
2663
|
qwencode: z.optional(z.looseObject({
|
|
2590
2664
|
hooks: z.optional(hooksRecordSchema),
|
|
2591
2665
|
disableAllHooks: z.optional(z.boolean())
|
|
@@ -3112,6 +3186,28 @@ function parseJsonc(content) {
|
|
|
3112
3186
|
return deepSanitize(result);
|
|
3113
3187
|
}
|
|
3114
3188
|
//#endregion
|
|
3189
|
+
//#region src/utils/rulesync-source-path.ts
|
|
3190
|
+
function getRulesyncSourceCandidates({ paths }) {
|
|
3191
|
+
return [paths.recommended, ...paths.legacy];
|
|
3192
|
+
}
|
|
3193
|
+
async function resolveRulesyncSourceWritePath({ outputRoot, paths }) {
|
|
3194
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3195
|
+
const targetPath = join(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3196
|
+
if (await fileExists(targetPath)) {
|
|
3197
|
+
await assertWritablePathInsideRoot({
|
|
3198
|
+
rootPath: outputRoot,
|
|
3199
|
+
targetPath
|
|
3200
|
+
});
|
|
3201
|
+
return candidate;
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
await assertWritablePathInsideRoot({
|
|
3205
|
+
rootPath: outputRoot,
|
|
3206
|
+
targetPath: join(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath)
|
|
3207
|
+
});
|
|
3208
|
+
return paths.recommended;
|
|
3209
|
+
}
|
|
3210
|
+
//#endregion
|
|
3115
3211
|
//#region src/features/hooks/rulesync-hooks.ts
|
|
3116
3212
|
var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
3117
3213
|
json;
|
|
@@ -3125,12 +3221,14 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3125
3221
|
}
|
|
3126
3222
|
static getSettablePaths() {
|
|
3127
3223
|
return {
|
|
3128
|
-
|
|
3129
|
-
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
3130
|
-
jsonc: {
|
|
3224
|
+
recommended: {
|
|
3131
3225
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3132
|
-
relativeFilePath:
|
|
3133
|
-
}
|
|
3226
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME
|
|
3227
|
+
},
|
|
3228
|
+
legacy: [{
|
|
3229
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3230
|
+
relativeFilePath: RULESYNC_HOOKS_LEGACY_FILE_NAME
|
|
3231
|
+
}]
|
|
3134
3232
|
};
|
|
3135
3233
|
}
|
|
3136
3234
|
validate() {
|
|
@@ -3146,11 +3244,7 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3146
3244
|
}
|
|
3147
3245
|
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
3148
3246
|
const paths = RulesyncHooks.getSettablePaths();
|
|
3149
|
-
const
|
|
3150
|
-
relativeDirPath: paths.relativeDirPath,
|
|
3151
|
-
relativeFilePath: paths.relativeFilePath
|
|
3152
|
-
}];
|
|
3153
|
-
for (const candidate of candidates) {
|
|
3247
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3154
3248
|
const filePath = join(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3155
3249
|
if (!await fileExists(filePath)) continue;
|
|
3156
3250
|
const fileContent = await readFileContent(filePath);
|
|
@@ -3162,7 +3256,7 @@ var RulesyncHooks = class RulesyncHooks extends RulesyncFile {
|
|
|
3162
3256
|
validate
|
|
3163
3257
|
});
|
|
3164
3258
|
}
|
|
3165
|
-
throw new Error(`No ${RULESYNC_HOOKS_RELATIVE_FILE_PATH} or ${
|
|
3259
|
+
throw new Error(`No ${RULESYNC_HOOKS_RELATIVE_FILE_PATH} or ${RULESYNC_HOOKS_LEGACY_RELATIVE_FILE_PATH} found.`);
|
|
3166
3260
|
}
|
|
3167
3261
|
getJson() {
|
|
3168
3262
|
return this.json;
|
|
@@ -3280,8 +3374,8 @@ const RulesyncMcpConfigSchema = z.object({ mcpServers: z.record(z.string(), Rule
|
|
|
3280
3374
|
* Tool-scoped MCP block: servers that apply only to one tool. A named entry
|
|
3281
3375
|
* replaces/adds the same-named shared server wholesale for that tool; `null`
|
|
3282
3376
|
* removes the shared server for that tool. Mirrors `{toolname}.hooks` in
|
|
3283
|
-
* `.rulesync/hooks.
|
|
3284
|
-
* `.rulesync/permissions.
|
|
3377
|
+
* `.rulesync/hooks.jsonc` and `{toolname}.permission` in
|
|
3378
|
+
* `.rulesync/permissions.jsonc`.
|
|
3285
3379
|
*/
|
|
3286
3380
|
const toolScopedMcpSchema = z.looseObject({ mcpServers: z.optional(z.record(z.string(), z.nullable(RulesyncMcpServerSchema))) });
|
|
3287
3381
|
const RulesyncMcpFileSchema = z.looseObject({
|
|
@@ -3306,6 +3400,7 @@ const RulesyncMcpFileSchema = z.looseObject({
|
|
|
3306
3400
|
hermesagent: z.optional(toolScopedMcpSchema),
|
|
3307
3401
|
junie: z.optional(toolScopedMcpSchema),
|
|
3308
3402
|
kilo: z.optional(toolScopedMcpSchema),
|
|
3403
|
+
"kimi-code": z.optional(toolScopedMcpSchema),
|
|
3309
3404
|
kiro: z.optional(toolScopedMcpSchema),
|
|
3310
3405
|
opencode: z.optional(toolScopedMcpSchema),
|
|
3311
3406
|
qwencode: z.optional(toolScopedMcpSchema),
|
|
@@ -3333,14 +3428,13 @@ var RulesyncMcp = class RulesyncMcp extends RulesyncFile {
|
|
|
3333
3428
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3334
3429
|
relativeFilePath: RULESYNC_MCP_FILE_NAME
|
|
3335
3430
|
},
|
|
3336
|
-
|
|
3431
|
+
legacy: [{
|
|
3337
3432
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3338
|
-
relativeFilePath:
|
|
3339
|
-
},
|
|
3340
|
-
legacy: {
|
|
3433
|
+
relativeFilePath: RULESYNC_MCP_LEGACY_FILE_NAME
|
|
3434
|
+
}, {
|
|
3341
3435
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
3342
3436
|
relativeFilePath: ".mcp.json"
|
|
3343
|
-
}
|
|
3437
|
+
}]
|
|
3344
3438
|
};
|
|
3345
3439
|
}
|
|
3346
3440
|
validate() {
|
|
@@ -3356,41 +3450,23 @@ var RulesyncMcp = class RulesyncMcp extends RulesyncFile {
|
|
|
3356
3450
|
}
|
|
3357
3451
|
static async fromFile({ outputRoot = process.cwd(), validate = true, logger }) {
|
|
3358
3452
|
const paths = this.getSettablePaths();
|
|
3359
|
-
const
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
relativeFilePath: paths.jsonc.relativeFilePath,
|
|
3368
|
-
fileContent,
|
|
3369
|
-
validate
|
|
3370
|
-
});
|
|
3371
|
-
}
|
|
3372
|
-
if (await fileExists(recommendedPath)) {
|
|
3373
|
-
const fileContent = await readFileContent(recommendedPath);
|
|
3374
|
-
return new RulesyncMcp({
|
|
3375
|
-
outputRoot,
|
|
3376
|
-
relativeDirPath: paths.recommended.relativeDirPath,
|
|
3377
|
-
relativeFilePath: paths.recommended.relativeFilePath,
|
|
3378
|
-
fileContent,
|
|
3379
|
-
validate
|
|
3380
|
-
});
|
|
3381
|
-
}
|
|
3382
|
-
if (await fileExists(legacyPath)) {
|
|
3383
|
-
logger?.warn(`⚠️ Using deprecated path "${legacyPath}". Please migrate to "${recommendedPath}"`);
|
|
3384
|
-
const fileContent = await readFileContent(legacyPath);
|
|
3453
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
3454
|
+
const filePath = join(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
3455
|
+
if (!await fileExists(filePath)) continue;
|
|
3456
|
+
if (candidate.relativeFilePath === ".mcp.json") {
|
|
3457
|
+
const recommendedPath = join(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath);
|
|
3458
|
+
logger?.warn(`⚠️ Using deprecated path "${filePath}". Please migrate to "${recommendedPath}"`);
|
|
3459
|
+
}
|
|
3460
|
+
const fileContent = await readFileContent(filePath);
|
|
3385
3461
|
return new RulesyncMcp({
|
|
3386
3462
|
outputRoot,
|
|
3387
|
-
relativeDirPath:
|
|
3388
|
-
relativeFilePath:
|
|
3463
|
+
relativeDirPath: candidate.relativeDirPath,
|
|
3464
|
+
relativeFilePath: candidate.relativeFilePath,
|
|
3389
3465
|
fileContent,
|
|
3390
3466
|
validate
|
|
3391
3467
|
});
|
|
3392
3468
|
}
|
|
3393
|
-
const fileContent = await readFileContent(
|
|
3469
|
+
const fileContent = await readFileContent(join(outputRoot, paths.recommended.relativeDirPath, paths.recommended.relativeFilePath));
|
|
3394
3470
|
return new RulesyncMcp({
|
|
3395
3471
|
outputRoot,
|
|
3396
3472
|
relativeDirPath: paths.recommended.relativeDirPath,
|
|
@@ -3591,7 +3667,7 @@ const PermissionRulesSchema = z.record(z.string(), PermissionActionSchema);
|
|
|
3591
3667
|
* key it appears under. During generation the categories placed here are
|
|
3592
3668
|
* merged over the shared `permission` block per category (the tool-scoped
|
|
3593
3669
|
* category replaces the shared one wholesale), mirroring how
|
|
3594
|
-
* `.rulesync/hooks.
|
|
3670
|
+
* `.rulesync/hooks.jsonc` merges `{toolname}.hooks` per event.
|
|
3595
3671
|
*
|
|
3596
3672
|
* @example
|
|
3597
3673
|
* { "claudecode": { "permission": { "bash": { "git push *": "deny" } } } }
|
|
@@ -3604,6 +3680,25 @@ const ToolScopedPermissionSchema = z.record(z.string(), PermissionRulesSchema);
|
|
|
3604
3680
|
* added without a schema break.
|
|
3605
3681
|
*/
|
|
3606
3682
|
const CanonicalPermissionsOverrideSchema = z.looseObject({ permission: z.optional(ToolScopedPermissionSchema) });
|
|
3683
|
+
const KimiCodePermissionsOverrideSchema = z.looseObject({
|
|
3684
|
+
permission: z.optional(ToolScopedPermissionSchema),
|
|
3685
|
+
defaultPermissionMode: z.optional(z.enum([
|
|
3686
|
+
"manual",
|
|
3687
|
+
"yolo",
|
|
3688
|
+
"auto"
|
|
3689
|
+
])),
|
|
3690
|
+
rules: z.optional(z.array(z.looseObject({
|
|
3691
|
+
decision: PermissionActionSchema,
|
|
3692
|
+
pattern: z.string(),
|
|
3693
|
+
scope: z.optional(z.enum([
|
|
3694
|
+
"turn-override",
|
|
3695
|
+
"session-runtime",
|
|
3696
|
+
"project",
|
|
3697
|
+
"user"
|
|
3698
|
+
])),
|
|
3699
|
+
reason: z.optional(z.string())
|
|
3700
|
+
})))
|
|
3701
|
+
});
|
|
3607
3702
|
/**
|
|
3608
3703
|
* OpenCode-specific permission value. Unlike the shared canonical block, which
|
|
3609
3704
|
* only accepts a pattern-to-action map, OpenCode also allows a bare action
|
|
@@ -4195,6 +4290,7 @@ const PermissionsConfigSchema = z.looseObject({
|
|
|
4195
4290
|
devin: z.optional(CanonicalPermissionsOverrideSchema),
|
|
4196
4291
|
goose: z.optional(CanonicalPermissionsOverrideSchema),
|
|
4197
4292
|
grokcli: z.optional(CanonicalPermissionsOverrideSchema),
|
|
4293
|
+
"kimi-code": z.optional(KimiCodePermissionsOverrideSchema),
|
|
4198
4294
|
rovodev: z.optional(CanonicalPermissionsOverrideSchema),
|
|
4199
4295
|
zed: z.optional(CanonicalPermissionsOverrideSchema)
|
|
4200
4296
|
});
|
|
@@ -4219,12 +4315,14 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4219
4315
|
}
|
|
4220
4316
|
static getSettablePaths() {
|
|
4221
4317
|
return {
|
|
4222
|
-
|
|
4223
|
-
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
4224
|
-
jsonc: {
|
|
4318
|
+
recommended: {
|
|
4225
4319
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
4226
|
-
relativeFilePath:
|
|
4227
|
-
}
|
|
4320
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME
|
|
4321
|
+
},
|
|
4322
|
+
legacy: [{
|
|
4323
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
4324
|
+
relativeFilePath: RULESYNC_PERMISSIONS_LEGACY_FILE_NAME
|
|
4325
|
+
}]
|
|
4228
4326
|
};
|
|
4229
4327
|
}
|
|
4230
4328
|
validate() {
|
|
@@ -4240,11 +4338,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4240
4338
|
}
|
|
4241
4339
|
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
4242
4340
|
const paths = RulesyncPermissions.getSettablePaths();
|
|
4243
|
-
const
|
|
4244
|
-
relativeDirPath: paths.relativeDirPath,
|
|
4245
|
-
relativeFilePath: paths.relativeFilePath
|
|
4246
|
-
}];
|
|
4247
|
-
for (const candidate of candidates) {
|
|
4341
|
+
for (const candidate of getRulesyncSourceCandidates({ paths })) {
|
|
4248
4342
|
const filePath = join(outputRoot, candidate.relativeDirPath, candidate.relativeFilePath);
|
|
4249
4343
|
if (!await fileExists(filePath)) continue;
|
|
4250
4344
|
const fileContent = await readFileContent(filePath);
|
|
@@ -4256,7 +4350,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4256
4350
|
validate
|
|
4257
4351
|
});
|
|
4258
4352
|
}
|
|
4259
|
-
throw new Error(`No ${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH} or ${
|
|
4353
|
+
throw new Error(`No ${RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH} or ${RULESYNC_PERMISSIONS_LEGACY_RELATIVE_FILE_PATH} found.`);
|
|
4260
4354
|
}
|
|
4261
4355
|
getJson() {
|
|
4262
4356
|
return this.json;
|
|
@@ -4266,7 +4360,7 @@ var RulesyncPermissions = class RulesyncPermissions extends RulesyncFile {
|
|
|
4266
4360
|
* tool-scoped `{toolname}.permission` block over the shared `permission`
|
|
4267
4361
|
* block, per category (the tool-scoped category replaces the shared one
|
|
4268
4362
|
* wholesale — mirroring how `{toolname}.hooks` merges per event in
|
|
4269
|
-
* `.rulesync/hooks.
|
|
4363
|
+
* `.rulesync/hooks.jsonc`). The consumed `permission` key is stripped from
|
|
4270
4364
|
* the override block so verbatim-passthrough translators (e.g. the Hermes
|
|
4271
4365
|
* deep merge or the Codex CLI top-level key whitelist) never see it.
|
|
4272
4366
|
*
|
|
@@ -4631,6 +4725,16 @@ const RulesyncSkillFrontmatterSchema = z.looseObject({
|
|
|
4631
4725
|
"disable-model-invocation": z.optional(z.boolean()),
|
|
4632
4726
|
"user-invocable": z.optional(z.boolean())
|
|
4633
4727
|
})),
|
|
4728
|
+
"kimi-code": z.optional(z.looseObject({
|
|
4729
|
+
type: z.optional(z.enum([
|
|
4730
|
+
"prompt",
|
|
4731
|
+
"inline",
|
|
4732
|
+
"flow"
|
|
4733
|
+
])),
|
|
4734
|
+
whenToUse: z.optional(z.string()),
|
|
4735
|
+
disableModelInvocation: z.optional(z.boolean()),
|
|
4736
|
+
arguments: z.optional(z.union([z.string(), z.array(z.string())]))
|
|
4737
|
+
})),
|
|
4634
4738
|
agentsskills: z.optional(z.looseObject({
|
|
4635
4739
|
license: z.optional(z.string()),
|
|
4636
4740
|
compatibility: z.optional(z.union([z.string(), z.looseObject({})])),
|
|
@@ -6332,6 +6436,28 @@ var ClaudecodeCommand = class ClaudecodeCommand extends ToolCommand {
|
|
|
6332
6436
|
}
|
|
6333
6437
|
};
|
|
6334
6438
|
//#endregion
|
|
6439
|
+
//#region src/constants/plugin-paths.ts
|
|
6440
|
+
const CLAUDECODE_PLUGIN_COMMANDS_DIR = "commands";
|
|
6441
|
+
const CLAUDECODE_PLUGIN_AGENTS_DIR = "agents";
|
|
6442
|
+
const CLAUDECODE_PLUGIN_SKILLS_DIR = "skills";
|
|
6443
|
+
const CLAUDECODE_PLUGIN_HOOKS_DIR = "hooks";
|
|
6444
|
+
const CLAUDECODE_PLUGIN_HOOKS_FILE_NAME = "hooks.json";
|
|
6445
|
+
const ANTIGRAVITY_PLUGIN_RULES_DIR = "rules";
|
|
6446
|
+
const ANTIGRAVITY_PLUGIN_SKILLS_DIR = "skills";
|
|
6447
|
+
const ANTIGRAVITY_PLUGIN_MCP_FILE_NAME = "mcp_config.json";
|
|
6448
|
+
const ANTIGRAVITY_PLUGIN_HOOKS_FILE_NAME = "hooks.json";
|
|
6449
|
+
//#endregion
|
|
6450
|
+
//#region src/features/commands/claudecode-plugin-command.ts
|
|
6451
|
+
var ClaudecodePluginCommand = class extends ClaudecodeCommand {
|
|
6452
|
+
static isTargetedByRulesyncCommand(rulesyncCommand) {
|
|
6453
|
+
const targets = rulesyncCommand.getFrontmatter().targets;
|
|
6454
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
6455
|
+
}
|
|
6456
|
+
static getSettablePaths() {
|
|
6457
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_COMMANDS_DIR };
|
|
6458
|
+
}
|
|
6459
|
+
};
|
|
6460
|
+
//#endregion
|
|
6335
6461
|
//#region src/constants/cline-paths.ts
|
|
6336
6462
|
const CLINE_DIR = ".cline";
|
|
6337
6463
|
const CLINERULES_DIR = ".clinerules";
|
|
@@ -7347,6 +7473,7 @@ const TAKT_CONFIG_SHARED_FILE_KEY = ".takt/config.yaml";
|
|
|
7347
7473
|
const CODEXCLI_CONFIG_SHARED_FILE_KEY = ".codex/config.toml";
|
|
7348
7474
|
const GROKCLI_CONFIG_SHARED_FILE_KEY = ".grok/config.toml";
|
|
7349
7475
|
const VIBE_CONFIG_SHARED_FILE_KEY = ".vibe/config.toml";
|
|
7476
|
+
const KIMI_CODE_CONFIG_SHARED_FILE_KEY = ".kimi-code/config.toml";
|
|
7350
7477
|
const REASONIX_PROJECT_CONFIG_SHARED_FILE_KEY = "reasonix.toml";
|
|
7351
7478
|
const REASONIX_GLOBAL_CONFIG_SHARED_FILE_KEY = ".reasonix/config.toml";
|
|
7352
7479
|
/**
|
|
@@ -7691,6 +7818,20 @@ const SHARED_CONFIG_OWNERSHIP = {
|
|
|
7691
7818
|
}
|
|
7692
7819
|
}
|
|
7693
7820
|
},
|
|
7821
|
+
[KIMI_CODE_CONFIG_SHARED_FILE_KEY]: {
|
|
7822
|
+
format: "toml",
|
|
7823
|
+
invalidRootPolicy: "error",
|
|
7824
|
+
features: {
|
|
7825
|
+
hooks: {
|
|
7826
|
+
kind: "replace-owned-keys",
|
|
7827
|
+
ownedKeys: ["hooks"]
|
|
7828
|
+
},
|
|
7829
|
+
permissions: {
|
|
7830
|
+
kind: "replace-owned-keys",
|
|
7831
|
+
ownedKeys: ["permission", "default_permission_mode"]
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
},
|
|
7694
7835
|
[REASONIX_PROJECT_CONFIG_SHARED_FILE_KEY]: {
|
|
7695
7836
|
format: "toml",
|
|
7696
7837
|
features: {
|
|
@@ -7825,6 +7966,10 @@ const applyPermissions = (params) => {
|
|
|
7825
7966
|
function toolSkillSearchRoots(paths) {
|
|
7826
7967
|
return [paths.relativeDirPath, ...paths.alternativeSkillRoots ?? []];
|
|
7827
7968
|
}
|
|
7969
|
+
/** Ordered import roots: managed roots first, followed by read-only discovery roots. */
|
|
7970
|
+
function toolSkillImportRoots(paths) {
|
|
7971
|
+
return [...toolSkillSearchRoots(paths), ...paths.importOnlySkillRoots ?? []];
|
|
7972
|
+
}
|
|
7828
7973
|
/**
|
|
7829
7974
|
* Abstract base class for AI development tool-specific skill formats.
|
|
7830
7975
|
*
|
|
@@ -7907,6 +8052,13 @@ var ToolSkill = class extends AiDir {
|
|
|
7907
8052
|
throw new Error("Please implement this method in the subclass.");
|
|
7908
8053
|
}
|
|
7909
8054
|
/**
|
|
8055
|
+
* Identity used to resolve duplicates across discovery roots during import.
|
|
8056
|
+
* Most tools identify a skill by its directory name.
|
|
8057
|
+
*/
|
|
8058
|
+
getImportIdentity() {
|
|
8059
|
+
return this.getDirName();
|
|
8060
|
+
}
|
|
8061
|
+
/**
|
|
7910
8062
|
* Load and parse skill directory content.
|
|
7911
8063
|
* This is a helper method that handles the common logic of reading SKILL.md,
|
|
7912
8064
|
* parsing frontmatter, and collecting other files.
|
|
@@ -8658,6 +8810,7 @@ const KIRO_IDE_HOOKS_DIR_PATH = join(KIRO_DIR, "hooks");
|
|
|
8658
8810
|
const KIRO_IDE_HOOKS_FILE_NAME = "rulesync.json";
|
|
8659
8811
|
const KIRO_MCP_FILE_NAME = "mcp.json";
|
|
8660
8812
|
const KIRO_IGNORE_FILE_NAME = ".kiroignore";
|
|
8813
|
+
const KIRO_GLOBAL_IGNORE_FILE_NAME = "kiroignore";
|
|
8661
8814
|
//#endregion
|
|
8662
8815
|
//#region src/features/commands/kiro-command.ts
|
|
8663
8816
|
var KiroCommand = class KiroCommand extends ToolCommand {
|
|
@@ -9938,6 +10091,16 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
9938
10091
|
supportsSubdirectory: true
|
|
9939
10092
|
}
|
|
9940
10093
|
}],
|
|
10094
|
+
["claudecode-plugin", {
|
|
10095
|
+
class: ClaudecodePluginCommand,
|
|
10096
|
+
meta: {
|
|
10097
|
+
extension: "md",
|
|
10098
|
+
supportsProject: true,
|
|
10099
|
+
supportsGlobal: false,
|
|
10100
|
+
isSimulated: false,
|
|
10101
|
+
supportsSubdirectory: true
|
|
10102
|
+
}
|
|
10103
|
+
}],
|
|
9941
10104
|
["claudecode-legacy", {
|
|
9942
10105
|
class: ClaudecodeCommand,
|
|
9943
10106
|
meta: {
|
|
@@ -10475,7 +10638,7 @@ var ToolHooks = class extends ToolFile {
|
|
|
10475
10638
|
return new RulesyncHooks({
|
|
10476
10639
|
outputRoot: this.outputRoot,
|
|
10477
10640
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
10478
|
-
relativeFilePath:
|
|
10641
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
10479
10642
|
fileContent: fileContent ?? this.fileContent
|
|
10480
10643
|
});
|
|
10481
10644
|
}
|
|
@@ -10572,7 +10735,7 @@ function isToolMatcherEntry(x) {
|
|
|
10572
10735
|
/**
|
|
10573
10736
|
* Filter the shared canonical hooks to the supported events and merge tool overrides on top.
|
|
10574
10737
|
*/
|
|
10575
|
-
function buildEffectiveHooks$
|
|
10738
|
+
function buildEffectiveHooks$2({ config, toolOverrideHooks, supportedEvents }) {
|
|
10576
10739
|
const supported = new Set(supportedEvents);
|
|
10577
10740
|
const sharedHooks = {};
|
|
10578
10741
|
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) sharedHooks[event] = defs;
|
|
@@ -10702,7 +10865,7 @@ function buildToolHooks({ defs, converterConfig }) {
|
|
|
10702
10865
|
* (e.g. beforeSubmitPrompt → UserPromptSubmit).
|
|
10703
10866
|
*/
|
|
10704
10867
|
function canonicalToToolHooks({ config, toolOverrideHooks, converterConfig, logger }) {
|
|
10705
|
-
const effectiveHooks = buildEffectiveHooks$
|
|
10868
|
+
const effectiveHooks = buildEffectiveHooks$2({
|
|
10706
10869
|
config,
|
|
10707
10870
|
toolOverrideHooks,
|
|
10708
10871
|
supportedEvents: converterConfig.supportedEvents
|
|
@@ -10839,7 +11002,7 @@ function toolMatcherEntryToCanonical({ rawEntry, converterConfig }) {
|
|
|
10839
11002
|
}
|
|
10840
11003
|
/**
|
|
10841
11004
|
* Assemble the canonical hooks config a tool importer writes to
|
|
10842
|
-
* `.rulesync/hooks.
|
|
11005
|
+
* `.rulesync/hooks.jsonc`.
|
|
10843
11006
|
*
|
|
10844
11007
|
* The top-level `hooks` record only accepts canonical event names, so any
|
|
10845
11008
|
* imported native event key without a canonical mapping is moved under the
|
|
@@ -11042,6 +11205,16 @@ var AntigravityCliHooks = class extends AntigravityHooks {
|
|
|
11042
11205
|
}
|
|
11043
11206
|
};
|
|
11044
11207
|
//#endregion
|
|
11208
|
+
//#region src/features/hooks/antigravity-plugin-hooks.ts
|
|
11209
|
+
var AntigravityPluginHooks = class extends AntigravityIdeHooks {
|
|
11210
|
+
static getSettablePaths() {
|
|
11211
|
+
return {
|
|
11212
|
+
relativeDirPath: ".",
|
|
11213
|
+
relativeFilePath: ANTIGRAVITY_PLUGIN_HOOKS_FILE_NAME
|
|
11214
|
+
};
|
|
11215
|
+
}
|
|
11216
|
+
};
|
|
11217
|
+
//#endregion
|
|
11045
11218
|
//#region src/utils/augmentcode-settings.ts
|
|
11046
11219
|
/**
|
|
11047
11220
|
* Top-level keys AugmentCode *replaces* (higher-precedence wins wholesale)
|
|
@@ -11267,7 +11440,7 @@ const CLAUDE_CONVERTER_CONFIG = {
|
|
|
11267
11440
|
tool: "if"
|
|
11268
11441
|
}]
|
|
11269
11442
|
};
|
|
11270
|
-
var ClaudecodeHooks = class
|
|
11443
|
+
var ClaudecodeHooks = class extends ToolHooks {
|
|
11271
11444
|
constructor(params) {
|
|
11272
11445
|
super({
|
|
11273
11446
|
...params,
|
|
@@ -11284,9 +11457,9 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11284
11457
|
};
|
|
11285
11458
|
}
|
|
11286
11459
|
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
11287
|
-
const paths =
|
|
11460
|
+
const paths = this.getSettablePaths({ global });
|
|
11288
11461
|
const fileContent = await readFileContentOrNull(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath)) ?? "{\"hooks\":{}}";
|
|
11289
|
-
return new
|
|
11462
|
+
return new this({
|
|
11290
11463
|
outputRoot,
|
|
11291
11464
|
relativeDirPath: paths.relativeDirPath,
|
|
11292
11465
|
relativeFilePath: paths.relativeFilePath,
|
|
@@ -11295,7 +11468,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11295
11468
|
});
|
|
11296
11469
|
}
|
|
11297
11470
|
static async fromRulesyncHooks({ outputRoot = process.cwd(), rulesyncHooks, validate = true, global = false, logger }) {
|
|
11298
|
-
const paths =
|
|
11471
|
+
const paths = this.getSettablePaths({ global });
|
|
11299
11472
|
const filePath = join(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
11300
11473
|
const existingContent = await readOrInitializeFileContent(filePath, JSON.stringify({}, null, 2));
|
|
11301
11474
|
const config = rulesyncHooks.getJson();
|
|
@@ -11311,7 +11484,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11311
11484
|
}) },
|
|
11312
11485
|
filePath
|
|
11313
11486
|
});
|
|
11314
|
-
return new
|
|
11487
|
+
return new this({
|
|
11315
11488
|
outputRoot,
|
|
11316
11489
|
relativeDirPath: paths.relativeDirPath,
|
|
11317
11490
|
relativeFilePath: paths.relativeFilePath,
|
|
@@ -11342,7 +11515,7 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11342
11515
|
};
|
|
11343
11516
|
}
|
|
11344
11517
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
11345
|
-
return new
|
|
11518
|
+
return new this({
|
|
11346
11519
|
outputRoot,
|
|
11347
11520
|
relativeDirPath,
|
|
11348
11521
|
relativeFilePath,
|
|
@@ -11352,6 +11525,19 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
11352
11525
|
}
|
|
11353
11526
|
};
|
|
11354
11527
|
//#endregion
|
|
11528
|
+
//#region src/features/hooks/claudecode-plugin-hooks.ts
|
|
11529
|
+
var ClaudecodePluginHooks = class extends ClaudecodeHooks {
|
|
11530
|
+
isDeletable() {
|
|
11531
|
+
return true;
|
|
11532
|
+
}
|
|
11533
|
+
static getSettablePaths() {
|
|
11534
|
+
return {
|
|
11535
|
+
relativeDirPath: CLAUDECODE_PLUGIN_HOOKS_DIR,
|
|
11536
|
+
relativeFilePath: CLAUDECODE_PLUGIN_HOOKS_FILE_NAME
|
|
11537
|
+
};
|
|
11538
|
+
}
|
|
11539
|
+
};
|
|
11540
|
+
//#endregion
|
|
11355
11541
|
//#region src/features/hooks/codexcli-hooks.ts
|
|
11356
11542
|
const CODEXCLI_CONVERTER_CONFIG = {
|
|
11357
11543
|
supportedEvents: CODEXCLI_HOOK_EVENTS,
|
|
@@ -12718,7 +12904,7 @@ const HERMESAGENT_MATCHER_EVENTS = /* @__PURE__ */ new Set(["preToolUse", "postT
|
|
|
12718
12904
|
* Filter the shared canonical hooks to the events Hermes understands and merge
|
|
12719
12905
|
* the `hermesagent`-specific override block on top.
|
|
12720
12906
|
*/
|
|
12721
|
-
function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
12907
|
+
function buildEffectiveHooks$1(config, toolOverrideHooks) {
|
|
12722
12908
|
const supported = new Set(HERMESAGENT_HOOK_EVENTS);
|
|
12723
12909
|
const shared = {};
|
|
12724
12910
|
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) shared[event] = defs;
|
|
@@ -12740,7 +12926,7 @@ function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
|
12740
12926
|
* matcher-less lifecycle events.
|
|
12741
12927
|
*/
|
|
12742
12928
|
function canonicalToHermesHooks({ config, toolOverrideHooks, logger }) {
|
|
12743
|
-
const effectiveHooks = buildEffectiveHooks(config, toolOverrideHooks);
|
|
12929
|
+
const effectiveHooks = buildEffectiveHooks$1(config, toolOverrideHooks);
|
|
12744
12930
|
const result = {};
|
|
12745
12931
|
for (const [canonicalEvent, defs] of Object.entries(effectiveHooks)) {
|
|
12746
12932
|
const nativeEvent = CANONICAL_TO_HERMESAGENT_EVENT_NAMES[canonicalEvent];
|
|
@@ -13180,6 +13366,197 @@ var KiloHooks = class KiloHooks extends ToolHooks {
|
|
|
13180
13366
|
}
|
|
13181
13367
|
};
|
|
13182
13368
|
//#endregion
|
|
13369
|
+
//#region src/constants/kimi-code-paths.ts
|
|
13370
|
+
const KIMI_CODE_DIR = ".kimi-code";
|
|
13371
|
+
const KIMI_CODE_RULE_FILE_NAME = "AGENTS.md";
|
|
13372
|
+
const KIMI_CODE_MCP_FILE_NAME = "mcp.json";
|
|
13373
|
+
const KIMI_CODE_CONFIG_FILE_NAME = "config.toml";
|
|
13374
|
+
const KIMI_CODE_SKILLS_DIR_NAME = "skills";
|
|
13375
|
+
const KIMI_CODE_AGENTS_DIR_NAME = "agents";
|
|
13376
|
+
const KIMI_CODE_SKILLS_DIR_PATH = join(KIMI_CODE_DIR, KIMI_CODE_SKILLS_DIR_NAME);
|
|
13377
|
+
join(KIMI_CODE_DIR, KIMI_CODE_AGENTS_DIR_NAME);
|
|
13378
|
+
const KIMI_CODE_SHARED_SKILLS_DIR_PATH = join(".agents", "skills");
|
|
13379
|
+
const KIMI_CODE_SHARED_AGENTS_DIR_PATH = join(".agents", "agents");
|
|
13380
|
+
//#endregion
|
|
13381
|
+
//#region src/utils/kimi-code.ts
|
|
13382
|
+
function getKimiCodeHome() {
|
|
13383
|
+
const configuredHome = process.env.KIMI_CODE_HOME?.trim();
|
|
13384
|
+
return configuredHome ? resolve(configuredHome) : void 0;
|
|
13385
|
+
}
|
|
13386
|
+
function resolveToolOutputRoot({ outputRoot, toolTarget, global }) {
|
|
13387
|
+
return toolTarget === "kimi-code" && global ? getKimiCodeHome() ?? outputRoot : outputRoot;
|
|
13388
|
+
}
|
|
13389
|
+
function getKimiCodeRelativeDirPath({ global, relativeDirPath = "." }) {
|
|
13390
|
+
return global && getKimiCodeHome() ? relativeDirPath : join(KIMI_CODE_DIR, relativeDirPath);
|
|
13391
|
+
}
|
|
13392
|
+
function getKimiCodeRulesyncOutputRoot({ nativeOutputRoot, global }) {
|
|
13393
|
+
return global && getKimiCodeHome() ? getHomeDirectory() : nativeOutputRoot;
|
|
13394
|
+
}
|
|
13395
|
+
//#endregion
|
|
13396
|
+
//#region src/features/hooks/kimi-code-hooks.ts
|
|
13397
|
+
function runFromTrustedDirectory({ command, trustedDirectory }) {
|
|
13398
|
+
if (process.platform === "win32") return `set "RULESYNC_KIMI_HOOK_CWD=1" && cd /d "${trustedDirectory.replaceAll("%", "%%").replaceAll("\"", "\"\"")}" && ${command}`;
|
|
13399
|
+
return `export RULESYNC_KIMI_HOOK_CWD=1 && cd -- '${trustedDirectory.replaceAll("'", `'"'"'`)}' && ${command}`;
|
|
13400
|
+
}
|
|
13401
|
+
function stripTrustedDirectoryWrapper(command) {
|
|
13402
|
+
const posix = command.match(/^export RULESYNC_KIMI_HOOK_CWD=1 && cd -- '(?:[^']|'"'"')*' && ([\s\S]*)$/);
|
|
13403
|
+
if (posix?.[1]) return posix[1];
|
|
13404
|
+
return command.match(/^set "RULESYNC_KIMI_HOOK_CWD=1" && cd \/d "(?:""|[^"])*" && ([\s\S]*)$/)?.[1] ?? command;
|
|
13405
|
+
}
|
|
13406
|
+
function buildEffectiveHooks(config, toolOverrideHooks) {
|
|
13407
|
+
const supported = new Set(KIMI_CODE_HOOK_EVENTS);
|
|
13408
|
+
const shared = {};
|
|
13409
|
+
for (const [event, definitions] of Object.entries(config.hooks)) if (supported.has(event)) shared[event] = definitions;
|
|
13410
|
+
return {
|
|
13411
|
+
...shared,
|
|
13412
|
+
...toolOverrideHooks
|
|
13413
|
+
};
|
|
13414
|
+
}
|
|
13415
|
+
function canonicalToKimiCodeHooks({ config, toolOverrideHooks, trustedDirectory, logger }) {
|
|
13416
|
+
const result = [];
|
|
13417
|
+
const nativeEvents = new Set(KIMI_CODE_NATIVE_HOOK_EVENTS);
|
|
13418
|
+
for (const [event, definitions] of Object.entries(buildEffectiveHooks(config, toolOverrideHooks))) {
|
|
13419
|
+
const nativeEvent = CANONICAL_TO_KIMI_CODE_EVENT_NAMES[event] ?? event;
|
|
13420
|
+
if (!nativeEvents.has(nativeEvent)) {
|
|
13421
|
+
logger?.warn(`Kimi Code hooks: skipping unsupported event "${event}".`);
|
|
13422
|
+
continue;
|
|
13423
|
+
}
|
|
13424
|
+
for (const definition of definitions) {
|
|
13425
|
+
if ((definition.type ?? "command") !== "command" || !definition.command) continue;
|
|
13426
|
+
const timeout = definition.timeout;
|
|
13427
|
+
const validTimeout = timeout === void 0 || Number.isInteger(timeout) && timeout >= 1 && timeout <= 600;
|
|
13428
|
+
if (!validTimeout) logger?.warn(`Kimi Code hooks: omitting invalid timeout for "${event}"; expected an integer from 1 to 600 seconds.`);
|
|
13429
|
+
result.push({
|
|
13430
|
+
event: nativeEvent,
|
|
13431
|
+
command: runFromTrustedDirectory({
|
|
13432
|
+
command: definition.command,
|
|
13433
|
+
trustedDirectory
|
|
13434
|
+
}),
|
|
13435
|
+
...definition.matcher && { matcher: definition.matcher },
|
|
13436
|
+
...validTimeout && timeout !== void 0 && { timeout }
|
|
13437
|
+
});
|
|
13438
|
+
}
|
|
13439
|
+
}
|
|
13440
|
+
return result;
|
|
13441
|
+
}
|
|
13442
|
+
function kimiCodeHooksToCanonical(hooks) {
|
|
13443
|
+
const result = {};
|
|
13444
|
+
if (!Array.isArray(hooks)) return result;
|
|
13445
|
+
for (const raw of hooks) {
|
|
13446
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
13447
|
+
const entry = raw;
|
|
13448
|
+
if (typeof entry.event !== "string" || typeof entry.command !== "string") continue;
|
|
13449
|
+
const event = KIMI_CODE_TO_CANONICAL_EVENT_NAMES[entry.event] ?? entry.event;
|
|
13450
|
+
const definition = {
|
|
13451
|
+
type: "command",
|
|
13452
|
+
command: stripTrustedDirectoryWrapper(entry.command),
|
|
13453
|
+
...typeof entry.matcher === "string" && { matcher: entry.matcher },
|
|
13454
|
+
...typeof entry.timeout === "number" && { timeout: entry.timeout }
|
|
13455
|
+
};
|
|
13456
|
+
(result[event] ??= []).push(definition);
|
|
13457
|
+
}
|
|
13458
|
+
return result;
|
|
13459
|
+
}
|
|
13460
|
+
/**
|
|
13461
|
+
* Kimi Code lifecycle hooks in the shared user `config.toml`.
|
|
13462
|
+
*
|
|
13463
|
+
* Kimi Code documents hooks only at user scope. The config file also contains
|
|
13464
|
+
* models, providers, permissions, and other settings, so the hooks patch is
|
|
13465
|
+
* merged in place and the file is never deleted.
|
|
13466
|
+
*
|
|
13467
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/hooks.html
|
|
13468
|
+
*/
|
|
13469
|
+
var KimiCodeHooks = class KimiCodeHooks extends ToolHooks {
|
|
13470
|
+
constructor(params) {
|
|
13471
|
+
super({
|
|
13472
|
+
...params,
|
|
13473
|
+
...KimiCodeHooks.getSettablePaths({ global: params.global ?? true })
|
|
13474
|
+
});
|
|
13475
|
+
}
|
|
13476
|
+
static getSettablePaths({ global = true } = {}) {
|
|
13477
|
+
return {
|
|
13478
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
13479
|
+
relativeFilePath: KIMI_CODE_CONFIG_FILE_NAME
|
|
13480
|
+
};
|
|
13481
|
+
}
|
|
13482
|
+
validate() {
|
|
13483
|
+
return {
|
|
13484
|
+
success: true,
|
|
13485
|
+
error: null
|
|
13486
|
+
};
|
|
13487
|
+
}
|
|
13488
|
+
isDeletable() {
|
|
13489
|
+
return false;
|
|
13490
|
+
}
|
|
13491
|
+
shouldMergeExistingFileContent() {
|
|
13492
|
+
return true;
|
|
13493
|
+
}
|
|
13494
|
+
setFileContent(fileContent) {
|
|
13495
|
+
const paths = KimiCodeHooks.getSettablePaths({ global: this.global });
|
|
13496
|
+
this.fileContent = applySharedConfigPatch({
|
|
13497
|
+
fileKey: KIMI_CODE_CONFIG_SHARED_FILE_KEY,
|
|
13498
|
+
feature: "hooks",
|
|
13499
|
+
existingContent: fileContent,
|
|
13500
|
+
patch: parseSharedConfig({
|
|
13501
|
+
format: "toml",
|
|
13502
|
+
fileContent: this.fileContent
|
|
13503
|
+
}),
|
|
13504
|
+
filePath: join(paths.relativeDirPath, paths.relativeFilePath)
|
|
13505
|
+
});
|
|
13506
|
+
}
|
|
13507
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = true }) {
|
|
13508
|
+
const paths = this.getSettablePaths({ global });
|
|
13509
|
+
return new KimiCodeHooks({
|
|
13510
|
+
outputRoot,
|
|
13511
|
+
fileContent: await readFileContent(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath)),
|
|
13512
|
+
validate,
|
|
13513
|
+
global
|
|
13514
|
+
});
|
|
13515
|
+
}
|
|
13516
|
+
static fromRulesyncHooks({ outputRoot, rulesyncHooks, logger }) {
|
|
13517
|
+
const config = rulesyncHooks.getJson();
|
|
13518
|
+
return new KimiCodeHooks({
|
|
13519
|
+
outputRoot,
|
|
13520
|
+
fileContent: stringifySharedConfig({
|
|
13521
|
+
format: "toml",
|
|
13522
|
+
document: { hooks: canonicalToKimiCodeHooks({
|
|
13523
|
+
config,
|
|
13524
|
+
toolOverrideHooks: config["kimi-code"]?.hooks,
|
|
13525
|
+
trustedDirectory: resolve(rulesyncHooks.getOutputRoot()),
|
|
13526
|
+
logger
|
|
13527
|
+
}) }
|
|
13528
|
+
}),
|
|
13529
|
+
global: true
|
|
13530
|
+
});
|
|
13531
|
+
}
|
|
13532
|
+
toRulesyncHooks() {
|
|
13533
|
+
const config = parseSharedConfig({
|
|
13534
|
+
format: "toml",
|
|
13535
|
+
fileContent: this.getFileContent()
|
|
13536
|
+
});
|
|
13537
|
+
return new RulesyncHooks({
|
|
13538
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
13539
|
+
nativeOutputRoot: this.outputRoot,
|
|
13540
|
+
global: this.global
|
|
13541
|
+
}),
|
|
13542
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
13543
|
+
relativeFilePath: RULESYNC_HOOKS_FILE_NAME,
|
|
13544
|
+
fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
13545
|
+
hooks: kimiCodeHooksToCanonical(config.hooks),
|
|
13546
|
+
overrideKey: "kimi-code"
|
|
13547
|
+
}), null, 2)
|
|
13548
|
+
});
|
|
13549
|
+
}
|
|
13550
|
+
static forDeletion({ outputRoot = process.cwd() }) {
|
|
13551
|
+
return new KimiCodeHooks({
|
|
13552
|
+
outputRoot,
|
|
13553
|
+
fileContent: "",
|
|
13554
|
+
validate: false,
|
|
13555
|
+
global: true
|
|
13556
|
+
});
|
|
13557
|
+
}
|
|
13558
|
+
};
|
|
13559
|
+
//#endregion
|
|
13183
13560
|
//#region src/features/hooks/kiro-hooks.ts
|
|
13184
13561
|
/**
|
|
13185
13562
|
* Convert canonical hooks config to Kiro CLI format.
|
|
@@ -13195,6 +13572,7 @@ function buildKiroEntriesForEvent(definitions) {
|
|
|
13195
13572
|
command: def.command,
|
|
13196
13573
|
...def.matcher !== void 0 && def.matcher !== null && def.matcher !== "" && { matcher: def.matcher },
|
|
13197
13574
|
...def.timeout !== void 0 && def.timeout !== null && def.timeout > 0 && { timeout_ms: def.timeout },
|
|
13575
|
+
...def.cacheTtl !== void 0 && { cache_ttl_seconds: def.cacheTtl },
|
|
13198
13576
|
...def.name !== void 0 && def.name !== null && { name: def.name },
|
|
13199
13577
|
...def.description !== void 0 && def.description !== null && { description: def.description }
|
|
13200
13578
|
});
|
|
@@ -13227,9 +13605,14 @@ const KiroHookEntrySchema = z.looseObject({
|
|
|
13227
13605
|
command: z.optional(safeString),
|
|
13228
13606
|
matcher: z.optional(z.string()),
|
|
13229
13607
|
timeout_ms: z.optional(z.number()),
|
|
13608
|
+
cache_ttl_seconds: z.optional(z.number().check(nonnegative())),
|
|
13230
13609
|
name: z.optional(z.string()),
|
|
13231
13610
|
description: z.optional(z.string())
|
|
13232
13611
|
});
|
|
13612
|
+
function importCacheTtl(entry) {
|
|
13613
|
+
if (entry.cache_ttl_seconds === void 0) return {};
|
|
13614
|
+
return { cacheTtl: entry.cache_ttl_seconds };
|
|
13615
|
+
}
|
|
13233
13616
|
/**
|
|
13234
13617
|
* Extract hooks from Kiro CLI agent config into canonical format.
|
|
13235
13618
|
*/
|
|
@@ -13250,6 +13633,7 @@ function kiroHooksToCanonical(kiroHooks) {
|
|
|
13250
13633
|
command: entry.command,
|
|
13251
13634
|
...entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" && { matcher: entry.matcher },
|
|
13252
13635
|
...entry.timeout_ms !== void 0 && entry.timeout_ms !== null && { timeout: entry.timeout_ms },
|
|
13636
|
+
...importCacheTtl(entry),
|
|
13253
13637
|
...entry.name !== void 0 && entry.name !== null && { name: entry.name },
|
|
13254
13638
|
...entry.description !== void 0 && entry.description !== null && { description: entry.description }
|
|
13255
13639
|
});
|
|
@@ -14489,6 +14873,17 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14489
14873
|
supportedHookTypes: ["command"],
|
|
14490
14874
|
supportsMatcher: true
|
|
14491
14875
|
}],
|
|
14876
|
+
["antigravity-plugin", {
|
|
14877
|
+
class: AntigravityPluginHooks,
|
|
14878
|
+
meta: {
|
|
14879
|
+
supportsProject: true,
|
|
14880
|
+
supportsGlobal: false,
|
|
14881
|
+
supportsImport: true
|
|
14882
|
+
},
|
|
14883
|
+
supportedEvents: ANTIGRAVITY_HOOK_EVENTS,
|
|
14884
|
+
supportedHookTypes: ["command"],
|
|
14885
|
+
supportsMatcher: true
|
|
14886
|
+
}],
|
|
14492
14887
|
["cursor", {
|
|
14493
14888
|
class: CursorHooks,
|
|
14494
14889
|
meta: {
|
|
@@ -14517,6 +14912,23 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14517
14912
|
],
|
|
14518
14913
|
supportsMatcher: true
|
|
14519
14914
|
}],
|
|
14915
|
+
["claudecode-plugin", {
|
|
14916
|
+
class: ClaudecodePluginHooks,
|
|
14917
|
+
meta: {
|
|
14918
|
+
supportsProject: true,
|
|
14919
|
+
supportsGlobal: false,
|
|
14920
|
+
supportsImport: true
|
|
14921
|
+
},
|
|
14922
|
+
supportedEvents: CLAUDE_HOOK_EVENTS,
|
|
14923
|
+
supportedHookTypes: [
|
|
14924
|
+
"command",
|
|
14925
|
+
"prompt",
|
|
14926
|
+
"http",
|
|
14927
|
+
"mcp_tool",
|
|
14928
|
+
"agent"
|
|
14929
|
+
],
|
|
14930
|
+
supportsMatcher: true
|
|
14931
|
+
}],
|
|
14520
14932
|
["codexcli", {
|
|
14521
14933
|
class: CodexcliHooks,
|
|
14522
14934
|
meta: {
|
|
@@ -14620,6 +15032,18 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
14620
15032
|
supportedHookTypes: ["command"],
|
|
14621
15033
|
supportsMatcher: true
|
|
14622
15034
|
}],
|
|
15035
|
+
["kimi-code", {
|
|
15036
|
+
class: KimiCodeHooks,
|
|
15037
|
+
meta: {
|
|
15038
|
+
supportsProject: false,
|
|
15039
|
+
supportsGlobal: true,
|
|
15040
|
+
supportsImport: true
|
|
15041
|
+
},
|
|
15042
|
+
supportedEvents: KIMI_CODE_HOOK_EVENTS,
|
|
15043
|
+
supportedHookTypes: ["command"],
|
|
15044
|
+
supportsMatcher: true,
|
|
15045
|
+
passthroughOverrideEvents: true
|
|
15046
|
+
}],
|
|
14623
15047
|
["deepagents", {
|
|
14624
15048
|
class: DeepagentsHooks,
|
|
14625
15049
|
meta: {
|
|
@@ -15795,40 +16219,45 @@ var KiloIgnore = class KiloIgnore extends ToolIgnore {
|
|
|
15795
16219
|
//#endregion
|
|
15796
16220
|
//#region src/features/ignore/kiro-ignore.ts
|
|
15797
16221
|
var KiroIgnore = class KiroIgnore extends ToolIgnore {
|
|
15798
|
-
static getSettablePaths() {
|
|
16222
|
+
static getSettablePaths({ global = false } = {}) {
|
|
15799
16223
|
return {
|
|
15800
|
-
relativeDirPath: ".",
|
|
15801
|
-
relativeFilePath: KIRO_IGNORE_FILE_NAME
|
|
16224
|
+
relativeDirPath: global ? KIRO_SETTINGS_DIR_PATH : ".",
|
|
16225
|
+
relativeFilePath: global ? KIRO_GLOBAL_IGNORE_FILE_NAME : KIRO_IGNORE_FILE_NAME
|
|
15802
16226
|
};
|
|
15803
16227
|
}
|
|
15804
16228
|
toRulesyncIgnore() {
|
|
15805
16229
|
return this.toRulesyncIgnoreDefault();
|
|
15806
16230
|
}
|
|
15807
|
-
static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore }) {
|
|
16231
|
+
static fromRulesyncIgnore({ outputRoot = process.cwd(), rulesyncIgnore, global = false }) {
|
|
16232
|
+
const paths = this.getSettablePaths({ global });
|
|
15808
16233
|
return new KiroIgnore({
|
|
15809
16234
|
outputRoot,
|
|
15810
|
-
relativeDirPath:
|
|
15811
|
-
relativeFilePath:
|
|
15812
|
-
fileContent: rulesyncIgnore.getFileContent()
|
|
16235
|
+
relativeDirPath: paths.relativeDirPath,
|
|
16236
|
+
relativeFilePath: paths.relativeFilePath,
|
|
16237
|
+
fileContent: rulesyncIgnore.getFileContent(),
|
|
16238
|
+
global
|
|
15813
16239
|
});
|
|
15814
16240
|
}
|
|
15815
|
-
static async fromFile({ outputRoot = process.cwd(), validate = true }) {
|
|
15816
|
-
const
|
|
16241
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
16242
|
+
const paths = this.getSettablePaths({ global });
|
|
16243
|
+
const fileContent = await readFileContent(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath));
|
|
15817
16244
|
return new KiroIgnore({
|
|
15818
16245
|
outputRoot,
|
|
15819
|
-
relativeDirPath:
|
|
15820
|
-
relativeFilePath:
|
|
16246
|
+
relativeDirPath: paths.relativeDirPath,
|
|
16247
|
+
relativeFilePath: paths.relativeFilePath,
|
|
15821
16248
|
fileContent,
|
|
15822
|
-
validate
|
|
16249
|
+
validate,
|
|
16250
|
+
global
|
|
15823
16251
|
});
|
|
15824
16252
|
}
|
|
15825
|
-
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
16253
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
15826
16254
|
return new KiroIgnore({
|
|
15827
16255
|
outputRoot,
|
|
15828
16256
|
relativeDirPath,
|
|
15829
16257
|
relativeFilePath,
|
|
15830
16258
|
fileContent: "",
|
|
15831
|
-
validate: false
|
|
16259
|
+
validate: false,
|
|
16260
|
+
global
|
|
15832
16261
|
});
|
|
15833
16262
|
}
|
|
15834
16263
|
};
|
|
@@ -16135,6 +16564,11 @@ const toolIgnoreFactories = /* @__PURE__ */ new Map([
|
|
|
16135
16564
|
["zed", { class: ZedIgnore }]
|
|
16136
16565
|
]);
|
|
16137
16566
|
const ignoreProcessorToolTargets = [...toolIgnoreFactories.keys()];
|
|
16567
|
+
const ignoreProcessorGlobalToolTargets = [
|
|
16568
|
+
"kiro",
|
|
16569
|
+
"kiro-cli",
|
|
16570
|
+
"kiro-ide"
|
|
16571
|
+
];
|
|
16138
16572
|
const defaultGetFactory$4 = (target) => {
|
|
16139
16573
|
const factory = toolIgnoreFactories.get(target);
|
|
16140
16574
|
if (!factory) throw new Error(`Unsupported tool target: ${target}`);
|
|
@@ -16144,7 +16578,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16144
16578
|
toolTarget;
|
|
16145
16579
|
getFactory;
|
|
16146
16580
|
featureOptions;
|
|
16147
|
-
|
|
16581
|
+
global;
|
|
16582
|
+
constructor({ outputRoot = process.cwd(), inputRoot = process.cwd(), toolTarget, getFactory = defaultGetFactory$4, global = false, dryRun = false, logger, featureOptions }) {
|
|
16148
16583
|
super({
|
|
16149
16584
|
outputRoot,
|
|
16150
16585
|
inputRoot,
|
|
@@ -16156,6 +16591,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16156
16591
|
this.toolTarget = result.data;
|
|
16157
16592
|
this.getFactory = getFactory;
|
|
16158
16593
|
this.featureOptions = featureOptions;
|
|
16594
|
+
this.global = global;
|
|
16159
16595
|
}
|
|
16160
16596
|
async writeToolIgnoresFromRulesyncIgnores(rulesyncIgnores) {
|
|
16161
16597
|
const toolIgnores = await this.convertRulesyncFilesToToolFiles(rulesyncIgnores);
|
|
@@ -16180,12 +16616,16 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16180
16616
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
16181
16617
|
try {
|
|
16182
16618
|
const factory = this.getFactory(this.toolTarget);
|
|
16183
|
-
const paths = factory.class.getSettablePaths({
|
|
16619
|
+
const paths = factory.class.getSettablePaths({
|
|
16620
|
+
options: this.featureOptions,
|
|
16621
|
+
global: this.global
|
|
16622
|
+
});
|
|
16184
16623
|
if (forDeletion) {
|
|
16185
16624
|
const toolIgnore = factory.class.forDeletion({
|
|
16186
16625
|
outputRoot: this.outputRoot,
|
|
16187
16626
|
relativeDirPath: paths.relativeDirPath,
|
|
16188
|
-
relativeFilePath: paths.relativeFilePath
|
|
16627
|
+
relativeFilePath: paths.relativeFilePath,
|
|
16628
|
+
global: this.global
|
|
16189
16629
|
});
|
|
16190
16630
|
const hasOwnershipGuard = factory.class.canDeleteAuxiliaryFiles !== void 0;
|
|
16191
16631
|
if (!(!hasOwnershipGuard || await factory.class.canDeleteAuxiliaryFiles?.({ outputRoot: this.outputRoot }) === true)) return [];
|
|
@@ -16205,7 +16645,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16205
16645
|
async loadToolIgnores() {
|
|
16206
16646
|
return [await this.getFactory(this.toolTarget).class.fromFile({
|
|
16207
16647
|
outputRoot: this.outputRoot,
|
|
16208
|
-
options: this.featureOptions
|
|
16648
|
+
options: this.featureOptions,
|
|
16649
|
+
global: this.global
|
|
16209
16650
|
})];
|
|
16210
16651
|
}
|
|
16211
16652
|
/**
|
|
@@ -16219,7 +16660,8 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16219
16660
|
const toolIgnore = await factory.class.fromRulesyncIgnore({
|
|
16220
16661
|
outputRoot: this.outputRoot,
|
|
16221
16662
|
rulesyncIgnore,
|
|
16222
|
-
options: this.featureOptions
|
|
16663
|
+
options: this.featureOptions,
|
|
16664
|
+
global: this.global
|
|
16223
16665
|
});
|
|
16224
16666
|
const auxiliaryFiles = await factory.class.getAuxiliaryFiles?.({
|
|
16225
16667
|
toolIgnore,
|
|
@@ -16241,7 +16683,7 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
16241
16683
|
* Return the tool targets that this processor supports
|
|
16242
16684
|
*/
|
|
16243
16685
|
static getToolTargets({ global = false } = {}) {
|
|
16244
|
-
if (global)
|
|
16686
|
+
if (global) return ignoreProcessorGlobalToolTargets;
|
|
16245
16687
|
return ignoreProcessorToolTargets;
|
|
16246
16688
|
}
|
|
16247
16689
|
};
|
|
@@ -16681,6 +17123,16 @@ var AntigravityIdeMcp = class extends AntigravityMcp {
|
|
|
16681
17123
|
}
|
|
16682
17124
|
};
|
|
16683
17125
|
//#endregion
|
|
17126
|
+
//#region src/features/mcp/antigravity-plugin-mcp.ts
|
|
17127
|
+
var AntigravityPluginMcp = class extends AntigravityIdeMcp {
|
|
17128
|
+
static getSettablePaths() {
|
|
17129
|
+
return {
|
|
17130
|
+
relativeDirPath: ".",
|
|
17131
|
+
relativeFilePath: ANTIGRAVITY_PLUGIN_MCP_FILE_NAME
|
|
17132
|
+
};
|
|
17133
|
+
}
|
|
17134
|
+
};
|
|
17135
|
+
//#endregion
|
|
16684
17136
|
//#region src/features/mcp/augmentcode-mcp.ts
|
|
16685
17137
|
function parseAugmentcodeSettings(fileContent, relativeDirPath, relativeFilePath) {
|
|
16686
17138
|
const configPath = join(relativeDirPath, relativeFilePath);
|
|
@@ -17100,7 +17552,7 @@ function convertToCodexFormat(mcpServers) {
|
|
|
17100
17552
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
17101
17553
|
if (!isRecord(config)) continue;
|
|
17102
17554
|
const { codexName, usedFallback } = normalizeCodexMcpServerName(name);
|
|
17103
|
-
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.
|
|
17555
|
+
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.`);
|
|
17104
17556
|
const converted = {};
|
|
17105
17557
|
for (const [key, value] of Object.entries(config)) {
|
|
17106
17558
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
@@ -18909,6 +19361,170 @@ var KiloMcp = class KiloMcp extends ToolMcp {
|
|
|
18909
19361
|
}
|
|
18910
19362
|
};
|
|
18911
19363
|
//#endregion
|
|
19364
|
+
//#region src/features/mcp/kimi-code-mcp.ts
|
|
19365
|
+
function normalizeKimiCodeTransport({ transport, hasCommand }) {
|
|
19366
|
+
if (transport === "local" || transport === "stdio") return "stdio";
|
|
19367
|
+
if (transport === "sse") return "sse";
|
|
19368
|
+
if (transport === "http" || transport === "streamable-http") return "http";
|
|
19369
|
+
return hasCommand ? "stdio" : "http";
|
|
19370
|
+
}
|
|
19371
|
+
function toKimiCodeServer({ name, server, logger }) {
|
|
19372
|
+
const transport = server.transport ?? server.type;
|
|
19373
|
+
if (transport === "ws") {
|
|
19374
|
+
logger?.warn(`Kimi Code MCP: skipping "${name}" because WebSocket transport is unsupported.`);
|
|
19375
|
+
return null;
|
|
19376
|
+
}
|
|
19377
|
+
const command = server.command;
|
|
19378
|
+
const normalizedCommand = Array.isArray(command) ? command[0] : command;
|
|
19379
|
+
const args = [...Array.isArray(command) ? command.slice(1) : [], ...server.args ?? []];
|
|
19380
|
+
const url = server.httpUrl ?? server.url;
|
|
19381
|
+
const normalizedTransport = normalizeKimiCodeTransport({
|
|
19382
|
+
transport,
|
|
19383
|
+
hasCommand: normalizedCommand !== void 0
|
|
19384
|
+
});
|
|
19385
|
+
if (normalizedTransport === "stdio" && !normalizedCommand || normalizedTransport !== "stdio" && !url) {
|
|
19386
|
+
logger?.warn(`Kimi Code MCP: skipping "${name}" because its ${normalizedTransport} configuration is incomplete.`);
|
|
19387
|
+
return null;
|
|
19388
|
+
}
|
|
19389
|
+
const converted = {
|
|
19390
|
+
transport: normalizedTransport,
|
|
19391
|
+
...normalizedCommand && { command: normalizedCommand },
|
|
19392
|
+
...args.length > 0 && { args },
|
|
19393
|
+
...url && { url }
|
|
19394
|
+
};
|
|
19395
|
+
for (const field of [
|
|
19396
|
+
"env",
|
|
19397
|
+
"cwd",
|
|
19398
|
+
"headers",
|
|
19399
|
+
"bearerTokenEnvVar",
|
|
19400
|
+
"enabled",
|
|
19401
|
+
"startupTimeoutMs",
|
|
19402
|
+
"toolTimeoutMs",
|
|
19403
|
+
"enabledTools",
|
|
19404
|
+
"disabledTools"
|
|
19405
|
+
]) if (server[field] !== void 0) converted[field] = server[field];
|
|
19406
|
+
if (server.disabled === true) converted.enabled = false;
|
|
19407
|
+
return converted;
|
|
19408
|
+
}
|
|
19409
|
+
function toKimiCodeServers({ servers, logger }) {
|
|
19410
|
+
const result = {};
|
|
19411
|
+
for (const [name, server] of Object.entries(servers)) {
|
|
19412
|
+
const converted = toKimiCodeServer({
|
|
19413
|
+
name,
|
|
19414
|
+
server,
|
|
19415
|
+
logger
|
|
19416
|
+
});
|
|
19417
|
+
if (converted) result[name] = converted;
|
|
19418
|
+
}
|
|
19419
|
+
return result;
|
|
19420
|
+
}
|
|
19421
|
+
function fromKimiCodeServers(servers) {
|
|
19422
|
+
return Object.fromEntries(Object.entries(servers).map(([name, server]) => {
|
|
19423
|
+
const { transport, enabled, ...rest } = server;
|
|
19424
|
+
const type = transport === "stdio" || transport === "sse" || transport === "http" ? transport : void 0;
|
|
19425
|
+
return [name, {
|
|
19426
|
+
...rest,
|
|
19427
|
+
...type && { type },
|
|
19428
|
+
...enabled === false && { disabled: true }
|
|
19429
|
+
}];
|
|
19430
|
+
}));
|
|
19431
|
+
}
|
|
19432
|
+
/**
|
|
19433
|
+
* Kimi Code MCP configuration.
|
|
19434
|
+
*
|
|
19435
|
+
* Both project and user scope use `.kimi-code/mcp.json`, resolved against the
|
|
19436
|
+
* project root or home directory respectively.
|
|
19437
|
+
*
|
|
19438
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/mcp.html
|
|
19439
|
+
*/
|
|
19440
|
+
var KimiCodeMcp = class KimiCodeMcp extends ToolMcp {
|
|
19441
|
+
json;
|
|
19442
|
+
constructor(params) {
|
|
19443
|
+
super(params);
|
|
19444
|
+
try {
|
|
19445
|
+
this.json = this.fileContent ? JSON.parse(this.fileContent) : {};
|
|
19446
|
+
} catch (error) {
|
|
19447
|
+
throw new Error(`Failed to parse Kimi Code MCP config at ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(error)}`, { cause: error });
|
|
19448
|
+
}
|
|
19449
|
+
}
|
|
19450
|
+
isDeletable() {
|
|
19451
|
+
return !this.global;
|
|
19452
|
+
}
|
|
19453
|
+
static getSettablePaths({ global = false } = {}) {
|
|
19454
|
+
return {
|
|
19455
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
19456
|
+
relativeFilePath: KIMI_CODE_MCP_FILE_NAME
|
|
19457
|
+
};
|
|
19458
|
+
}
|
|
19459
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
19460
|
+
const paths = this.getSettablePaths({ global });
|
|
19461
|
+
const fileContent = await readFileContentOrNull(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath)) ?? "{\"mcpServers\":{}}";
|
|
19462
|
+
return new KimiCodeMcp({
|
|
19463
|
+
outputRoot,
|
|
19464
|
+
relativeDirPath: paths.relativeDirPath,
|
|
19465
|
+
relativeFilePath: paths.relativeFilePath,
|
|
19466
|
+
fileContent,
|
|
19467
|
+
validate,
|
|
19468
|
+
global
|
|
19469
|
+
});
|
|
19470
|
+
}
|
|
19471
|
+
static async fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, global = false, logger }) {
|
|
19472
|
+
const paths = this.getSettablePaths({ global });
|
|
19473
|
+
const filePath = join(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
19474
|
+
const existingContent = await readFileContentOrNull(filePath) ?? "{}";
|
|
19475
|
+
let existing;
|
|
19476
|
+
try {
|
|
19477
|
+
existing = JSON.parse(existingContent);
|
|
19478
|
+
} catch (error) {
|
|
19479
|
+
throw new Error(`Failed to parse Kimi Code MCP config at ${filePath}: ${formatError(error)}`, { cause: error });
|
|
19480
|
+
}
|
|
19481
|
+
return new KimiCodeMcp({
|
|
19482
|
+
outputRoot,
|
|
19483
|
+
relativeDirPath: paths.relativeDirPath,
|
|
19484
|
+
relativeFilePath: paths.relativeFilePath,
|
|
19485
|
+
fileContent: JSON.stringify({
|
|
19486
|
+
...existing,
|
|
19487
|
+
mcpServers: toKimiCodeServers({
|
|
19488
|
+
servers: rulesyncMcp.getMcpServers(),
|
|
19489
|
+
logger
|
|
19490
|
+
})
|
|
19491
|
+
}, null, 2),
|
|
19492
|
+
validate,
|
|
19493
|
+
global
|
|
19494
|
+
});
|
|
19495
|
+
}
|
|
19496
|
+
toRulesyncMcp() {
|
|
19497
|
+
return new RulesyncMcp({
|
|
19498
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
19499
|
+
nativeOutputRoot: this.outputRoot,
|
|
19500
|
+
global: this.global
|
|
19501
|
+
}),
|
|
19502
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
19503
|
+
relativeFilePath: RULESYNC_MCP_FILE_NAME,
|
|
19504
|
+
fileContent: JSON.stringify({
|
|
19505
|
+
...this.json,
|
|
19506
|
+
mcpServers: fromKimiCodeServers(isMcpServers(this.json.mcpServers) ? this.json.mcpServers : {})
|
|
19507
|
+
}, null, 2)
|
|
19508
|
+
});
|
|
19509
|
+
}
|
|
19510
|
+
validate() {
|
|
19511
|
+
return {
|
|
19512
|
+
success: true,
|
|
19513
|
+
error: null
|
|
19514
|
+
};
|
|
19515
|
+
}
|
|
19516
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
19517
|
+
return new KimiCodeMcp({
|
|
19518
|
+
outputRoot,
|
|
19519
|
+
relativeDirPath,
|
|
19520
|
+
relativeFilePath,
|
|
19521
|
+
fileContent: "{}",
|
|
19522
|
+
validate: false,
|
|
19523
|
+
global
|
|
19524
|
+
});
|
|
19525
|
+
}
|
|
19526
|
+
};
|
|
19527
|
+
//#endregion
|
|
18912
19528
|
//#region src/features/mcp/kiro-mcp.ts
|
|
18913
19529
|
var KiroMcp = class KiroMcp extends ToolMcp {
|
|
18914
19530
|
json;
|
|
@@ -19717,7 +20333,7 @@ var RovodevMcp = class RovodevMcp extends ToolMcp {
|
|
|
19717
20333
|
* `workflow_mcp_servers: { stdio, sse, http }`. Without it, workflow-defined MCP
|
|
19718
20334
|
* servers are refused regardless of how they are declared. So this adapter emits
|
|
19719
20335
|
* the transport allowlist derived from the transports present in
|
|
19720
|
-
* `.rulesync/mcp.
|
|
20336
|
+
* `.rulesync/mcp.jsonc`, enabling exactly the transports the user's servers need.
|
|
19721
20337
|
*
|
|
19722
20338
|
* Lossiness (documented, intentional): the per-server names, commands, env, URLs
|
|
19723
20339
|
* and headers are NOT representable in `config.yaml` and are intentionally not
|
|
@@ -20237,6 +20853,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20237
20853
|
supportsDisabledTools: true
|
|
20238
20854
|
}
|
|
20239
20855
|
}],
|
|
20856
|
+
["antigravity-plugin", {
|
|
20857
|
+
class: AntigravityPluginMcp,
|
|
20858
|
+
meta: {
|
|
20859
|
+
supportsProject: true,
|
|
20860
|
+
supportsGlobal: false,
|
|
20861
|
+
supportsEnabledTools: false,
|
|
20862
|
+
supportsDisabledTools: true
|
|
20863
|
+
}
|
|
20864
|
+
}],
|
|
20240
20865
|
["augmentcode", {
|
|
20241
20866
|
class: AugmentcodeMcp,
|
|
20242
20867
|
meta: {
|
|
@@ -20255,6 +20880,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20255
20880
|
supportsDisabledTools: false
|
|
20256
20881
|
}
|
|
20257
20882
|
}],
|
|
20883
|
+
["claudecode-plugin", {
|
|
20884
|
+
class: ClaudecodeMcp,
|
|
20885
|
+
meta: {
|
|
20886
|
+
supportsProject: true,
|
|
20887
|
+
supportsGlobal: false,
|
|
20888
|
+
supportsEnabledTools: false,
|
|
20889
|
+
supportsDisabledTools: false
|
|
20890
|
+
}
|
|
20891
|
+
}],
|
|
20258
20892
|
["claudecode-legacy", {
|
|
20259
20893
|
class: ClaudecodeMcp,
|
|
20260
20894
|
meta: {
|
|
@@ -20354,6 +20988,15 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20354
20988
|
supportsDisabledTools: false
|
|
20355
20989
|
}
|
|
20356
20990
|
}],
|
|
20991
|
+
["kimi-code", {
|
|
20992
|
+
class: KimiCodeMcp,
|
|
20993
|
+
meta: {
|
|
20994
|
+
supportsProject: true,
|
|
20995
|
+
supportsGlobal: true,
|
|
20996
|
+
supportsEnabledTools: true,
|
|
20997
|
+
supportsDisabledTools: true
|
|
20998
|
+
}
|
|
20999
|
+
}],
|
|
20357
21000
|
["kilo", {
|
|
20358
21001
|
class: KiloMcp,
|
|
20359
21002
|
meta: {
|
|
@@ -20369,7 +21012,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20369
21012
|
supportsProject: true,
|
|
20370
21013
|
supportsGlobal: true,
|
|
20371
21014
|
supportsEnabledTools: false,
|
|
20372
|
-
supportsDisabledTools:
|
|
21015
|
+
supportsDisabledTools: true
|
|
20373
21016
|
}
|
|
20374
21017
|
}],
|
|
20375
21018
|
["kiro-cli", {
|
|
@@ -20378,7 +21021,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20378
21021
|
supportsProject: true,
|
|
20379
21022
|
supportsGlobal: true,
|
|
20380
21023
|
supportsEnabledTools: false,
|
|
20381
|
-
supportsDisabledTools:
|
|
21024
|
+
supportsDisabledTools: true
|
|
20382
21025
|
}
|
|
20383
21026
|
}],
|
|
20384
21027
|
["kiro-ide", {
|
|
@@ -20387,7 +21030,7 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20387
21030
|
supportsProject: true,
|
|
20388
21031
|
supportsGlobal: true,
|
|
20389
21032
|
supportsEnabledTools: false,
|
|
20390
|
-
supportsDisabledTools:
|
|
21033
|
+
supportsDisabledTools: true
|
|
20391
21034
|
}
|
|
20392
21035
|
}],
|
|
20393
21036
|
["junie", {
|
|
@@ -22954,7 +23597,7 @@ function mergeFilesystemCategoryRules({ categoryRules, logger }) {
|
|
|
22954
23597
|
function buildCodexBashRulesContent(config) {
|
|
22955
23598
|
const bashRules = config.permission.bash ?? {};
|
|
22956
23599
|
const entries = Object.entries(bashRules);
|
|
22957
|
-
const header = ["# Generated by Rulesync from .rulesync/permissions.
|
|
23600
|
+
const header = ["# Generated by Rulesync from .rulesync/permissions.jsonc (permission.bash)", "# https://developers.openai.com/codex/rules"];
|
|
22958
23601
|
if (entries.length === 0) return [...header, "# No bash permission rules were configured."].join("\n");
|
|
22959
23602
|
const ruleBlocks = entries.map(([pattern, action]) => {
|
|
22960
23603
|
const tokens = toCommandPatternTokens(pattern);
|
|
@@ -24414,8 +25057,9 @@ var HermesagentPermissions = class HermesagentPermissions extends ToolPermission
|
|
|
24414
25057
|
});
|
|
24415
25058
|
const permissions = config.permissions && typeof config.permissions === "object" ? config.permissions.rulesync : {};
|
|
24416
25059
|
return new RulesyncPermissions({
|
|
24417
|
-
|
|
24418
|
-
|
|
25060
|
+
outputRoot: this.outputRoot,
|
|
25061
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
25062
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
24419
25063
|
fileContent: JSON.stringify(permissions ?? {}, null, 2)
|
|
24420
25064
|
});
|
|
24421
25065
|
}
|
|
@@ -24837,7 +25481,7 @@ var KiloPermissions = class KiloPermissions extends ToolPermissions {
|
|
|
24837
25481
|
}
|
|
24838
25482
|
if (Object.keys(droppedDenyByKey).length > 0) {
|
|
24839
25483
|
const summary = Object.entries(droppedDenyByKey).map(([key, patterns]) => `${key}: [${patterns.join(", ")}]`).join("; ");
|
|
24840
|
-
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.
|
|
25484
|
+
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'.`);
|
|
24841
25485
|
}
|
|
24842
25486
|
const mergedPermission = {
|
|
24843
25487
|
...existingPermission,
|
|
@@ -24897,6 +25541,227 @@ var KiloPermissions = class KiloPermissions extends ToolPermissions {
|
|
|
24897
25541
|
}
|
|
24898
25542
|
};
|
|
24899
25543
|
//#endregion
|
|
25544
|
+
//#region src/features/permissions/kimi-code-permissions.ts
|
|
25545
|
+
const CATEGORY_TO_KIMI_CODE_TOOL = {
|
|
25546
|
+
bash: "Bash",
|
|
25547
|
+
read: "Read",
|
|
25548
|
+
write: "Write",
|
|
25549
|
+
edit: "Edit",
|
|
25550
|
+
grep: "Grep",
|
|
25551
|
+
glob: "Glob",
|
|
25552
|
+
websearch: "WebSearch",
|
|
25553
|
+
webfetch: "FetchURL",
|
|
25554
|
+
agent: "Agent"
|
|
25555
|
+
};
|
|
25556
|
+
function buildKimiCodePattern(category, pattern) {
|
|
25557
|
+
if (category.startsWith("mcp__")) return pattern === "*" || pattern === "" ? category : null;
|
|
25558
|
+
if (category === "mcp") return pattern === "*" || pattern === "" ? "mcp__*" : `mcp__${pattern}`;
|
|
25559
|
+
const tool = CATEGORY_TO_KIMI_CODE_TOOL[category];
|
|
25560
|
+
if (!tool) return null;
|
|
25561
|
+
return pattern === "*" || pattern === "" ? tool : `${tool}(${pattern})`;
|
|
25562
|
+
}
|
|
25563
|
+
function canonicalToKimiCodeRules({ config, logger }) {
|
|
25564
|
+
const canonicalRules = [];
|
|
25565
|
+
const overrideRules = config["kimi-code"]?.rules ?? [];
|
|
25566
|
+
for (const [category, rules] of Object.entries(config.permission)) {
|
|
25567
|
+
if (!(category === "mcp" || category.startsWith("mcp__") || CATEGORY_TO_KIMI_CODE_TOOL[category] !== void 0)) {
|
|
25568
|
+
if (Object.keys(rules).length > 0) logger?.warn(`Kimi Code permissions: skipping unsupported category "${category}".`);
|
|
25569
|
+
continue;
|
|
25570
|
+
}
|
|
25571
|
+
for (const [pattern, decision] of Object.entries(rules)) {
|
|
25572
|
+
if (category.startsWith("mcp__") && pattern !== "*" && pattern !== "") {
|
|
25573
|
+
if (decision === "deny") {
|
|
25574
|
+
logger?.warn(`Kimi Code permissions: broadening argument-specific deny for "${category}" to the whole MCP tool because Kimi does not match MCP tool arguments.`);
|
|
25575
|
+
canonicalRules.push({
|
|
25576
|
+
decision,
|
|
25577
|
+
pattern: category,
|
|
25578
|
+
scope: "user"
|
|
25579
|
+
});
|
|
25580
|
+
} else logger?.warn(`Kimi Code permissions: skipping argument-specific ${decision} for "${category}" because Kimi does not match MCP tool arguments.`);
|
|
25581
|
+
continue;
|
|
25582
|
+
}
|
|
25583
|
+
const kimiCodePattern = buildKimiCodePattern(category, pattern);
|
|
25584
|
+
if (!kimiCodePattern) continue;
|
|
25585
|
+
canonicalRules.push({
|
|
25586
|
+
decision,
|
|
25587
|
+
pattern: kimiCodePattern,
|
|
25588
|
+
scope: "user"
|
|
25589
|
+
});
|
|
25590
|
+
}
|
|
25591
|
+
}
|
|
25592
|
+
return [...overrideRules, ...sortKimiCodeRulesFailClosed(canonicalRules)];
|
|
25593
|
+
}
|
|
25594
|
+
function getKimiCodePatternSpecificity(pattern) {
|
|
25595
|
+
const opening = pattern.indexOf("(");
|
|
25596
|
+
const hasArguments = opening >= 0 && pattern.endsWith(")");
|
|
25597
|
+
const tool = hasArguments ? pattern.slice(0, opening) : pattern;
|
|
25598
|
+
const argument = hasArguments ? pattern.slice(opening + 1, -1) : "";
|
|
25599
|
+
return {
|
|
25600
|
+
tool,
|
|
25601
|
+
toolLiteralLength: tool.replaceAll("*", "").replaceAll("?", "").length,
|
|
25602
|
+
toolWildcardCount: [...tool].filter((character) => "*?".includes(character)).length,
|
|
25603
|
+
literalLength: argument.replaceAll("*", "").replaceAll("?", "").replaceAll("[", "").replaceAll("]", "").length,
|
|
25604
|
+
wildcardCount: [...argument].filter((character) => "*?[]".includes(character)).length,
|
|
25605
|
+
hasArguments
|
|
25606
|
+
};
|
|
25607
|
+
}
|
|
25608
|
+
function sortKimiCodeRulesFailClosed(rules) {
|
|
25609
|
+
const actionPriority = {
|
|
25610
|
+
deny: 0,
|
|
25611
|
+
ask: 1,
|
|
25612
|
+
allow: 2
|
|
25613
|
+
};
|
|
25614
|
+
return rules.map((rule, index) => ({
|
|
25615
|
+
rule,
|
|
25616
|
+
index,
|
|
25617
|
+
specificity: getKimiCodePatternSpecificity(rule.pattern)
|
|
25618
|
+
})).toSorted((left, right) => {
|
|
25619
|
+
const actionOrder = actionPriority[left.rule.decision] - actionPriority[right.rule.decision];
|
|
25620
|
+
if (actionOrder !== 0) return actionOrder;
|
|
25621
|
+
if (left.specificity.tool.startsWith("mcp__") && right.specificity.tool.startsWith("mcp__")) {
|
|
25622
|
+
const toolLiteralOrder = right.specificity.toolLiteralLength - left.specificity.toolLiteralLength;
|
|
25623
|
+
if (toolLiteralOrder !== 0) return toolLiteralOrder;
|
|
25624
|
+
const toolWildcardOrder = left.specificity.toolWildcardCount - right.specificity.toolWildcardCount;
|
|
25625
|
+
if (toolWildcardOrder !== 0) return toolWildcardOrder;
|
|
25626
|
+
}
|
|
25627
|
+
const toolOrder = left.specificity.tool.localeCompare(right.specificity.tool);
|
|
25628
|
+
if (toolOrder !== 0) return toolOrder;
|
|
25629
|
+
if (left.specificity.hasArguments !== right.specificity.hasArguments) return left.specificity.hasArguments ? -1 : 1;
|
|
25630
|
+
const literalOrder = right.specificity.literalLength - left.specificity.literalLength;
|
|
25631
|
+
if (literalOrder !== 0) return literalOrder;
|
|
25632
|
+
const wildcardOrder = left.specificity.wildcardCount - right.specificity.wildcardCount;
|
|
25633
|
+
if (wildcardOrder !== 0) return wildcardOrder;
|
|
25634
|
+
return left.index - right.index;
|
|
25635
|
+
}).map(({ rule }) => rule);
|
|
25636
|
+
}
|
|
25637
|
+
function preserveKimiCodeRules(rules) {
|
|
25638
|
+
const permission = {};
|
|
25639
|
+
const nativeRules = [];
|
|
25640
|
+
if (!Array.isArray(rules)) return {
|
|
25641
|
+
permission,
|
|
25642
|
+
nativeRules
|
|
25643
|
+
};
|
|
25644
|
+
for (const raw of rules) {
|
|
25645
|
+
if (!isRecord(raw)) continue;
|
|
25646
|
+
const decision = raw.decision;
|
|
25647
|
+
const pattern = raw.pattern;
|
|
25648
|
+
if (decision !== "allow" && decision !== "ask" && decision !== "deny" || typeof pattern !== "string") continue;
|
|
25649
|
+
nativeRules.push({
|
|
25650
|
+
decision,
|
|
25651
|
+
pattern,
|
|
25652
|
+
...typeof raw.scope === "string" && { scope: raw.scope },
|
|
25653
|
+
...typeof raw.reason === "string" && { reason: raw.reason }
|
|
25654
|
+
});
|
|
25655
|
+
}
|
|
25656
|
+
return {
|
|
25657
|
+
permission,
|
|
25658
|
+
nativeRules
|
|
25659
|
+
};
|
|
25660
|
+
}
|
|
25661
|
+
/**
|
|
25662
|
+
* Kimi Code permission rules in the shared user `config.toml`.
|
|
25663
|
+
*
|
|
25664
|
+
* @see https://moonshotai.github.io/kimi-code/en/configuration/config-files.html
|
|
25665
|
+
*/
|
|
25666
|
+
var KimiCodePermissions = class KimiCodePermissions extends ToolPermissions {
|
|
25667
|
+
constructor(params) {
|
|
25668
|
+
super({
|
|
25669
|
+
...params,
|
|
25670
|
+
...KimiCodePermissions.getSettablePaths({ global: params.global ?? true })
|
|
25671
|
+
});
|
|
25672
|
+
}
|
|
25673
|
+
static getSettablePaths({ global = true } = {}) {
|
|
25674
|
+
return {
|
|
25675
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
25676
|
+
relativeFilePath: KIMI_CODE_CONFIG_FILE_NAME
|
|
25677
|
+
};
|
|
25678
|
+
}
|
|
25679
|
+
validate() {
|
|
25680
|
+
return {
|
|
25681
|
+
success: true,
|
|
25682
|
+
error: null
|
|
25683
|
+
};
|
|
25684
|
+
}
|
|
25685
|
+
isDeletable() {
|
|
25686
|
+
return false;
|
|
25687
|
+
}
|
|
25688
|
+
shouldMergeExistingFileContent() {
|
|
25689
|
+
return true;
|
|
25690
|
+
}
|
|
25691
|
+
setFileContent(fileContent) {
|
|
25692
|
+
const paths = KimiCodePermissions.getSettablePaths({ global: this.global });
|
|
25693
|
+
this.fileContent = applySharedConfigPatch({
|
|
25694
|
+
fileKey: KIMI_CODE_CONFIG_SHARED_FILE_KEY,
|
|
25695
|
+
feature: "permissions",
|
|
25696
|
+
existingContent: fileContent,
|
|
25697
|
+
patch: parseSharedConfig({
|
|
25698
|
+
format: "toml",
|
|
25699
|
+
fileContent: this.fileContent
|
|
25700
|
+
}),
|
|
25701
|
+
filePath: join(paths.relativeDirPath, paths.relativeFilePath)
|
|
25702
|
+
});
|
|
25703
|
+
}
|
|
25704
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = true }) {
|
|
25705
|
+
const paths = this.getSettablePaths({ global });
|
|
25706
|
+
return new KimiCodePermissions({
|
|
25707
|
+
outputRoot,
|
|
25708
|
+
fileContent: await readFileContent(join(outputRoot, paths.relativeDirPath, paths.relativeFilePath)),
|
|
25709
|
+
validate,
|
|
25710
|
+
global
|
|
25711
|
+
});
|
|
25712
|
+
}
|
|
25713
|
+
static fromRulesyncPermissions({ outputRoot, rulesyncPermissions, logger }) {
|
|
25714
|
+
const config = rulesyncPermissions.getJson();
|
|
25715
|
+
const defaultPermissionMode = config["kimi-code"]?.defaultPermissionMode;
|
|
25716
|
+
return new KimiCodePermissions({
|
|
25717
|
+
outputRoot,
|
|
25718
|
+
fileContent: stringifySharedConfig({
|
|
25719
|
+
format: "toml",
|
|
25720
|
+
document: {
|
|
25721
|
+
...defaultPermissionMode && { default_permission_mode: defaultPermissionMode },
|
|
25722
|
+
permission: { rules: canonicalToKimiCodeRules({
|
|
25723
|
+
config,
|
|
25724
|
+
logger
|
|
25725
|
+
}) }
|
|
25726
|
+
}
|
|
25727
|
+
}),
|
|
25728
|
+
global: true
|
|
25729
|
+
});
|
|
25730
|
+
}
|
|
25731
|
+
toRulesyncPermissions() {
|
|
25732
|
+
const config = parseSharedConfig({
|
|
25733
|
+
format: "toml",
|
|
25734
|
+
fileContent: this.getFileContent()
|
|
25735
|
+
});
|
|
25736
|
+
const { permission, nativeRules } = preserveKimiCodeRules((isRecord(config.permission) ? config.permission : {}).rules);
|
|
25737
|
+
const defaultPermissionMode = config.default_permission_mode;
|
|
25738
|
+
const toolOverride = {
|
|
25739
|
+
...defaultPermissionMode === "manual" || defaultPermissionMode === "yolo" || defaultPermissionMode === "auto" ? { defaultPermissionMode } : {},
|
|
25740
|
+
...nativeRules.length > 0 && { rules: nativeRules }
|
|
25741
|
+
};
|
|
25742
|
+
return new RulesyncPermissions({
|
|
25743
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
25744
|
+
nativeOutputRoot: this.outputRoot,
|
|
25745
|
+
global: this.global
|
|
25746
|
+
}),
|
|
25747
|
+
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
25748
|
+
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
25749
|
+
fileContent: JSON.stringify({
|
|
25750
|
+
permission,
|
|
25751
|
+
...Object.keys(toolOverride).length > 0 && { "kimi-code": toolOverride }
|
|
25752
|
+
}, null, 2)
|
|
25753
|
+
});
|
|
25754
|
+
}
|
|
25755
|
+
static forDeletion({ outputRoot = process.cwd() }) {
|
|
25756
|
+
return new KimiCodePermissions({
|
|
25757
|
+
outputRoot,
|
|
25758
|
+
fileContent: "",
|
|
25759
|
+
validate: false,
|
|
25760
|
+
global: true
|
|
25761
|
+
});
|
|
25762
|
+
}
|
|
25763
|
+
};
|
|
25764
|
+
//#endregion
|
|
24900
25765
|
//#region src/features/permissions/kiro-permissions.ts
|
|
24901
25766
|
const KiroAgentSchema = z.looseObject({
|
|
24902
25767
|
allowedTools: z.optional(z.array(z.string())),
|
|
@@ -27112,6 +27977,14 @@ const toolPermissionsFactories = /* @__PURE__ */ new Map([
|
|
|
27112
27977
|
supportsImport: true
|
|
27113
27978
|
}
|
|
27114
27979
|
}],
|
|
27980
|
+
["kimi-code", {
|
|
27981
|
+
class: KimiCodePermissions,
|
|
27982
|
+
meta: {
|
|
27983
|
+
supportsProject: false,
|
|
27984
|
+
supportsGlobal: true,
|
|
27985
|
+
supportsImport: true
|
|
27986
|
+
}
|
|
27987
|
+
}],
|
|
27115
27988
|
["junie", {
|
|
27116
27989
|
class: JuniePermissions,
|
|
27117
27990
|
meta: {
|
|
@@ -28205,6 +29078,17 @@ var AntigravityIdeSkill = class extends AntigravitySharedSkill {
|
|
|
28205
29078
|
}
|
|
28206
29079
|
};
|
|
28207
29080
|
//#endregion
|
|
29081
|
+
//#region src/features/skills/antigravity-plugin-skill.ts
|
|
29082
|
+
var AntigravityPluginSkill = class extends AntigravityIdeSkill {
|
|
29083
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
29084
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
29085
|
+
return targets.includes("*") || targets.includes("antigravity-plugin");
|
|
29086
|
+
}
|
|
29087
|
+
static getSettablePaths() {
|
|
29088
|
+
return { relativeDirPath: ANTIGRAVITY_PLUGIN_SKILLS_DIR };
|
|
29089
|
+
}
|
|
29090
|
+
};
|
|
29091
|
+
//#endregion
|
|
28208
29092
|
//#region src/features/skills/augmentcode-skill.ts
|
|
28209
29093
|
const AugmentcodeSkillFrontmatterSchema = z.looseObject({
|
|
28210
29094
|
name: z.string(),
|
|
@@ -28399,7 +29283,7 @@ function buildClaudecodeSkillFrontmatter({ rulesyncFrontmatter, resolvedDisableM
|
|
|
28399
29283
|
* Unlike subagents and commands, skills are directories containing SKILL.md and other files.
|
|
28400
29284
|
* Extends ToolSkill to inherit directory management and security features from AiDir.
|
|
28401
29285
|
*/
|
|
28402
|
-
var ClaudecodeSkill = class
|
|
29286
|
+
var ClaudecodeSkill = class extends ToolSkill {
|
|
28403
29287
|
constructor({ outputRoot = process.cwd(), relativeDirPath = CLAUDECODE_SKILLS_DIR_PATH, dirName, frontmatter, body, otherFiles = [], validate = true, global = false }) {
|
|
28404
29288
|
super({
|
|
28405
29289
|
outputRoot,
|
|
@@ -28494,9 +29378,9 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28494
29378
|
section: rulesyncFrontmatter.claudecode
|
|
28495
29379
|
})
|
|
28496
29380
|
});
|
|
28497
|
-
const settablePaths =
|
|
29381
|
+
const settablePaths = this.getSettablePaths({ global });
|
|
28498
29382
|
const relativeDirPath = rulesyncFrontmatter.claudecode?.["scheduled-task"] ? CLAUDECODE_SCHEDULED_TASKS_DIR_PATH : settablePaths.relativeDirPath;
|
|
28499
|
-
return new
|
|
29383
|
+
return new this({
|
|
28500
29384
|
outputRoot,
|
|
28501
29385
|
relativeDirPath,
|
|
28502
29386
|
dirName: rulesyncSkill.getDirName(),
|
|
@@ -28516,14 +29400,14 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28516
29400
|
static async fromDir(params) {
|
|
28517
29401
|
const loaded = await this.loadSkillDirContent({
|
|
28518
29402
|
...params,
|
|
28519
|
-
getSettablePaths:
|
|
29403
|
+
getSettablePaths: (options) => this.getSettablePaths(options)
|
|
28520
29404
|
});
|
|
28521
29405
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28522
29406
|
if (!result.success) {
|
|
28523
29407
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28524
29408
|
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28525
29409
|
}
|
|
28526
|
-
return new
|
|
29410
|
+
return new this({
|
|
28527
29411
|
outputRoot: loaded.outputRoot,
|
|
28528
29412
|
relativeDirPath: loaded.relativeDirPath,
|
|
28529
29413
|
dirName: loaded.dirName,
|
|
@@ -28535,7 +29419,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28535
29419
|
});
|
|
28536
29420
|
}
|
|
28537
29421
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
28538
|
-
return new
|
|
29422
|
+
return new this({
|
|
28539
29423
|
outputRoot,
|
|
28540
29424
|
relativeDirPath,
|
|
28541
29425
|
dirName,
|
|
@@ -28551,6 +29435,17 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
28551
29435
|
}
|
|
28552
29436
|
};
|
|
28553
29437
|
//#endregion
|
|
29438
|
+
//#region src/features/skills/claudecode-plugin-skill.ts
|
|
29439
|
+
var ClaudecodePluginSkill = class extends ClaudecodeSkill {
|
|
29440
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
29441
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
29442
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
29443
|
+
}
|
|
29444
|
+
static getSettablePaths() {
|
|
29445
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_SKILLS_DIR };
|
|
29446
|
+
}
|
|
29447
|
+
};
|
|
29448
|
+
//#endregion
|
|
28554
29449
|
//#region src/features/skills/cline-skill.ts
|
|
28555
29450
|
const ClineSkillFrontmatterSchema = z.looseObject({
|
|
28556
29451
|
name: z.string(),
|
|
@@ -30340,6 +31235,197 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
30340
31235
|
}
|
|
30341
31236
|
};
|
|
30342
31237
|
//#endregion
|
|
31238
|
+
//#region src/features/skills/kimi-code-skill.ts
|
|
31239
|
+
const KimiCodeSkillFrontmatterSchema = z.looseObject({
|
|
31240
|
+
name: z.string(),
|
|
31241
|
+
description: z.string(),
|
|
31242
|
+
type: z.optional(z.enum([
|
|
31243
|
+
"prompt",
|
|
31244
|
+
"inline",
|
|
31245
|
+
"flow"
|
|
31246
|
+
])),
|
|
31247
|
+
whenToUse: z.optional(z.string()),
|
|
31248
|
+
disableModelInvocation: z.optional(z.boolean()),
|
|
31249
|
+
arguments: z.optional(z.union([z.string(), z.array(z.string())]))
|
|
31250
|
+
});
|
|
31251
|
+
const KimiCodeFlatSkillFrontmatterSchema = z.looseObject({
|
|
31252
|
+
name: z.optional(z.string()),
|
|
31253
|
+
description: z.optional(z.string()),
|
|
31254
|
+
type: z.optional(z.enum([
|
|
31255
|
+
"prompt",
|
|
31256
|
+
"inline",
|
|
31257
|
+
"flow"
|
|
31258
|
+
])),
|
|
31259
|
+
whenToUse: z.optional(z.string()),
|
|
31260
|
+
disableModelInvocation: z.optional(z.boolean()),
|
|
31261
|
+
arguments: z.optional(z.union([z.string(), z.array(z.string())]))
|
|
31262
|
+
});
|
|
31263
|
+
function logicalSkillDirName(name) {
|
|
31264
|
+
const normalized = name.toLowerCase();
|
|
31265
|
+
return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(normalized) ? normalized : `kimi-${encodeURIComponent(normalized)}`;
|
|
31266
|
+
}
|
|
31267
|
+
/**
|
|
31268
|
+
* Kimi Code Agent Skill.
|
|
31269
|
+
*
|
|
31270
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/skills.html
|
|
31271
|
+
*/
|
|
31272
|
+
var KimiCodeSkill = class KimiCodeSkill extends ToolSkill {
|
|
31273
|
+
constructor({ outputRoot = process.cwd(), relativeDirPath = KIMI_CODE_SKILLS_DIR_PATH, dirName, frontmatter, body, otherFiles = [], validate = true, global = false }) {
|
|
31274
|
+
super({
|
|
31275
|
+
outputRoot,
|
|
31276
|
+
relativeDirPath,
|
|
31277
|
+
dirName,
|
|
31278
|
+
mainFile: {
|
|
31279
|
+
name: SKILL_FILE_NAME,
|
|
31280
|
+
body,
|
|
31281
|
+
frontmatter: { ...frontmatter }
|
|
31282
|
+
},
|
|
31283
|
+
otherFiles,
|
|
31284
|
+
global
|
|
31285
|
+
});
|
|
31286
|
+
if (validate) {
|
|
31287
|
+
const result = this.validate();
|
|
31288
|
+
if (!result.success) throw result.error;
|
|
31289
|
+
}
|
|
31290
|
+
}
|
|
31291
|
+
static getSettablePaths({ global = false } = {}) {
|
|
31292
|
+
const customHome = global ? getKimiCodeHome() : void 0;
|
|
31293
|
+
return {
|
|
31294
|
+
relativeDirPath: getKimiCodeRelativeDirPath({
|
|
31295
|
+
global,
|
|
31296
|
+
relativeDirPath: KIMI_CODE_SKILLS_DIR_NAME
|
|
31297
|
+
}),
|
|
31298
|
+
importOnlySkillRoots: [customHome ? {
|
|
31299
|
+
outputRoot: getHomeDirectory(),
|
|
31300
|
+
relativeDirPath: KIMI_CODE_SHARED_SKILLS_DIR_PATH
|
|
31301
|
+
} : KIMI_CODE_SHARED_SKILLS_DIR_PATH]
|
|
31302
|
+
};
|
|
31303
|
+
}
|
|
31304
|
+
getFrontmatter() {
|
|
31305
|
+
return KimiCodeSkillFrontmatterSchema.parse(this.requireMainFileFrontmatter());
|
|
31306
|
+
}
|
|
31307
|
+
getBody() {
|
|
31308
|
+
return this.mainFile?.body ?? "";
|
|
31309
|
+
}
|
|
31310
|
+
getImportIdentity() {
|
|
31311
|
+
return this.getFrontmatter().name.toLowerCase();
|
|
31312
|
+
}
|
|
31313
|
+
validate() {
|
|
31314
|
+
if (!this.mainFile) return {
|
|
31315
|
+
success: false,
|
|
31316
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
31317
|
+
};
|
|
31318
|
+
const result = KimiCodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
31319
|
+
return result.success ? {
|
|
31320
|
+
success: true,
|
|
31321
|
+
error: null
|
|
31322
|
+
} : {
|
|
31323
|
+
success: false,
|
|
31324
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${this.getDirPath()}: ${formatError(result.error)}`)
|
|
31325
|
+
};
|
|
31326
|
+
}
|
|
31327
|
+
toRulesyncSkill() {
|
|
31328
|
+
const { name, description, disableModelInvocation, ...kimiCodeFrontmatter } = this.getFrontmatter();
|
|
31329
|
+
const toolSection = {
|
|
31330
|
+
...kimiCodeFrontmatter,
|
|
31331
|
+
...disableModelInvocation !== void 0 && { disableModelInvocation }
|
|
31332
|
+
};
|
|
31333
|
+
const frontmatter = {
|
|
31334
|
+
name,
|
|
31335
|
+
description,
|
|
31336
|
+
targets: ["*"],
|
|
31337
|
+
...disableModelInvocation !== void 0 && { "disable-model-invocation": disableModelInvocation },
|
|
31338
|
+
...Object.keys(toolSection).length > 0 && { "kimi-code": toolSection }
|
|
31339
|
+
};
|
|
31340
|
+
return new RulesyncSkill({
|
|
31341
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
31342
|
+
nativeOutputRoot: this.outputRoot,
|
|
31343
|
+
global: this.global
|
|
31344
|
+
}),
|
|
31345
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
31346
|
+
dirName: logicalSkillDirName(name),
|
|
31347
|
+
frontmatter,
|
|
31348
|
+
body: this.getBody(),
|
|
31349
|
+
otherFiles: this.getOtherFiles(),
|
|
31350
|
+
validate: true,
|
|
31351
|
+
global: this.global
|
|
31352
|
+
});
|
|
31353
|
+
}
|
|
31354
|
+
static fromRulesyncSkill({ outputRoot = process.cwd(), rulesyncSkill, validate = true, global = false }) {
|
|
31355
|
+
const frontmatter = rulesyncSkill.getFrontmatter();
|
|
31356
|
+
const kimiCodeSection = frontmatter["kimi-code"] ?? {};
|
|
31357
|
+
const kimiCodeFrontmatter = {
|
|
31358
|
+
name: frontmatter.name,
|
|
31359
|
+
description: frontmatter.description,
|
|
31360
|
+
...frontmatter["disable-model-invocation"] !== void 0 && { disableModelInvocation: frontmatter["disable-model-invocation"] },
|
|
31361
|
+
...kimiCodeSection
|
|
31362
|
+
};
|
|
31363
|
+
return new KimiCodeSkill({
|
|
31364
|
+
outputRoot,
|
|
31365
|
+
relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
|
|
31366
|
+
dirName: rulesyncSkill.getDirName(),
|
|
31367
|
+
frontmatter: kimiCodeFrontmatter,
|
|
31368
|
+
body: rulesyncSkill.getBody(),
|
|
31369
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
31370
|
+
validate,
|
|
31371
|
+
global
|
|
31372
|
+
});
|
|
31373
|
+
}
|
|
31374
|
+
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
31375
|
+
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
31376
|
+
return targets.includes("*") || targets.includes("kimi-code");
|
|
31377
|
+
}
|
|
31378
|
+
static async fromDir(params) {
|
|
31379
|
+
const loaded = await this.loadSkillDirContent({
|
|
31380
|
+
...params,
|
|
31381
|
+
getSettablePaths: KimiCodeSkill.getSettablePaths
|
|
31382
|
+
});
|
|
31383
|
+
const result = KimiCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
31384
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
31385
|
+
return new KimiCodeSkill({
|
|
31386
|
+
...loaded,
|
|
31387
|
+
frontmatter: result.data,
|
|
31388
|
+
validate: true
|
|
31389
|
+
});
|
|
31390
|
+
}
|
|
31391
|
+
static async fromFlatFile({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
31392
|
+
const filePath = join(outputRoot, relativeDirPath, relativeFilePath);
|
|
31393
|
+
const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
31394
|
+
const result = KimiCodeFlatSkillFrontmatterSchema.safeParse(frontmatter);
|
|
31395
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
31396
|
+
const fileName = basename(relativeFilePath, extname(relativeFilePath));
|
|
31397
|
+
const firstBodyLine = body.split(/\r?\n/).map((line) => line.trim()).find((line) => line !== "");
|
|
31398
|
+
const normalizedFrontmatter = {
|
|
31399
|
+
...result.data,
|
|
31400
|
+
name: result.data.name ?? fileName,
|
|
31401
|
+
description: result.data.description ?? firstBodyLine?.slice(0, 240) ?? "No description provided."
|
|
31402
|
+
};
|
|
31403
|
+
return new KimiCodeSkill({
|
|
31404
|
+
outputRoot,
|
|
31405
|
+
relativeDirPath,
|
|
31406
|
+
dirName: fileName,
|
|
31407
|
+
frontmatter: normalizedFrontmatter,
|
|
31408
|
+
body: body.trim(),
|
|
31409
|
+
validate: true,
|
|
31410
|
+
global
|
|
31411
|
+
});
|
|
31412
|
+
}
|
|
31413
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
31414
|
+
return new KimiCodeSkill({
|
|
31415
|
+
outputRoot,
|
|
31416
|
+
relativeDirPath: relativeDirPath ?? this.getSettablePaths({ global }).relativeDirPath,
|
|
31417
|
+
dirName,
|
|
31418
|
+
frontmatter: {
|
|
31419
|
+
name: "",
|
|
31420
|
+
description: ""
|
|
31421
|
+
},
|
|
31422
|
+
body: "",
|
|
31423
|
+
validate: false,
|
|
31424
|
+
global
|
|
31425
|
+
});
|
|
31426
|
+
}
|
|
31427
|
+
};
|
|
31428
|
+
//#endregion
|
|
30343
31429
|
//#region src/features/skills/kiro-skill.ts
|
|
30344
31430
|
const KiroSkillFrontmatterSchema = z.looseObject({
|
|
30345
31431
|
name: z.string(),
|
|
@@ -32066,6 +33152,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32066
33152
|
supportsGlobal: true
|
|
32067
33153
|
}
|
|
32068
33154
|
}],
|
|
33155
|
+
["antigravity-plugin", {
|
|
33156
|
+
class: AntigravityPluginSkill,
|
|
33157
|
+
meta: {
|
|
33158
|
+
supportsProject: true,
|
|
33159
|
+
supportsSimulated: false,
|
|
33160
|
+
supportsGlobal: false
|
|
33161
|
+
}
|
|
33162
|
+
}],
|
|
32069
33163
|
["augmentcode", {
|
|
32070
33164
|
class: AugmentcodeSkill,
|
|
32071
33165
|
meta: {
|
|
@@ -32082,6 +33176,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32082
33176
|
supportsGlobal: true
|
|
32083
33177
|
}
|
|
32084
33178
|
}],
|
|
33179
|
+
["claudecode-plugin", {
|
|
33180
|
+
class: ClaudecodePluginSkill,
|
|
33181
|
+
meta: {
|
|
33182
|
+
supportsProject: true,
|
|
33183
|
+
supportsSimulated: false,
|
|
33184
|
+
supportsGlobal: false
|
|
33185
|
+
}
|
|
33186
|
+
}],
|
|
32085
33187
|
["claudecode-legacy", {
|
|
32086
33188
|
class: ClaudecodeSkill,
|
|
32087
33189
|
meta: {
|
|
@@ -32186,6 +33288,14 @@ const toolSkillFactories = /* @__PURE__ */ new Map([
|
|
|
32186
33288
|
supportsGlobal: true
|
|
32187
33289
|
}
|
|
32188
33290
|
}],
|
|
33291
|
+
["kimi-code", {
|
|
33292
|
+
class: KimiCodeSkill,
|
|
33293
|
+
meta: {
|
|
33294
|
+
supportsProject: true,
|
|
33295
|
+
supportsSimulated: false,
|
|
33296
|
+
supportsGlobal: true
|
|
33297
|
+
}
|
|
33298
|
+
}],
|
|
32189
33299
|
["kiro", {
|
|
32190
33300
|
class: KiroSkill,
|
|
32191
33301
|
meta: {
|
|
@@ -32407,36 +33517,56 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
32407
33517
|
*/
|
|
32408
33518
|
async loadToolDirs() {
|
|
32409
33519
|
const factory = this.getFactory(this.toolTarget);
|
|
32410
|
-
const roots =
|
|
32411
|
-
const
|
|
32412
|
-
const
|
|
33520
|
+
const roots = toolSkillImportRoots(factory.class.getSettablePaths({ global: this.global }));
|
|
33521
|
+
const seenSkillNames = /* @__PURE__ */ new Set();
|
|
33522
|
+
const toolSkills = [];
|
|
32413
33523
|
for (const root of roots) {
|
|
32414
|
-
const
|
|
33524
|
+
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
33525
|
+
const relativeDirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
33526
|
+
const skillsDirPath = join(rootOutputRoot, relativeDirPath);
|
|
32415
33527
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
32416
33528
|
const dirPaths = await findFilesByGlobs(join(skillsDirPath, "*"), { type: "dir" });
|
|
33529
|
+
const ownedDirNames = [];
|
|
32417
33530
|
for (const dirPath of dirPaths) {
|
|
32418
33531
|
const dirName = basename(dirPath);
|
|
32419
|
-
if (seenDirNames.has(dirName)) continue;
|
|
32420
33532
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
32421
|
-
outputRoot:
|
|
32422
|
-
relativeDirPath
|
|
33533
|
+
outputRoot: rootOutputRoot,
|
|
33534
|
+
relativeDirPath,
|
|
32423
33535
|
dirName,
|
|
32424
33536
|
inputRoot: this.inputRoot
|
|
32425
33537
|
})) continue;
|
|
32426
|
-
|
|
32427
|
-
|
|
32428
|
-
|
|
32429
|
-
|
|
32430
|
-
|
|
33538
|
+
ownedDirNames.push(dirName);
|
|
33539
|
+
}
|
|
33540
|
+
const directorySkills = await Promise.all(ownedDirNames.map((dirName) => factory.class.fromDir({
|
|
33541
|
+
outputRoot: rootOutputRoot,
|
|
33542
|
+
relativeDirPath,
|
|
33543
|
+
dirName,
|
|
33544
|
+
global: this.global
|
|
33545
|
+
})));
|
|
33546
|
+
for (const skill of directorySkills) {
|
|
33547
|
+
const skillName = skill.getImportIdentity();
|
|
33548
|
+
if (seenSkillNames.has(skillName)) continue;
|
|
33549
|
+
seenSkillNames.add(skillName);
|
|
33550
|
+
toolSkills.push(skill);
|
|
33551
|
+
}
|
|
33552
|
+
if (!factory.class.fromFlatFile) continue;
|
|
33553
|
+
const fromFlatFile = factory.class.fromFlatFile;
|
|
33554
|
+
const directoryStems = new Set(ownedDirNames);
|
|
33555
|
+
const flatFilePaths = (await findFilesByGlobs(join(skillsDirPath, "*.md"), { type: "file" })).filter((filePath) => !directoryStems.has(basename(filePath, ".md")));
|
|
33556
|
+
const flatSkills = await Promise.all(flatFilePaths.map((filePath) => fromFlatFile({
|
|
33557
|
+
outputRoot: rootOutputRoot,
|
|
33558
|
+
relativeDirPath,
|
|
33559
|
+
relativeFilePath: basename(filePath),
|
|
33560
|
+
global: this.global
|
|
33561
|
+
})));
|
|
33562
|
+
for (const skill of flatSkills) {
|
|
33563
|
+
const skillName = skill.getImportIdentity();
|
|
33564
|
+
if (seenSkillNames.has(skillName)) continue;
|
|
33565
|
+
seenSkillNames.add(skillName);
|
|
33566
|
+
toolSkills.push(skill);
|
|
32431
33567
|
}
|
|
32432
33568
|
}
|
|
32433
|
-
|
|
32434
|
-
outputRoot: this.outputRoot,
|
|
32435
|
-
relativeDirPath: root,
|
|
32436
|
-
dirName,
|
|
32437
|
-
global: this.global
|
|
32438
|
-
})));
|
|
32439
|
-
this.logger.debug(`Successfully loaded ${toolSkills.length} skills from ${roots.length} root(s): ${roots.join(", ")}`);
|
|
33569
|
+
this.logger.debug(`Successfully loaded ${toolSkills.length} skills from ${roots.length} root(s)`);
|
|
32440
33570
|
return toolSkills;
|
|
32441
33571
|
}
|
|
32442
33572
|
async loadToolDirsToDelete() {
|
|
@@ -32446,8 +33576,19 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
32446
33576
|
for (const root of roots) {
|
|
32447
33577
|
const skillsDirPath = join(this.outputRoot, root);
|
|
32448
33578
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
32449
|
-
|
|
33579
|
+
await assertWritablePathInsideRoot({
|
|
33580
|
+
rootPath: this.outputRoot,
|
|
33581
|
+
targetPath: skillsDirPath
|
|
33582
|
+
});
|
|
33583
|
+
const dirPaths = await findFilesByGlobs(join(skillsDirPath, "*"), {
|
|
33584
|
+
type: "dir",
|
|
33585
|
+
followSymbolicLinks: false
|
|
33586
|
+
});
|
|
32450
33587
|
for (const dirPath of dirPaths) {
|
|
33588
|
+
await assertWritablePathInsideRoot({
|
|
33589
|
+
rootPath: skillsDirPath,
|
|
33590
|
+
targetPath: dirPath
|
|
33591
|
+
});
|
|
32451
33592
|
const dirName = basename(dirPath);
|
|
32452
33593
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
32453
33594
|
outputRoot: this.outputRoot,
|
|
@@ -32537,6 +33678,10 @@ var ToolSubagent = class extends ToolFile {
|
|
|
32537
33678
|
static fromRulesyncSubagent(_params) {
|
|
32538
33679
|
throw new Error("Please implement this method in the subclass.");
|
|
32539
33680
|
}
|
|
33681
|
+
/** Identity used to resolve duplicate imports across discovery roots. */
|
|
33682
|
+
getImportIdentity() {
|
|
33683
|
+
return this.getRelativeFilePath();
|
|
33684
|
+
}
|
|
32540
33685
|
static isTargetedByRulesyncSubagent(_rulesyncSubagent) {
|
|
32541
33686
|
throw new Error("Please implement this method in the subclass.");
|
|
32542
33687
|
}
|
|
@@ -33198,6 +34343,17 @@ var ClaudecodeSubagent = class ClaudecodeSubagent extends ToolSubagent {
|
|
|
33198
34343
|
}
|
|
33199
34344
|
};
|
|
33200
34345
|
//#endregion
|
|
34346
|
+
//#region src/features/subagents/claudecode-plugin-subagent.ts
|
|
34347
|
+
var ClaudecodePluginSubagent = class extends ClaudecodeSubagent {
|
|
34348
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
34349
|
+
const targets = rulesyncSubagent.getFrontmatter().targets;
|
|
34350
|
+
return targets.includes("*") || targets.includes("claudecode-plugin");
|
|
34351
|
+
}
|
|
34352
|
+
static getSettablePaths() {
|
|
34353
|
+
return { relativeDirPath: CLAUDECODE_PLUGIN_AGENTS_DIR };
|
|
34354
|
+
}
|
|
34355
|
+
};
|
|
34356
|
+
//#endregion
|
|
33201
34357
|
//#region src/features/subagents/cline-subagent.ts
|
|
33202
34358
|
const ClineSubagentFrontmatterSchema = z.looseObject({
|
|
33203
34359
|
name: z.string(),
|
|
@@ -35185,9 +36341,153 @@ var KiloSubagent = class KiloSubagent extends OpenCodeStyleSubagent {
|
|
|
35185
36341
|
}
|
|
35186
36342
|
};
|
|
35187
36343
|
//#endregion
|
|
36344
|
+
//#region src/features/subagents/kimi-code-subagent.ts
|
|
36345
|
+
const KimiCodeAgentNameSchema = z.pipe(z.string(), z.custom((value) => typeof value === "string" && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value), "must be a kebab-case name"));
|
|
36346
|
+
const KimiCodeSubagentFrontmatterSchema = z.looseObject({
|
|
36347
|
+
name: z.optional(KimiCodeAgentNameSchema),
|
|
36348
|
+
description: z.string(),
|
|
36349
|
+
whenToUse: z.optional(z.string()),
|
|
36350
|
+
override: z.optional(z.boolean()),
|
|
36351
|
+
tools: z.optional(z.union([z.string(), z.array(z.string())])),
|
|
36352
|
+
disallowedTools: z.optional(z.union([z.string(), z.array(z.string())])),
|
|
36353
|
+
subagents: z.optional(z.union([z.string(), z.array(z.string())]))
|
|
36354
|
+
});
|
|
36355
|
+
/**
|
|
36356
|
+
* Kimi Code custom agent.
|
|
36357
|
+
*
|
|
36358
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/agents.html
|
|
36359
|
+
*/
|
|
36360
|
+
var KimiCodeSubagent = class KimiCodeSubagent extends ToolSubagent {
|
|
36361
|
+
frontmatter;
|
|
36362
|
+
body;
|
|
36363
|
+
constructor({ frontmatter, body, fileContent, ...rest }) {
|
|
36364
|
+
if (rest.validate !== false) {
|
|
36365
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
36366
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
36367
|
+
}
|
|
36368
|
+
super({
|
|
36369
|
+
...rest,
|
|
36370
|
+
fileContent: fileContent ?? stringifyFrontmatter(body, frontmatter)
|
|
36371
|
+
});
|
|
36372
|
+
this.frontmatter = frontmatter;
|
|
36373
|
+
this.body = body;
|
|
36374
|
+
}
|
|
36375
|
+
static getSettablePaths({ global = false } = {}) {
|
|
36376
|
+
const customHome = global ? getKimiCodeHome() : void 0;
|
|
36377
|
+
return {
|
|
36378
|
+
relativeDirPath: getKimiCodeRelativeDirPath({
|
|
36379
|
+
global,
|
|
36380
|
+
relativeDirPath: KIMI_CODE_AGENTS_DIR_NAME
|
|
36381
|
+
}),
|
|
36382
|
+
importDirPaths: [customHome ? {
|
|
36383
|
+
outputRoot: getHomeDirectory(),
|
|
36384
|
+
relativeDirPath: KIMI_CODE_SHARED_AGENTS_DIR_PATH
|
|
36385
|
+
} : KIMI_CODE_SHARED_AGENTS_DIR_PATH]
|
|
36386
|
+
};
|
|
36387
|
+
}
|
|
36388
|
+
getFrontmatter() {
|
|
36389
|
+
return this.frontmatter;
|
|
36390
|
+
}
|
|
36391
|
+
getBody() {
|
|
36392
|
+
return this.body;
|
|
36393
|
+
}
|
|
36394
|
+
getImportIdentity() {
|
|
36395
|
+
const fileName = basename(this.getRelativeFilePath(), extname(this.getRelativeFilePath()));
|
|
36396
|
+
return KimiCodeAgentNameSchema.parse(this.frontmatter.name ?? fileName).toLowerCase();
|
|
36397
|
+
}
|
|
36398
|
+
toRulesyncSubagent() {
|
|
36399
|
+
const { name: _name, description, ...rest } = this.frontmatter;
|
|
36400
|
+
const resolvedName = this.getImportIdentity();
|
|
36401
|
+
const frontmatter = {
|
|
36402
|
+
targets: ["*"],
|
|
36403
|
+
name: resolvedName,
|
|
36404
|
+
description,
|
|
36405
|
+
...Object.keys(rest).length > 0 && { "kimi-code": rest }
|
|
36406
|
+
};
|
|
36407
|
+
return new RulesyncSubagent({
|
|
36408
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
36409
|
+
nativeOutputRoot: this.outputRoot,
|
|
36410
|
+
global: this.global
|
|
36411
|
+
}),
|
|
36412
|
+
relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
|
|
36413
|
+
relativeFilePath: `${resolvedName}.md`,
|
|
36414
|
+
frontmatter,
|
|
36415
|
+
body: this.body,
|
|
36416
|
+
validate: true,
|
|
36417
|
+
global: this.global
|
|
36418
|
+
});
|
|
36419
|
+
}
|
|
36420
|
+
static fromRulesyncSubagent({ outputRoot = process.cwd(), rulesyncSubagent, validate = true, global = false }) {
|
|
36421
|
+
const frontmatter = rulesyncSubagent.getFrontmatter();
|
|
36422
|
+
const toolSection = frontmatter["kimi-code"] ?? {};
|
|
36423
|
+
const kimiCodeFrontmatter = KimiCodeSubagentFrontmatterSchema.parse({
|
|
36424
|
+
name: frontmatter.name,
|
|
36425
|
+
description: frontmatter.description,
|
|
36426
|
+
...toolSection
|
|
36427
|
+
});
|
|
36428
|
+
const body = rulesyncSubagent.getBody();
|
|
36429
|
+
return new KimiCodeSubagent({
|
|
36430
|
+
outputRoot,
|
|
36431
|
+
relativeDirPath: this.getSettablePaths({ global }).relativeDirPath,
|
|
36432
|
+
relativeFilePath: rulesyncSubagent.getRelativeFilePath(),
|
|
36433
|
+
frontmatter: kimiCodeFrontmatter,
|
|
36434
|
+
body,
|
|
36435
|
+
fileContent: stringifyFrontmatter(body, kimiCodeFrontmatter, { avoidBlockScalars: true }),
|
|
36436
|
+
validate,
|
|
36437
|
+
global
|
|
36438
|
+
});
|
|
36439
|
+
}
|
|
36440
|
+
validate() {
|
|
36441
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(this.frontmatter);
|
|
36442
|
+
return result.success ? {
|
|
36443
|
+
success: true,
|
|
36444
|
+
error: null
|
|
36445
|
+
} : {
|
|
36446
|
+
success: false,
|
|
36447
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
36448
|
+
};
|
|
36449
|
+
}
|
|
36450
|
+
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
36451
|
+
return this.isTargetedByRulesyncSubagentDefault({
|
|
36452
|
+
rulesyncSubagent,
|
|
36453
|
+
toolTarget: "kimi-code"
|
|
36454
|
+
});
|
|
36455
|
+
}
|
|
36456
|
+
static async fromFile({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, validate = true, global = false }) {
|
|
36457
|
+
const actualRelativeDirPath = relativeDirPath ?? this.getSettablePaths({ global }).relativeDirPath;
|
|
36458
|
+
const filePath = join(outputRoot, actualRelativeDirPath, relativeFilePath);
|
|
36459
|
+
const fileContent = await readFileContent(filePath);
|
|
36460
|
+
const { frontmatter, body } = parseFrontmatter(fileContent, filePath);
|
|
36461
|
+
const result = KimiCodeSubagentFrontmatterSchema.safeParse(frontmatter);
|
|
36462
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
36463
|
+
return new KimiCodeSubagent({
|
|
36464
|
+
outputRoot,
|
|
36465
|
+
relativeDirPath: actualRelativeDirPath,
|
|
36466
|
+
relativeFilePath,
|
|
36467
|
+
frontmatter: result.data,
|
|
36468
|
+
body: body.trim(),
|
|
36469
|
+
fileContent,
|
|
36470
|
+
validate,
|
|
36471
|
+
global
|
|
36472
|
+
});
|
|
36473
|
+
}
|
|
36474
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
36475
|
+
return new KimiCodeSubagent({
|
|
36476
|
+
outputRoot,
|
|
36477
|
+
relativeDirPath,
|
|
36478
|
+
relativeFilePath,
|
|
36479
|
+
frontmatter: { description: "" },
|
|
36480
|
+
body: "",
|
|
36481
|
+
fileContent: "",
|
|
36482
|
+
validate: false,
|
|
36483
|
+
global
|
|
36484
|
+
});
|
|
36485
|
+
}
|
|
36486
|
+
};
|
|
36487
|
+
//#endregion
|
|
35188
36488
|
//#region src/features/subagents/kiro-subagent.ts
|
|
35189
36489
|
const KiroCliSubagentJsonSchema = z.looseObject({
|
|
35190
|
-
name: z.string(),
|
|
36490
|
+
name: z.optional(z.string()),
|
|
35191
36491
|
description: z.optional(z.nullable(z.string())),
|
|
35192
36492
|
prompt: z.optional(z.nullable(z.string())),
|
|
35193
36493
|
tools: z.optional(z.nullable(z.array(z.string()))),
|
|
@@ -35202,7 +36502,7 @@ const KiroCliSubagentJsonSchema = z.looseObject({
|
|
|
35202
36502
|
allowedTools: z.optional(z.nullable(z.array(z.string()))),
|
|
35203
36503
|
includeMcpJson: z.optional(z.nullable(z.boolean()))
|
|
35204
36504
|
});
|
|
35205
|
-
var KiroSubagent = class
|
|
36505
|
+
var KiroSubagent = class extends ToolSubagent {
|
|
35206
36506
|
body;
|
|
35207
36507
|
constructor({ body, ...rest }) {
|
|
35208
36508
|
if (rest.validate !== false) try {
|
|
@@ -35220,6 +36520,9 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35220
36520
|
getBody() {
|
|
35221
36521
|
return this.body;
|
|
35222
36522
|
}
|
|
36523
|
+
static getToolTarget() {
|
|
36524
|
+
return "kiro";
|
|
36525
|
+
}
|
|
35223
36526
|
toRulesyncSubagent() {
|
|
35224
36527
|
let parsed;
|
|
35225
36528
|
try {
|
|
@@ -35228,12 +36531,13 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35228
36531
|
throw new Error(`Failed to parse JSON in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
35229
36532
|
}
|
|
35230
36533
|
const { name, description, prompt, ...restFields } = parsed;
|
|
36534
|
+
const toolTarget = this.constructor.getToolTarget();
|
|
35231
36535
|
const kiroSection = { ...restFields };
|
|
35232
36536
|
return new RulesyncSubagent({
|
|
35233
36537
|
outputRoot: ".",
|
|
35234
36538
|
frontmatter: {
|
|
35235
|
-
targets: [
|
|
35236
|
-
name,
|
|
36539
|
+
targets: [toolTarget],
|
|
36540
|
+
name: name ?? basename(this.getRelativeFilePath(), ".json"),
|
|
35237
36541
|
description: description ?? void 0,
|
|
35238
36542
|
...Object.keys(kiroSection).length > 0 && { kiro: kiroSection }
|
|
35239
36543
|
},
|
|
@@ -35260,7 +36564,7 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35260
36564
|
const body = JSON.stringify(json, null, 2);
|
|
35261
36565
|
const paths = this.getSettablePaths({ global });
|
|
35262
36566
|
const relativeFilePath = rulesyncSubagent.getRelativeFilePath().replace(/\.md$/, ".json");
|
|
35263
|
-
return new
|
|
36567
|
+
return new this({
|
|
35264
36568
|
outputRoot,
|
|
35265
36569
|
body,
|
|
35266
36570
|
relativeDirPath: paths.relativeDirPath,
|
|
@@ -35288,14 +36592,14 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35288
36592
|
static isTargetedByRulesyncSubagent(rulesyncSubagent) {
|
|
35289
36593
|
return this.isTargetedByRulesyncSubagentDefault({
|
|
35290
36594
|
rulesyncSubagent,
|
|
35291
|
-
toolTarget:
|
|
36595
|
+
toolTarget: this.getToolTarget()
|
|
35292
36596
|
});
|
|
35293
36597
|
}
|
|
35294
36598
|
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
35295
36599
|
const paths = this.getSettablePaths({ global });
|
|
35296
36600
|
const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
35297
36601
|
const fileContent = await readFileContent(filePath);
|
|
35298
|
-
const subagent = new
|
|
36602
|
+
const subagent = new this({
|
|
35299
36603
|
outputRoot,
|
|
35300
36604
|
relativeDirPath: paths.relativeDirPath,
|
|
35301
36605
|
relativeFilePath,
|
|
@@ -35311,7 +36615,7 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35311
36615
|
return subagent;
|
|
35312
36616
|
}
|
|
35313
36617
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
35314
|
-
return new
|
|
36618
|
+
return new this({
|
|
35315
36619
|
outputRoot,
|
|
35316
36620
|
relativeDirPath,
|
|
35317
36621
|
relativeFilePath,
|
|
@@ -35333,11 +36637,8 @@ var KiroSubagent = class KiroSubagent extends ToolSubagent {
|
|
|
35333
36637
|
* {@link import("./kiro-ide-subagent.js").KiroIdeSubagent}.)
|
|
35334
36638
|
*/
|
|
35335
36639
|
var KiroCliSubagent = class extends KiroSubagent {
|
|
35336
|
-
static
|
|
35337
|
-
return
|
|
35338
|
-
rulesyncSubagent,
|
|
35339
|
-
toolTarget: "kiro-cli"
|
|
35340
|
-
});
|
|
36640
|
+
static getToolTarget() {
|
|
36641
|
+
return "kiro-cli";
|
|
35341
36642
|
}
|
|
35342
36643
|
};
|
|
35343
36644
|
//#endregion
|
|
@@ -36324,6 +37625,14 @@ const toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
|
36324
37625
|
filePattern: "*.md"
|
|
36325
37626
|
}
|
|
36326
37627
|
}],
|
|
37628
|
+
["claudecode-plugin", {
|
|
37629
|
+
class: ClaudecodePluginSubagent,
|
|
37630
|
+
meta: {
|
|
37631
|
+
supportsSimulated: false,
|
|
37632
|
+
supportsGlobal: false,
|
|
37633
|
+
filePattern: "*.md"
|
|
37634
|
+
}
|
|
37635
|
+
}],
|
|
36327
37636
|
["claudecode-legacy", {
|
|
36328
37637
|
class: ClaudecodeSubagent,
|
|
36329
37638
|
meta: {
|
|
@@ -36460,6 +37769,14 @@ const toolSubagentFactories = /* @__PURE__ */ new Map([
|
|
|
36460
37769
|
filePattern: "*.md"
|
|
36461
37770
|
}
|
|
36462
37771
|
}],
|
|
37772
|
+
["kimi-code", {
|
|
37773
|
+
class: KimiCodeSubagent,
|
|
37774
|
+
meta: {
|
|
37775
|
+
supportsSimulated: false,
|
|
37776
|
+
supportsGlobal: true,
|
|
37777
|
+
filePattern: join("**", "*.md")
|
|
37778
|
+
}
|
|
37779
|
+
}],
|
|
36463
37780
|
["opencode", {
|
|
36464
37781
|
class: OpenCodeSubagent,
|
|
36465
37782
|
meta: {
|
|
@@ -36581,7 +37898,18 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36581
37898
|
}
|
|
36582
37899
|
rulesyncSubagents.push(toolSubagent.toRulesyncSubagent());
|
|
36583
37900
|
}
|
|
36584
|
-
|
|
37901
|
+
const uniqueRulesyncSubagents = [];
|
|
37902
|
+
const seenOutputPaths = /* @__PURE__ */ new Set();
|
|
37903
|
+
for (const rulesyncSubagent of rulesyncSubagents) {
|
|
37904
|
+
const outputPath = join(rulesyncSubagent.getRelativeDirPath(), rulesyncSubagent.getRelativeFilePath());
|
|
37905
|
+
if (seenOutputPaths.has(outputPath)) {
|
|
37906
|
+
this.logger.warn(`Multiple ${this.toolTarget} subagents resolve to "${outputPath}"; keeping the first and ignoring this copy.`);
|
|
37907
|
+
continue;
|
|
37908
|
+
}
|
|
37909
|
+
seenOutputPaths.add(outputPath);
|
|
37910
|
+
uniqueRulesyncSubagents.push(rulesyncSubagent);
|
|
37911
|
+
}
|
|
37912
|
+
return uniqueRulesyncSubagents;
|
|
36585
37913
|
}
|
|
36586
37914
|
/**
|
|
36587
37915
|
* Implementation of abstract method from Processor
|
|
@@ -36629,25 +37957,35 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36629
37957
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
36630
37958
|
const factory = this.getFactory(this.toolTarget);
|
|
36631
37959
|
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
36632
|
-
const
|
|
37960
|
+
const roots = forDeletion ? [paths.relativeDirPath] : [paths.relativeDirPath, ...paths.importDirPaths ?? []];
|
|
36633
37961
|
const toolSubagents = [];
|
|
36634
37962
|
const seenRelativeFilePaths = /* @__PURE__ */ new Set();
|
|
36635
|
-
for (const
|
|
36636
|
-
const
|
|
36637
|
-
const
|
|
37963
|
+
for (const root of roots) {
|
|
37964
|
+
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
37965
|
+
const dirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
37966
|
+
const baseDir = join(rootOutputRoot, dirPath);
|
|
37967
|
+
if (forDeletion && await directoryExists(baseDir)) await assertWritablePathInsideRoot({
|
|
37968
|
+
rootPath: rootOutputRoot,
|
|
37969
|
+
targetPath: baseDir
|
|
37970
|
+
});
|
|
37971
|
+
const subagentFilePaths = await findFilesByGlobs(join(baseDir, factory.meta.filePattern), { followSymbolicLinks: !forDeletion });
|
|
36638
37972
|
const toRelativeFilePath = (path) => relative(baseDir, path);
|
|
36639
37973
|
let ownedFilePaths = subagentFilePaths;
|
|
36640
37974
|
if (factory.class.isFileOwned) {
|
|
36641
37975
|
const ownership = await Promise.all(subagentFilePaths.map((path) => factory.class.isFileOwned({
|
|
36642
|
-
outputRoot:
|
|
37976
|
+
outputRoot: rootOutputRoot,
|
|
36643
37977
|
relativeDirPath: dirPath,
|
|
36644
37978
|
relativeFilePath: toRelativeFilePath(path)
|
|
36645
37979
|
})));
|
|
36646
37980
|
ownedFilePaths = subagentFilePaths.filter((_, index) => ownership[index]);
|
|
36647
37981
|
}
|
|
36648
37982
|
if (forDeletion) {
|
|
37983
|
+
await Promise.all(ownedFilePaths.map((path) => assertWritablePathInsideRoot({
|
|
37984
|
+
rootPath: baseDir,
|
|
37985
|
+
targetPath: path
|
|
37986
|
+
})));
|
|
36649
37987
|
toolSubagents.push(...ownedFilePaths.map((path) => factory.class.forDeletion({
|
|
36650
|
-
outputRoot:
|
|
37988
|
+
outputRoot: rootOutputRoot,
|
|
36651
37989
|
relativeDirPath: dirPath,
|
|
36652
37990
|
relativeFilePath: toRelativeFilePath(path),
|
|
36653
37991
|
global: this.global
|
|
@@ -36655,14 +37993,14 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36655
37993
|
continue;
|
|
36656
37994
|
}
|
|
36657
37995
|
const loaded = await Promise.all(ownedFilePaths.map((path) => factory.class.fromFile({
|
|
36658
|
-
outputRoot:
|
|
37996
|
+
outputRoot: rootOutputRoot,
|
|
36659
37997
|
relativeDirPath: dirPath,
|
|
36660
37998
|
relativeFilePath: toRelativeFilePath(path),
|
|
36661
37999
|
global: this.global
|
|
36662
38000
|
})));
|
|
36663
38001
|
const deduped = [];
|
|
36664
38002
|
for (const subagent of loaded) {
|
|
36665
|
-
const key = subagent.
|
|
38003
|
+
const key = subagent.getImportIdentity();
|
|
36666
38004
|
if (seenRelativeFilePaths.has(key)) {
|
|
36667
38005
|
this.logger.warn(`Duplicate ${this.toolTarget} subagent "${key}" found in ${dirPath}; keeping the one from a higher-precedence directory and ignoring this copy.`);
|
|
36668
38006
|
continue;
|
|
@@ -36678,7 +38016,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36678
38016
|
global: this.global
|
|
36679
38017
|
});
|
|
36680
38018
|
for (const subagent of additionalSubagents) {
|
|
36681
|
-
const key = subagent.
|
|
38019
|
+
const key = subagent.getImportIdentity();
|
|
36682
38020
|
if (seenRelativeFilePaths.has(key)) {
|
|
36683
38021
|
this.logger.warn(`Duplicate ${this.toolTarget} subagent "${key}" defined inline; keeping the standalone file and ignoring the inline copy.`);
|
|
36684
38022
|
continue;
|
|
@@ -36687,7 +38025,7 @@ var SubagentsProcessor = class extends FeatureProcessor {
|
|
|
36687
38025
|
toolSubagents.push(subagent);
|
|
36688
38026
|
}
|
|
36689
38027
|
}
|
|
36690
|
-
this.logger.debug(`Successfully loaded ${toolSubagents.length} ${this.toolTarget} subagents from ${
|
|
38028
|
+
this.logger.debug(`Successfully loaded ${toolSubagents.length} ${this.toolTarget} subagents from ${roots.length} root(s)`);
|
|
36691
38029
|
return toolSubagents;
|
|
36692
38030
|
}
|
|
36693
38031
|
/**
|
|
@@ -37351,17 +38689,18 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37351
38689
|
};
|
|
37352
38690
|
}
|
|
37353
38691
|
static getSettablePaths({ global = false, excludeToolDir } = {}) {
|
|
37354
|
-
if (global) return { root:
|
|
38692
|
+
if (global) return { root: this.getGlobalRootPath(excludeToolDir) };
|
|
37355
38693
|
return {
|
|
37356
|
-
root:
|
|
38694
|
+
root: this.getProjectRootPath(),
|
|
37357
38695
|
nonRoot: { relativeDirPath: buildToolPath(ANTIGRAVITY_IDE_AGENTS_DIR, "rules", excludeToolDir) }
|
|
37358
38696
|
};
|
|
37359
38697
|
}
|
|
37360
38698
|
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
38699
|
+
const paths = this.getSettablePaths({ global });
|
|
37361
38700
|
if (global) {
|
|
37362
|
-
const rootPath =
|
|
38701
|
+
const rootPath = paths.root;
|
|
37363
38702
|
const fileContent = await readFileContent(join(outputRoot, rootPath.relativeDirPath, rootPath.relativeFilePath));
|
|
37364
|
-
return new
|
|
38703
|
+
return new this({
|
|
37365
38704
|
outputRoot,
|
|
37366
38705
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37367
38706
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37371,10 +38710,10 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37371
38710
|
root: true
|
|
37372
38711
|
});
|
|
37373
38712
|
}
|
|
37374
|
-
if (relativeFilePath ===
|
|
37375
|
-
const rootPath =
|
|
38713
|
+
if (relativeFilePath === paths.root.relativeFilePath) {
|
|
38714
|
+
const rootPath = paths.root;
|
|
37376
38715
|
const rootContent = await readFileContent(join(outputRoot, rootPath.relativeDirPath, rootPath.relativeFilePath));
|
|
37377
|
-
return new
|
|
38716
|
+
return new this({
|
|
37378
38717
|
outputRoot,
|
|
37379
38718
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37380
38719
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37384,7 +38723,8 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37384
38723
|
root: true
|
|
37385
38724
|
});
|
|
37386
38725
|
}
|
|
37387
|
-
|
|
38726
|
+
if (!("nonRoot" in paths) || !paths.nonRoot) throw new Error(`nonRoot path is not set for ${relativeFilePath}`);
|
|
38727
|
+
const nonRootDirPath = paths.nonRoot.relativeDirPath;
|
|
37388
38728
|
const filePath = join(outputRoot, nonRootDirPath, relativeFilePath);
|
|
37389
38729
|
const { frontmatter, body } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
37390
38730
|
let parsedFrontmatter;
|
|
@@ -37393,7 +38733,7 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37393
38733
|
if (result.success) parsedFrontmatter = result.data;
|
|
37394
38734
|
else throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
37395
38735
|
} else parsedFrontmatter = frontmatter;
|
|
37396
|
-
return new
|
|
38736
|
+
return new this({
|
|
37397
38737
|
outputRoot,
|
|
37398
38738
|
relativeDirPath: nonRootDirPath,
|
|
37399
38739
|
relativeFilePath,
|
|
@@ -37404,9 +38744,10 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37404
38744
|
});
|
|
37405
38745
|
}
|
|
37406
38746
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
38747
|
+
const paths = this.getSettablePaths({ global });
|
|
37407
38748
|
if (global) {
|
|
37408
|
-
const rootPath =
|
|
37409
|
-
return new
|
|
38749
|
+
const rootPath = paths.root;
|
|
38750
|
+
return new this({
|
|
37410
38751
|
outputRoot,
|
|
37411
38752
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37412
38753
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37417,8 +38758,8 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37417
38758
|
});
|
|
37418
38759
|
}
|
|
37419
38760
|
if (rulesyncRule.getFrontmatter().root) {
|
|
37420
|
-
const rootPath =
|
|
37421
|
-
return new
|
|
38761
|
+
const rootPath = paths.root;
|
|
38762
|
+
return new this({
|
|
37422
38763
|
outputRoot,
|
|
37423
38764
|
relativeDirPath: rootPath.relativeDirPath,
|
|
37424
38765
|
relativeFilePath: rootPath.relativeFilePath,
|
|
@@ -37435,10 +38776,11 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37435
38776
|
const strategy = STRATEGIES$1.find((s) => s.canHandle(storedTrigger));
|
|
37436
38777
|
if (!strategy) throw new Error(`No strategy found for trigger: ${storedTrigger}`);
|
|
37437
38778
|
const frontmatter = strategy.generateFrontmatter(normalized, rulesyncFrontmatter);
|
|
38779
|
+
if (!("nonRoot" in paths) || !paths.nonRoot) throw new Error(`nonRoot path is not set for ${rulesyncRule.getRelativeFilePath()}`);
|
|
37438
38780
|
const kebabCaseFilename = toKebabCaseFilename(rulesyncRule.getRelativeFilePath());
|
|
37439
|
-
return new
|
|
38781
|
+
return new this({
|
|
37440
38782
|
outputRoot,
|
|
37441
|
-
relativeDirPath:
|
|
38783
|
+
relativeDirPath: paths.nonRoot.relativeDirPath,
|
|
37442
38784
|
relativeFilePath: kebabCaseFilename,
|
|
37443
38785
|
frontmatter,
|
|
37444
38786
|
body: rulesyncRule.getBody(),
|
|
@@ -37507,6 +38849,23 @@ var AntigravityIdeRule = class AntigravityIdeRule extends ToolRule {
|
|
|
37507
38849
|
}
|
|
37508
38850
|
};
|
|
37509
38851
|
//#endregion
|
|
38852
|
+
//#region src/features/rules/antigravity-plugin-rule.ts
|
|
38853
|
+
var AntigravityPluginRule = class extends AntigravityIdeRule {
|
|
38854
|
+
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
38855
|
+
const targets = rulesyncRule.getFrontmatter().targets;
|
|
38856
|
+
return targets.includes("*") || targets.includes("antigravity-plugin");
|
|
38857
|
+
}
|
|
38858
|
+
static getSettablePaths() {
|
|
38859
|
+
return {
|
|
38860
|
+
root: {
|
|
38861
|
+
relativeDirPath: ANTIGRAVITY_PLUGIN_RULES_DIR,
|
|
38862
|
+
relativeFilePath: "AGENTS.md"
|
|
38863
|
+
},
|
|
38864
|
+
nonRoot: { relativeDirPath: ANTIGRAVITY_PLUGIN_RULES_DIR }
|
|
38865
|
+
};
|
|
38866
|
+
}
|
|
38867
|
+
};
|
|
38868
|
+
//#endregion
|
|
37510
38869
|
//#region src/features/rules/augmentcode-legacy-rule.ts
|
|
37511
38870
|
var AugmentcodeLegacyRule = class AugmentcodeLegacyRule extends ToolRule {
|
|
37512
38871
|
toRulesyncRule() {
|
|
@@ -39456,13 +40815,17 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
39456
40815
|
if (global) {
|
|
39457
40816
|
const paths = this.getSettablePaths({ global: true });
|
|
39458
40817
|
if (!("root" in paths) || !paths.root) throw new Error("JunieRule global settable paths must include a root path");
|
|
39459
|
-
|
|
39460
|
-
return new JunieRule(
|
|
40818
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
40819
|
+
return new JunieRule({
|
|
39461
40820
|
outputRoot,
|
|
39462
|
-
|
|
40821
|
+
relativeDirPath: paths.root.relativeDirPath,
|
|
40822
|
+
relativeFilePath: paths.root.relativeFilePath,
|
|
40823
|
+
fileContent: rulesyncRule.getBody(),
|
|
39463
40824
|
validate,
|
|
39464
|
-
|
|
39465
|
-
|
|
40825
|
+
root: frontmatter.root ?? false,
|
|
40826
|
+
description: frontmatter.description,
|
|
40827
|
+
globs: frontmatter.globs
|
|
40828
|
+
});
|
|
39466
40829
|
}
|
|
39467
40830
|
const { root } = this.getSettablePaths();
|
|
39468
40831
|
return new JunieRule({
|
|
@@ -39583,6 +40946,97 @@ var KiloRule = class KiloRule extends ToolRule {
|
|
|
39583
40946
|
}
|
|
39584
40947
|
};
|
|
39585
40948
|
//#endregion
|
|
40949
|
+
//#region src/features/rules/kimi-code-rule.ts
|
|
40950
|
+
/**
|
|
40951
|
+
* Kimi Code instruction file.
|
|
40952
|
+
*
|
|
40953
|
+
* Kimi Code discovers `.kimi-code/AGENTS.md` at project scope and
|
|
40954
|
+
* `~/.kimi-code/AGENTS.md` at user scope. Rulesync's topic rules have no
|
|
40955
|
+
* dedicated Kimi rule directory, so the processor folds them into this root
|
|
40956
|
+
* instruction file.
|
|
40957
|
+
*
|
|
40958
|
+
* @see https://moonshotai.github.io/kimi-code/en/customization/agents.html
|
|
40959
|
+
*/
|
|
40960
|
+
var KimiCodeRule = class KimiCodeRule extends ToolRule {
|
|
40961
|
+
constructor({ fileContent, root, ...rest }) {
|
|
40962
|
+
super({
|
|
40963
|
+
...rest,
|
|
40964
|
+
fileContent,
|
|
40965
|
+
root: root ?? false
|
|
40966
|
+
});
|
|
40967
|
+
}
|
|
40968
|
+
static getSettablePaths({ global = false } = {}) {
|
|
40969
|
+
return { root: {
|
|
40970
|
+
relativeDirPath: getKimiCodeRelativeDirPath({ global }),
|
|
40971
|
+
relativeFilePath: KIMI_CODE_RULE_FILE_NAME
|
|
40972
|
+
} };
|
|
40973
|
+
}
|
|
40974
|
+
static async fromFile({ outputRoot = process.cwd(), validate = true, global = false }) {
|
|
40975
|
+
const { root } = this.getSettablePaths({ global });
|
|
40976
|
+
const fileContent = await readFileContent(join(outputRoot, root.relativeDirPath, root.relativeFilePath));
|
|
40977
|
+
return new KimiCodeRule({
|
|
40978
|
+
outputRoot,
|
|
40979
|
+
relativeDirPath: root.relativeDirPath,
|
|
40980
|
+
relativeFilePath: root.relativeFilePath,
|
|
40981
|
+
fileContent,
|
|
40982
|
+
validate,
|
|
40983
|
+
global,
|
|
40984
|
+
root: true
|
|
40985
|
+
});
|
|
40986
|
+
}
|
|
40987
|
+
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
40988
|
+
const { root } = this.getSettablePaths({ global });
|
|
40989
|
+
return new KimiCodeRule({
|
|
40990
|
+
outputRoot,
|
|
40991
|
+
relativeDirPath: root.relativeDirPath,
|
|
40992
|
+
relativeFilePath: root.relativeFilePath,
|
|
40993
|
+
fileContent: rulesyncRule.getBody(),
|
|
40994
|
+
validate,
|
|
40995
|
+
global,
|
|
40996
|
+
root: rulesyncRule.getFrontmatter().root ?? false
|
|
40997
|
+
});
|
|
40998
|
+
}
|
|
40999
|
+
toRulesyncRule() {
|
|
41000
|
+
return new RulesyncRule({
|
|
41001
|
+
outputRoot: getKimiCodeRulesyncOutputRoot({
|
|
41002
|
+
nativeOutputRoot: this.outputRoot,
|
|
41003
|
+
global: this.global
|
|
41004
|
+
}),
|
|
41005
|
+
relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
|
|
41006
|
+
relativeFilePath: RULESYNC_OVERVIEW_FILE_NAME,
|
|
41007
|
+
frontmatter: {
|
|
41008
|
+
root: true,
|
|
41009
|
+
targets: ["*"],
|
|
41010
|
+
globs: ["**/*"]
|
|
41011
|
+
},
|
|
41012
|
+
body: this.getFileContent()
|
|
41013
|
+
});
|
|
41014
|
+
}
|
|
41015
|
+
validate() {
|
|
41016
|
+
return {
|
|
41017
|
+
success: true,
|
|
41018
|
+
error: null
|
|
41019
|
+
};
|
|
41020
|
+
}
|
|
41021
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
41022
|
+
return new KimiCodeRule({
|
|
41023
|
+
outputRoot,
|
|
41024
|
+
relativeDirPath,
|
|
41025
|
+
relativeFilePath,
|
|
41026
|
+
fileContent: "",
|
|
41027
|
+
validate: false,
|
|
41028
|
+
global,
|
|
41029
|
+
root: relativeDirPath === getKimiCodeRelativeDirPath({ global }) && relativeFilePath === "AGENTS.md"
|
|
41030
|
+
});
|
|
41031
|
+
}
|
|
41032
|
+
static isTargetedByRulesyncRule(rulesyncRule) {
|
|
41033
|
+
return this.isTargetedByRulesyncRuleDefault({
|
|
41034
|
+
rulesyncRule,
|
|
41035
|
+
toolTarget: "kimi-code"
|
|
41036
|
+
});
|
|
41037
|
+
}
|
|
41038
|
+
};
|
|
41039
|
+
//#endregion
|
|
39586
41040
|
//#region src/features/rules/kiro-rule.ts
|
|
39587
41041
|
const WILDCARD_GLOBS = /* @__PURE__ */ new Set([
|
|
39588
41042
|
"**/*",
|
|
@@ -41033,6 +42487,14 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
41033
42487
|
ruleDiscoveryMode: "auto"
|
|
41034
42488
|
}
|
|
41035
42489
|
}],
|
|
42490
|
+
["antigravity-plugin", {
|
|
42491
|
+
class: AntigravityPluginRule,
|
|
42492
|
+
meta: {
|
|
42493
|
+
extension: "md",
|
|
42494
|
+
supportsGlobal: false,
|
|
42495
|
+
ruleDiscoveryMode: "auto"
|
|
42496
|
+
}
|
|
42497
|
+
}],
|
|
41036
42498
|
["augmentcode", {
|
|
41037
42499
|
class: AugmentcodeRule,
|
|
41038
42500
|
meta: {
|
|
@@ -41172,6 +42634,15 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
41172
42634
|
mcpInstructionsRegistrar: KiloMcp
|
|
41173
42635
|
}
|
|
41174
42636
|
}],
|
|
42637
|
+
["kimi-code", {
|
|
42638
|
+
class: KimiCodeRule,
|
|
42639
|
+
meta: {
|
|
42640
|
+
extension: "md",
|
|
42641
|
+
supportsGlobal: true,
|
|
42642
|
+
ruleDiscoveryMode: "auto",
|
|
42643
|
+
foldsNonRootIntoRoot: true
|
|
42644
|
+
}
|
|
42645
|
+
}],
|
|
41175
42646
|
["kiro", {
|
|
41176
42647
|
class: KiroRule,
|
|
41177
42648
|
meta: {
|
|
@@ -41645,7 +43116,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
41645
43116
|
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)})`);
|
|
41646
43117
|
if (this.global) {
|
|
41647
43118
|
const globalPaths = factory.class.getSettablePaths({ global: true });
|
|
41648
|
-
const supportsGlobalNonRoot = "nonRoot" in globalPaths && globalPaths.nonRoot !== null;
|
|
43119
|
+
const supportsGlobalNonRoot = "nonRoot" in globalPaths && globalPaths.nonRoot !== null || factory.meta.supportsGlobal && factory.meta.foldsNonRootIntoRoot === true;
|
|
41649
43120
|
const nonRootRules = rulesyncRules.filter((rule) => !rule.getFrontmatter().root && !rule.getFrontmatter().localRoot && factory.class.isTargetedByRulesyncRule(rule));
|
|
41650
43121
|
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)}`);
|
|
41651
43122
|
if (targetedLocalRootRules.length > 0) this.logger.warn(`${targetedLocalRootRules.length} localRoot rules found, but localRoot is not supported in global mode, ignoring them: ${formatRulePaths(targetedLocalRootRules)}`);
|
|
@@ -41848,12 +43319,25 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
41848
43319
|
}
|
|
41849
43320
|
};
|
|
41850
43321
|
//#endregion
|
|
43322
|
+
//#region src/utils/plugin-root.ts
|
|
43323
|
+
function isPackagingToolTarget(toolTarget) {
|
|
43324
|
+
return PACKAGING_TOOL_TARGETS.includes(toolTarget);
|
|
43325
|
+
}
|
|
43326
|
+
async function assertPluginRootSafe(params) {
|
|
43327
|
+
if (!isPackagingToolTarget(params.toolTarget)) return;
|
|
43328
|
+
await assertDirectoryIfExists(params.outputRoot);
|
|
43329
|
+
if (!await directoryExists(params.outputRoot)) throw new Error(`Plugin output root must be an existing directory: ${params.outputRoot}.`);
|
|
43330
|
+
await assertTreeContainsNoSymlinks(params.outputRoot);
|
|
43331
|
+
}
|
|
43332
|
+
//#endregion
|
|
41851
43333
|
//#region src/lib/convert.ts
|
|
41852
43334
|
/**
|
|
41853
43335
|
* Convert configuration files between AI tools without writing intermediate
|
|
41854
43336
|
* `.rulesync/` files to disk. Rulesync file instances live in memory only.
|
|
41855
43337
|
*/
|
|
41856
43338
|
async function convertFromTool(params) {
|
|
43339
|
+
const packagingTarget = [params.fromTool, ...params.toTools].find(isPackagingToolTarget);
|
|
43340
|
+
if (packagingTarget) throw new Error(`Plugin packaging target '${packagingTarget}' is not supported by convert. Use import and generate with explicit plugin directories.`);
|
|
41857
43341
|
const ctx = params;
|
|
41858
43342
|
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount, checksCount] = [
|
|
41859
43343
|
await runFeatureConvert(ctx, buildRulesStrategy(ctx)),
|
|
@@ -41932,7 +43416,11 @@ function buildRulesStrategy(ctx) {
|
|
|
41932
43416
|
itemLabel: "rule file(s)",
|
|
41933
43417
|
allTargets: RulesProcessor.getToolTargets({ global }),
|
|
41934
43418
|
createProcessor: ({ toolTarget, dryRun }) => new RulesProcessor({
|
|
41935
|
-
outputRoot
|
|
43419
|
+
outputRoot: resolveToolOutputRoot({
|
|
43420
|
+
outputRoot,
|
|
43421
|
+
toolTarget,
|
|
43422
|
+
global
|
|
43423
|
+
}),
|
|
41936
43424
|
toolTarget,
|
|
41937
43425
|
global,
|
|
41938
43426
|
dryRun,
|
|
@@ -41946,18 +43434,20 @@ function buildRulesStrategy(ctx) {
|
|
|
41946
43434
|
}
|
|
41947
43435
|
function buildIgnoreStrategy(ctx) {
|
|
41948
43436
|
const { config, logger } = ctx;
|
|
41949
|
-
|
|
41950
|
-
logger.debug("Skipping ignore conversion (not supported in global mode)");
|
|
41951
|
-
return null;
|
|
41952
|
-
}
|
|
43437
|
+
const global = config.getGlobal();
|
|
41953
43438
|
const outputRoot = getOutputRoot(config);
|
|
41954
43439
|
return {
|
|
41955
43440
|
feature: "ignore",
|
|
41956
43441
|
itemLabel: "ignore file(s)",
|
|
41957
|
-
allTargets: IgnoreProcessor.getToolTargets(),
|
|
43442
|
+
allTargets: IgnoreProcessor.getToolTargets({ global }),
|
|
41958
43443
|
createProcessor: ({ toolTarget, dryRun }) => new IgnoreProcessor({
|
|
41959
|
-
outputRoot
|
|
43444
|
+
outputRoot: resolveToolOutputRoot({
|
|
43445
|
+
outputRoot,
|
|
43446
|
+
toolTarget,
|
|
43447
|
+
global
|
|
43448
|
+
}),
|
|
41960
43449
|
toolTarget,
|
|
43450
|
+
global,
|
|
41961
43451
|
dryRun,
|
|
41962
43452
|
logger,
|
|
41963
43453
|
featureOptions: config.getFeatureOptions(toolTarget, "ignore")
|
|
@@ -41977,7 +43467,11 @@ function buildMcpStrategy(ctx) {
|
|
|
41977
43467
|
itemLabel: "MCP file(s)",
|
|
41978
43468
|
allTargets: McpProcessor.getToolTargets({ global }),
|
|
41979
43469
|
createProcessor: ({ toolTarget, dryRun }) => new McpProcessor({
|
|
41980
|
-
outputRoot
|
|
43470
|
+
outputRoot: resolveToolOutputRoot({
|
|
43471
|
+
outputRoot,
|
|
43472
|
+
toolTarget,
|
|
43473
|
+
global
|
|
43474
|
+
}),
|
|
41981
43475
|
toolTarget,
|
|
41982
43476
|
global,
|
|
41983
43477
|
dryRun,
|
|
@@ -42026,7 +43520,11 @@ function buildSubagentsStrategy(ctx) {
|
|
|
42026
43520
|
includeSimulated: false
|
|
42027
43521
|
}),
|
|
42028
43522
|
createProcessor: ({ toolTarget, dryRun }) => new SubagentsProcessor({
|
|
42029
|
-
outputRoot
|
|
43523
|
+
outputRoot: resolveToolOutputRoot({
|
|
43524
|
+
outputRoot,
|
|
43525
|
+
toolTarget,
|
|
43526
|
+
global
|
|
43527
|
+
}),
|
|
42030
43528
|
toolTarget,
|
|
42031
43529
|
global,
|
|
42032
43530
|
dryRun,
|
|
@@ -42047,7 +43545,11 @@ function buildSkillsStrategy(ctx) {
|
|
|
42047
43545
|
itemLabel: "skill(s)",
|
|
42048
43546
|
allTargets: SkillsProcessor.getToolTargets({ global }),
|
|
42049
43547
|
createProcessor: ({ toolTarget, dryRun }) => new SkillsProcessor({
|
|
42050
|
-
outputRoot
|
|
43548
|
+
outputRoot: resolveToolOutputRoot({
|
|
43549
|
+
outputRoot,
|
|
43550
|
+
toolTarget,
|
|
43551
|
+
global
|
|
43552
|
+
}),
|
|
42051
43553
|
toolTarget,
|
|
42052
43554
|
global,
|
|
42053
43555
|
dryRun,
|
|
@@ -42072,7 +43574,11 @@ function buildHooksStrategy(ctx) {
|
|
|
42072
43574
|
importOnly: true
|
|
42073
43575
|
}),
|
|
42074
43576
|
createProcessor: ({ toolTarget, dryRun }) => new HooksProcessor({
|
|
42075
|
-
outputRoot
|
|
43577
|
+
outputRoot: resolveToolOutputRoot({
|
|
43578
|
+
outputRoot,
|
|
43579
|
+
toolTarget,
|
|
43580
|
+
global
|
|
43581
|
+
}),
|
|
42076
43582
|
toolTarget,
|
|
42077
43583
|
global,
|
|
42078
43584
|
dryRun,
|
|
@@ -42097,7 +43603,11 @@ function buildPermissionsStrategy(ctx) {
|
|
|
42097
43603
|
importOnly: true
|
|
42098
43604
|
}),
|
|
42099
43605
|
createProcessor: ({ toolTarget, dryRun }) => new PermissionsProcessor({
|
|
42100
|
-
outputRoot
|
|
43606
|
+
outputRoot: resolveToolOutputRoot({
|
|
43607
|
+
outputRoot,
|
|
43608
|
+
toolTarget,
|
|
43609
|
+
global
|
|
43610
|
+
}),
|
|
42101
43611
|
toolTarget,
|
|
42102
43612
|
global,
|
|
42103
43613
|
dryRun,
|
|
@@ -42598,6 +44108,10 @@ async function warnSkillSubagentNameCollisions(params) {
|
|
|
42598
44108
|
*/
|
|
42599
44109
|
async function generate(params) {
|
|
42600
44110
|
const { config, logger } = params;
|
|
44111
|
+
for (const toolTarget of config.getTargets()) for (const outputRoot of config.getOutputRoots(toolTarget)) await assertPluginRootSafe({
|
|
44112
|
+
toolTarget,
|
|
44113
|
+
outputRoot
|
|
44114
|
+
});
|
|
42601
44115
|
await warnSkillSubagentNameCollisions({
|
|
42602
44116
|
config,
|
|
42603
44117
|
logger
|
|
@@ -42717,7 +44231,11 @@ async function generateRulesCore(params) {
|
|
|
42717
44231
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42718
44232
|
if (!config.getFeatures(toolTarget).includes("rules")) continue;
|
|
42719
44233
|
const processor = new RulesProcessor({
|
|
42720
|
-
outputRoot
|
|
44234
|
+
outputRoot: resolveToolOutputRoot({
|
|
44235
|
+
outputRoot,
|
|
44236
|
+
toolTarget,
|
|
44237
|
+
global: config.getGlobal()
|
|
44238
|
+
}),
|
|
42721
44239
|
inputRoot: config.getInputRoot(),
|
|
42722
44240
|
toolTarget,
|
|
42723
44241
|
global: config.getGlobal(),
|
|
@@ -42752,18 +44270,14 @@ async function generateRulesCore(params) {
|
|
|
42752
44270
|
}
|
|
42753
44271
|
async function generateIgnoreCore(params) {
|
|
42754
44272
|
const { config, logger } = params;
|
|
42755
|
-
const
|
|
44273
|
+
const global = config.getGlobal();
|
|
44274
|
+
const supportedIgnoreTargets = IgnoreProcessor.getToolTargets({ global });
|
|
42756
44275
|
warnUnsupportedTargets({
|
|
42757
44276
|
config,
|
|
42758
44277
|
supportedTargets: supportedIgnoreTargets,
|
|
42759
44278
|
featureName: "ignore",
|
|
42760
44279
|
logger
|
|
42761
44280
|
});
|
|
42762
|
-
if (config.getGlobal()) return {
|
|
42763
|
-
count: 0,
|
|
42764
|
-
paths: [],
|
|
42765
|
-
hasDiff: false
|
|
42766
|
-
};
|
|
42767
44281
|
let totalCount = 0;
|
|
42768
44282
|
const allPaths = [];
|
|
42769
44283
|
let hasDiff = false;
|
|
@@ -42774,6 +44288,7 @@ async function generateIgnoreCore(params) {
|
|
|
42774
44288
|
outputRoot,
|
|
42775
44289
|
inputRoot: config.getInputRoot(),
|
|
42776
44290
|
toolTarget,
|
|
44291
|
+
global,
|
|
42777
44292
|
dryRun: config.isPreviewMode(),
|
|
42778
44293
|
logger,
|
|
42779
44294
|
featureOptions: config.getFeatureOptions(toolTarget, "ignore")
|
|
@@ -42813,7 +44328,11 @@ async function generateMcpCore(params) {
|
|
|
42813
44328
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42814
44329
|
if (!config.getFeatures(toolTarget).includes("mcp")) continue;
|
|
42815
44330
|
const processor = new McpProcessor({
|
|
42816
|
-
outputRoot
|
|
44331
|
+
outputRoot: resolveToolOutputRoot({
|
|
44332
|
+
outputRoot,
|
|
44333
|
+
toolTarget,
|
|
44334
|
+
global: config.getGlobal()
|
|
44335
|
+
}),
|
|
42817
44336
|
inputRoot: config.getInputRoot(),
|
|
42818
44337
|
toolTarget,
|
|
42819
44338
|
global: config.getGlobal(),
|
|
@@ -42898,7 +44417,11 @@ async function generateSubagentsCore(params) {
|
|
|
42898
44417
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42899
44418
|
if (!config.getFeatures(toolTarget).includes("subagents")) continue;
|
|
42900
44419
|
const processor = new SubagentsProcessor({
|
|
42901
|
-
outputRoot
|
|
44420
|
+
outputRoot: resolveToolOutputRoot({
|
|
44421
|
+
outputRoot,
|
|
44422
|
+
toolTarget,
|
|
44423
|
+
global: config.getGlobal()
|
|
44424
|
+
}),
|
|
42902
44425
|
inputRoot: config.getInputRoot(),
|
|
42903
44426
|
toolTarget,
|
|
42904
44427
|
global: config.getGlobal(),
|
|
@@ -42941,7 +44464,11 @@ async function generateSkillsCore(params) {
|
|
|
42941
44464
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42942
44465
|
if (!config.getFeatures(toolTarget).includes("skills")) continue;
|
|
42943
44466
|
const processor = new SkillsProcessor({
|
|
42944
|
-
outputRoot
|
|
44467
|
+
outputRoot: resolveToolOutputRoot({
|
|
44468
|
+
outputRoot,
|
|
44469
|
+
toolTarget,
|
|
44470
|
+
global: config.getGlobal()
|
|
44471
|
+
}),
|
|
42945
44472
|
inputRoot: config.getInputRoot(),
|
|
42946
44473
|
toolTarget,
|
|
42947
44474
|
global: config.getGlobal(),
|
|
@@ -42982,7 +44509,11 @@ async function generateHooksCore(params) {
|
|
|
42982
44509
|
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
42983
44510
|
if (!config.getFeatures(toolTarget).includes("hooks")) continue;
|
|
42984
44511
|
const processor = new HooksProcessor({
|
|
42985
|
-
outputRoot
|
|
44512
|
+
outputRoot: resolveToolOutputRoot({
|
|
44513
|
+
outputRoot,
|
|
44514
|
+
toolTarget,
|
|
44515
|
+
global: config.getGlobal()
|
|
44516
|
+
}),
|
|
42986
44517
|
inputRoot: config.getInputRoot(),
|
|
42987
44518
|
toolTarget,
|
|
42988
44519
|
global: config.getGlobal(),
|
|
@@ -43020,7 +44551,11 @@ async function generatePermissionsCore(params) {
|
|
|
43020
44551
|
if (!config.getFeatures(toolTarget).includes("permissions")) continue;
|
|
43021
44552
|
try {
|
|
43022
44553
|
const processor = new PermissionsProcessor({
|
|
43023
|
-
outputRoot
|
|
44554
|
+
outputRoot: resolveToolOutputRoot({
|
|
44555
|
+
outputRoot,
|
|
44556
|
+
toolTarget,
|
|
44557
|
+
global: config.getGlobal()
|
|
44558
|
+
}),
|
|
43024
44559
|
inputRoot: config.getInputRoot(),
|
|
43025
44560
|
toolTarget,
|
|
43026
44561
|
global: config.getGlobal(),
|
|
@@ -43086,21 +44621,41 @@ async function generateChecksCore(params) {
|
|
|
43086
44621
|
}
|
|
43087
44622
|
//#endregion
|
|
43088
44623
|
//#region src/lib/import.ts
|
|
43089
|
-
|
|
43090
|
-
|
|
43091
|
-
|
|
43092
|
-
|
|
43093
|
-
|
|
43094
|
-
|
|
43095
|
-
|
|
43096
|
-
|
|
43097
|
-
|
|
44624
|
+
async function applyRulesyncSourcePath({ files, paths, sourceClass, outputRoot }) {
|
|
44625
|
+
const first = files[0];
|
|
44626
|
+
if (!first) return files;
|
|
44627
|
+
const destinationOutputRoot = outputRoot ?? first.getOutputRoot();
|
|
44628
|
+
const destination = await resolveRulesyncSourceWritePath({
|
|
44629
|
+
outputRoot: destinationOutputRoot,
|
|
44630
|
+
paths
|
|
44631
|
+
});
|
|
44632
|
+
return files.map((file) => new sourceClass({
|
|
44633
|
+
outputRoot: destinationOutputRoot,
|
|
44634
|
+
relativeDirPath: destination.relativeDirPath,
|
|
44635
|
+
relativeFilePath: destination.relativeFilePath,
|
|
44636
|
+
fileContent: file.getFileContent(),
|
|
44637
|
+
validate: true
|
|
44638
|
+
}));
|
|
44639
|
+
}
|
|
44640
|
+
function getToolOutputRoot({ config, tool }) {
|
|
44641
|
+
return resolveToolOutputRoot({
|
|
44642
|
+
outputRoot: config.getOutputRoots(tool)[0] ?? ".",
|
|
44643
|
+
toolTarget: tool,
|
|
44644
|
+
global: config.getGlobal()
|
|
44645
|
+
});
|
|
43098
44646
|
}
|
|
43099
44647
|
/**
|
|
43100
44648
|
* Import configuration files from AI tools.
|
|
43101
44649
|
*/
|
|
43102
44650
|
async function importFromTool(params) {
|
|
43103
44651
|
const { config, tool, logger } = params;
|
|
44652
|
+
await assertPluginRootSafe({
|
|
44653
|
+
toolTarget: tool,
|
|
44654
|
+
outputRoot: getToolOutputRoot({
|
|
44655
|
+
config,
|
|
44656
|
+
tool
|
|
44657
|
+
})
|
|
44658
|
+
});
|
|
43104
44659
|
return {
|
|
43105
44660
|
rulesCount: await importRulesCore({
|
|
43106
44661
|
config,
|
|
@@ -43155,7 +44710,10 @@ async function importRulesCore(params) {
|
|
|
43155
44710
|
const global = config.getGlobal();
|
|
43156
44711
|
if (!RulesProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43157
44712
|
const rulesProcessor = new RulesProcessor({
|
|
43158
|
-
outputRoot:
|
|
44713
|
+
outputRoot: getToolOutputRoot({
|
|
44714
|
+
config,
|
|
44715
|
+
tool
|
|
44716
|
+
}),
|
|
43159
44717
|
toolTarget: tool,
|
|
43160
44718
|
global,
|
|
43161
44719
|
logger
|
|
@@ -43173,14 +44731,15 @@ async function importRulesCore(params) {
|
|
|
43173
44731
|
async function importIgnoreCore(params) {
|
|
43174
44732
|
const { config, tool, logger } = params;
|
|
43175
44733
|
if (!config.getFeatures(tool).includes("ignore")) return 0;
|
|
43176
|
-
|
|
43177
|
-
|
|
43178
|
-
return 0;
|
|
43179
|
-
}
|
|
43180
|
-
if (!IgnoreProcessor.getToolTargets().includes(tool)) return 0;
|
|
44734
|
+
const global = config.getGlobal();
|
|
44735
|
+
if (!IgnoreProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43181
44736
|
const ignoreProcessor = new IgnoreProcessor({
|
|
43182
|
-
outputRoot:
|
|
44737
|
+
outputRoot: getToolOutputRoot({
|
|
44738
|
+
config,
|
|
44739
|
+
tool
|
|
44740
|
+
}),
|
|
43183
44741
|
toolTarget: tool,
|
|
44742
|
+
global,
|
|
43184
44743
|
logger,
|
|
43185
44744
|
featureOptions: config.getFeatureOptions(tool, "ignore")
|
|
43186
44745
|
});
|
|
@@ -43201,7 +44760,10 @@ async function importMcpCore(params) {
|
|
|
43201
44760
|
const global = config.getGlobal();
|
|
43202
44761
|
if (!McpProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43203
44762
|
const mcpProcessor = new McpProcessor({
|
|
43204
|
-
outputRoot:
|
|
44763
|
+
outputRoot: getToolOutputRoot({
|
|
44764
|
+
config,
|
|
44765
|
+
tool
|
|
44766
|
+
}),
|
|
43205
44767
|
toolTarget: tool,
|
|
43206
44768
|
global,
|
|
43207
44769
|
logger
|
|
@@ -43211,14 +44773,13 @@ async function importMcpCore(params) {
|
|
|
43211
44773
|
logger.warn(`No MCP files found for ${tool}. Skipping import.`);
|
|
43212
44774
|
return 0;
|
|
43213
44775
|
}
|
|
43214
|
-
const rulesyncFiles = await
|
|
43215
|
-
|
|
43216
|
-
|
|
43217
|
-
|
|
43218
|
-
|
|
43219
|
-
jsoncRelativePath: RULESYNC_MCP_JSONC_RELATIVE_FILE_PATH,
|
|
43220
|
-
logger
|
|
44776
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44777
|
+
files: await mcpProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44778
|
+
paths: RulesyncMcp.getSettablePaths(),
|
|
44779
|
+
sourceClass: RulesyncMcp,
|
|
44780
|
+
outputRoot: isPackagingToolTarget(tool) ? process.cwd() : void 0
|
|
43221
44781
|
});
|
|
44782
|
+
const { count: writtenCount } = await mcpProcessor.writeAiFiles(rulesyncFiles);
|
|
43222
44783
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} MCP files`);
|
|
43223
44784
|
return writtenCount;
|
|
43224
44785
|
}
|
|
@@ -43231,7 +44792,10 @@ async function importCommandsCore(params) {
|
|
|
43231
44792
|
includeSimulated: false
|
|
43232
44793
|
}).includes(tool)) return 0;
|
|
43233
44794
|
const commandsProcessor = new CommandsProcessor({
|
|
43234
|
-
outputRoot:
|
|
44795
|
+
outputRoot: getToolOutputRoot({
|
|
44796
|
+
config,
|
|
44797
|
+
tool
|
|
44798
|
+
}),
|
|
43235
44799
|
toolTarget: tool,
|
|
43236
44800
|
global,
|
|
43237
44801
|
logger
|
|
@@ -43255,7 +44819,10 @@ async function importSubagentsCore(params) {
|
|
|
43255
44819
|
includeSimulated: false
|
|
43256
44820
|
}).includes(tool)) return 0;
|
|
43257
44821
|
const subagentsProcessor = new SubagentsProcessor({
|
|
43258
|
-
outputRoot:
|
|
44822
|
+
outputRoot: getToolOutputRoot({
|
|
44823
|
+
config,
|
|
44824
|
+
tool
|
|
44825
|
+
}),
|
|
43259
44826
|
toolTarget: tool,
|
|
43260
44827
|
global: config.getGlobal(),
|
|
43261
44828
|
logger
|
|
@@ -43276,7 +44843,10 @@ async function importSkillsCore(params) {
|
|
|
43276
44843
|
const global = config.getGlobal();
|
|
43277
44844
|
if (!SkillsProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
43278
44845
|
const skillsProcessor = new SkillsProcessor({
|
|
43279
|
-
outputRoot:
|
|
44846
|
+
outputRoot: getToolOutputRoot({
|
|
44847
|
+
config,
|
|
44848
|
+
tool
|
|
44849
|
+
}),
|
|
43280
44850
|
toolTarget: tool,
|
|
43281
44851
|
global,
|
|
43282
44852
|
logger
|
|
@@ -43286,8 +44856,21 @@ async function importSkillsCore(params) {
|
|
|
43286
44856
|
logger.warn(`No skill directories found for ${tool}. Skipping import.`);
|
|
43287
44857
|
return 0;
|
|
43288
44858
|
}
|
|
43289
|
-
const
|
|
43290
|
-
|
|
44859
|
+
const rebasedRulesyncDirs = (await skillsProcessor.convertToolDirsToRulesyncDirs(toolDirs)).map((dir) => {
|
|
44860
|
+
if (!isPackagingToolTarget(tool)) return dir;
|
|
44861
|
+
if (!(dir instanceof RulesyncSkill)) return dir;
|
|
44862
|
+
return new RulesyncSkill({
|
|
44863
|
+
outputRoot: process.cwd(),
|
|
44864
|
+
relativeDirPath: dir.getRelativeDirPath(),
|
|
44865
|
+
dirName: dir.getDirName(),
|
|
44866
|
+
frontmatter: dir.getFrontmatter(),
|
|
44867
|
+
body: dir.getBody(),
|
|
44868
|
+
otherFiles: dir.getOtherFiles(),
|
|
44869
|
+
validate: true,
|
|
44870
|
+
global: false
|
|
44871
|
+
});
|
|
44872
|
+
});
|
|
44873
|
+
const { count: writtenCount } = await skillsProcessor.writeAiDirs(rebasedRulesyncDirs);
|
|
43291
44874
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} skill directories`);
|
|
43292
44875
|
return writtenCount;
|
|
43293
44876
|
}
|
|
@@ -43306,7 +44889,10 @@ async function importHooksCore(params) {
|
|
|
43306
44889
|
return 0;
|
|
43307
44890
|
}
|
|
43308
44891
|
const hooksProcessor = new HooksProcessor({
|
|
43309
|
-
outputRoot:
|
|
44892
|
+
outputRoot: getToolOutputRoot({
|
|
44893
|
+
config,
|
|
44894
|
+
tool
|
|
44895
|
+
}),
|
|
43310
44896
|
toolTarget: tool,
|
|
43311
44897
|
global,
|
|
43312
44898
|
logger
|
|
@@ -43316,14 +44902,13 @@ async function importHooksCore(params) {
|
|
|
43316
44902
|
logger.warn(`No hooks files found for ${tool}. Skipping import.`);
|
|
43317
44903
|
return 0;
|
|
43318
44904
|
}
|
|
43319
|
-
const rulesyncFiles = await
|
|
43320
|
-
|
|
43321
|
-
|
|
43322
|
-
|
|
43323
|
-
|
|
43324
|
-
jsoncRelativePath: RULESYNC_HOOKS_JSONC_RELATIVE_FILE_PATH,
|
|
43325
|
-
logger
|
|
44905
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44906
|
+
files: await hooksProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44907
|
+
paths: RulesyncHooks.getSettablePaths(),
|
|
44908
|
+
sourceClass: RulesyncHooks,
|
|
44909
|
+
outputRoot: isPackagingToolTarget(tool) ? process.cwd() : void 0
|
|
43326
44910
|
});
|
|
44911
|
+
const { count: writtenCount } = await hooksProcessor.writeAiFiles(rulesyncFiles);
|
|
43327
44912
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} hooks file(s)`);
|
|
43328
44913
|
return writtenCount;
|
|
43329
44914
|
}
|
|
@@ -43341,7 +44926,10 @@ async function importPermissionsCore(params) {
|
|
|
43341
44926
|
return 0;
|
|
43342
44927
|
}
|
|
43343
44928
|
const permissionsProcessor = new PermissionsProcessor({
|
|
43344
|
-
outputRoot:
|
|
44929
|
+
outputRoot: getToolOutputRoot({
|
|
44930
|
+
config,
|
|
44931
|
+
tool
|
|
44932
|
+
}),
|
|
43345
44933
|
toolTarget: tool,
|
|
43346
44934
|
global: config.getGlobal(),
|
|
43347
44935
|
logger
|
|
@@ -43351,14 +44939,12 @@ async function importPermissionsCore(params) {
|
|
|
43351
44939
|
logger.warn(`No permissions files found for ${tool}. Skipping import.`);
|
|
43352
44940
|
return 0;
|
|
43353
44941
|
}
|
|
43354
|
-
const rulesyncFiles = await
|
|
43355
|
-
|
|
43356
|
-
|
|
43357
|
-
|
|
43358
|
-
jsonRelativePath: RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH,
|
|
43359
|
-
jsoncRelativePath: RULESYNC_PERMISSIONS_JSONC_RELATIVE_FILE_PATH,
|
|
43360
|
-
logger
|
|
44942
|
+
const rulesyncFiles = await applyRulesyncSourcePath({
|
|
44943
|
+
files: await permissionsProcessor.convertToolFilesToRulesyncFiles(toolFiles),
|
|
44944
|
+
paths: RulesyncPermissions.getSettablePaths(),
|
|
44945
|
+
sourceClass: RulesyncPermissions
|
|
43361
44946
|
});
|
|
44947
|
+
const { count: writtenCount } = await permissionsProcessor.writeAiFiles(rulesyncFiles);
|
|
43362
44948
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} permissions file(s)`);
|
|
43363
44949
|
return writtenCount;
|
|
43364
44950
|
}
|
|
@@ -43384,6 +44970,6 @@ async function importChecksCore(params) {
|
|
|
43384
44970
|
return writtenCount;
|
|
43385
44971
|
}
|
|
43386
44972
|
//#endregion
|
|
43387
|
-
export {
|
|
44973
|
+
export { assertDirectoryIfExists as $, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as $t, RulesyncMcp as A, RULESYNC_CHECKS_RELATIVE_DIR_PATH as At, stringifyFrontmatter as B, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as Bt, RulesyncSubagent as C, ALL_TOOL_TARGETS as Ct, RulesyncRule as D, MAX_FILE_SIZE as Dt, RulesyncSkillFrontmatterSchema as E, ToolTargetSchema as Et, parseJsonc as F, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as Ft, SourceEntrySchema as G, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as Gt, SKILL_FILE_NAME as H, RULESYNC_MCP_LEGACY_FILE_NAME as Ht, RulesyncCommand as I, RULESYNC_HOOKS_FILE_NAME as It, JsonLogger as J, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Jt, findControlCharacter as K, RULESYNC_PERMISSIONS_FILE_NAME as Kt, RulesyncCommandFrontmatterSchema as L, RULESYNC_HOOKS_LEGACY_FILE_NAME as Lt, RulesyncHooks as M, RULESYNC_CONFIG_RELATIVE_FILE_PATH as Mt, getRulesyncSourceCandidates as N, RULESYNC_CONFIG_SCHEMA_URL as Nt, RulesyncRuleFrontmatterSchema as O, RULESYNC_AIIGNORE_FILE_NAME as Ot, resolveRulesyncSourceWritePath as P, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as Pt, ErrorCodes as Q, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Qt, RulesyncCheck as R, RULESYNC_HOOKS_RELATIVE_FILE_PATH as Rt, getLocalSkillDirNames as S, writeFileContent as St, RulesyncSkill as T, PACKAGING_TOOL_TARGETS as Tt, ConfigResolver as U, RULESYNC_MCP_RELATIVE_FILE_PATH as Ut, loadYaml as V, RULESYNC_MCP_FILE_NAME as Vt, ConfigFileSchema as W, RULESYNC_MCP_SCHEMA_URL as Wt, warnOnConflictingFlags as X, RULESYNC_RELATIVE_DIR_PATH as Xt, fallbackLogger as Y, RULESYNC_PERMISSIONS_SCHEMA_URL as Yt, CLIError as Z, RULESYNC_RULES_RELATIVE_DIR_PATH as Zt, CLAUDECODE_LOCAL_RULE_FILE_NAME as _, removeFileStrict as _t, convertFromTool as a, ensureDir as at, CLAUDECODE_SKILLS_DIR_PATH as b, runWithDirectoryRollback as bt, SubagentsProcessor as c, getFileSize as ct, IgnoreProcessor as d, listDirectoryFiles as dt, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as en, assertTreeContainsNoSymlinks as et, HooksProcessor as f, readFileContent as ft, CLAUDECODE_DIR as g, removeFile as gt, CODEXCLI_DIR as h, removeDirectoryStrict as ht, getProcessorRegistryEntry as i, directoryExists as it, RulesyncIgnore as j, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as jt, RulesyncPermissions as k, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as kt, SkillsProcessor as l, getHomeDirectory as lt, CODEXCLI_BASH_RULES_FILE_NAME as m, removeDirectory as mt, checkRulesyncDirExists as n, ALL_FEATURES_WITH_WILDCARD as nn, checkPathTraversal as nt, isPackagingToolTarget as o, fileExists as ot, CommandsProcessor as p, readFileContentOrNull as pt, ConsoleLogger as q, RULESYNC_PERMISSIONS_LEGACY_FILE_NAME as qt, generate as r, formatError as rn, createTempDirectory as rt, RulesProcessor as s, findFilesByGlobs as st, importFromTool as t, ALL_FEATURES as tn, assertWritablePathInsideRoot as tt, McpProcessor as u, isSymlink as ut, CLAUDECODE_MEMORIES_DIR_NAME as v, removeTempDirectory as vt, RulesyncSubagentFrontmatterSchema as w, ALL_TOOL_TARGETS_WITH_WILDCARD as wt, ChecksProcessor as x, toPosixPath as xt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as y, resolvePath as yt, RulesyncCheckFrontmatterSchema as z, RULESYNC_IGNORE_RELATIVE_FILE_PATH as zt };
|
|
43388
44974
|
|
|
43389
|
-
//# sourceMappingURL=import-
|
|
44975
|
+
//# sourceMappingURL=import-BuxzyDyH.js.map
|