rulesync 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -39
- package/dist/cli/index.cjs +251 -12
- package/dist/cli/index.js +251 -12
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-hM4jDZn1.js → import-CMSHVMqU.js} +1455 -476
- package/dist/import-CMSHVMqU.js.map +1 -0
- package/dist/{import-C0N0Lo_F.cjs → import-nbmxtKYi.cjs} +1497 -488
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +7 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/import-hM4jDZn1.js.map +0 -1
|
@@ -37,6 +37,7 @@ let gray_matter = require("gray-matter");
|
|
|
37
37
|
gray_matter = __toESM(gray_matter, 1);
|
|
38
38
|
let js_yaml = require("js-yaml");
|
|
39
39
|
let es_toolkit_object = require("es-toolkit/object");
|
|
40
|
+
let node_crypto = require("node:crypto");
|
|
40
41
|
let _toon_format_toon = require("@toon-format/toon");
|
|
41
42
|
//#region src/types/features.ts
|
|
42
43
|
const ALL_FEATURES = [
|
|
@@ -47,7 +48,8 @@ const ALL_FEATURES = [
|
|
|
47
48
|
"commands",
|
|
48
49
|
"skills",
|
|
49
50
|
"hooks",
|
|
50
|
-
"permissions"
|
|
51
|
+
"permissions",
|
|
52
|
+
"checks"
|
|
51
53
|
];
|
|
52
54
|
const ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
|
|
53
55
|
const FeatureSchema = zod_mini.z.enum(ALL_FEATURES);
|
|
@@ -114,25 +116,26 @@ function formatError(error) {
|
|
|
114
116
|
}
|
|
115
117
|
//#endregion
|
|
116
118
|
//#region src/constants/rulesync-paths.ts
|
|
117
|
-
const { join: join$
|
|
119
|
+
const { join: join$256 } = node_path.posix;
|
|
118
120
|
const RULESYNC_CONFIG_RELATIVE_FILE_PATH = "rulesync.jsonc";
|
|
119
121
|
const RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH = "rulesync.local.jsonc";
|
|
120
122
|
const RULESYNC_RELATIVE_DIR_PATH = ".rulesync";
|
|
121
|
-
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$
|
|
122
|
-
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$
|
|
123
|
-
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const
|
|
128
|
-
const
|
|
129
|
-
const
|
|
123
|
+
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "rules");
|
|
124
|
+
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "commands");
|
|
125
|
+
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "subagents");
|
|
126
|
+
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "checks");
|
|
127
|
+
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
|
|
128
|
+
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "hooks.json");
|
|
129
|
+
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "permissions.json");
|
|
130
|
+
const RULESYNC_MCP_JSONC_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "mcp.jsonc");
|
|
131
|
+
const RULESYNC_HOOKS_JSONC_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "hooks.jsonc");
|
|
132
|
+
const RULESYNC_PERMISSIONS_JSONC_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "permissions.jsonc");
|
|
130
133
|
const RULESYNC_AIIGNORE_FILE_NAME = ".aiignore";
|
|
131
|
-
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$
|
|
134
|
+
const RULESYNC_AIIGNORE_RELATIVE_FILE_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, ".aiignore");
|
|
132
135
|
const RULESYNC_IGNORE_RELATIVE_FILE_PATH = ".rulesyncignore";
|
|
133
136
|
const RULESYNC_OVERVIEW_FILE_NAME = "overview.md";
|
|
134
|
-
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$
|
|
135
|
-
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$
|
|
137
|
+
const RULESYNC_SKILLS_RELATIVE_DIR_PATH = join$256(RULESYNC_RELATIVE_DIR_PATH, "skills");
|
|
138
|
+
const RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH = join$256(RULESYNC_SKILLS_RELATIVE_DIR_PATH, ".curated");
|
|
136
139
|
const RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH = "rulesync.lock";
|
|
137
140
|
const RULESYNC_MCP_FILE_NAME = "mcp.json";
|
|
138
141
|
const RULESYNC_HOOKS_FILE_NAME = "hooks.json";
|
|
@@ -386,6 +389,7 @@ const permissionsProcessorToolTargetTuple = [
|
|
|
386
389
|
"warp",
|
|
387
390
|
"zed"
|
|
388
391
|
];
|
|
392
|
+
const checksProcessorToolTargetTuple = ["amp"];
|
|
389
393
|
//#endregion
|
|
390
394
|
//#region src/types/tool-targets.ts
|
|
391
395
|
const ALL_TOOL_TARGETS = [...new Set([
|
|
@@ -396,7 +400,8 @@ const ALL_TOOL_TARGETS = [...new Set([
|
|
|
396
400
|
subagentsProcessorToolTargetTuple,
|
|
397
401
|
skillsProcessorToolTargetTuple,
|
|
398
402
|
hooksProcessorToolTargetTuple,
|
|
399
|
-
permissionsProcessorToolTargetTuple
|
|
403
|
+
permissionsProcessorToolTargetTuple,
|
|
404
|
+
checksProcessorToolTargetTuple
|
|
400
405
|
].flat())];
|
|
401
406
|
const ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
402
407
|
const ToolTargetSchema = zod_mini.z.enum(ALL_TOOL_TARGETS);
|
|
@@ -1470,7 +1475,7 @@ function isPlainObject$1(value) {
|
|
|
1470
1475
|
/**
|
|
1471
1476
|
* Type guard to check if a value is an array of strings.
|
|
1472
1477
|
*/
|
|
1473
|
-
function isStringArray(value) {
|
|
1478
|
+
function isStringArray$1(value) {
|
|
1474
1479
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1475
1480
|
}
|
|
1476
1481
|
//#endregion
|
|
@@ -1718,13 +1723,17 @@ var FeatureProcessor = class {
|
|
|
1718
1723
|
}
|
|
1719
1724
|
};
|
|
1720
1725
|
//#endregion
|
|
1721
|
-
//#region src/constants/
|
|
1722
|
-
const
|
|
1723
|
-
const
|
|
1724
|
-
const
|
|
1725
|
-
const
|
|
1726
|
-
const
|
|
1727
|
-
const
|
|
1726
|
+
//#region src/constants/amp-paths.ts
|
|
1727
|
+
const AMP_DIR = ".amp";
|
|
1728
|
+
const AMP_GLOBAL_DIR = (0, node_path.join)(".config", "amp");
|
|
1729
|
+
const AMP_AGENTS_DIR = ".agents";
|
|
1730
|
+
const AMP_SKILLS_PROJECT_DIR = (0, node_path.join)(AMP_AGENTS_DIR, "skills");
|
|
1731
|
+
const AMP_SKILLS_GLOBAL_DIR = (0, node_path.join)(".config", "agents", "skills");
|
|
1732
|
+
const AMP_CHECKS_PROJECT_DIR = (0, node_path.join)(AMP_AGENTS_DIR, "checks");
|
|
1733
|
+
const AMP_CHECKS_GLOBAL_DIR = (0, node_path.join)(AMP_GLOBAL_DIR, "checks");
|
|
1734
|
+
const AMP_RULE_FILE_NAME = "AGENTS.md";
|
|
1735
|
+
const AMP_SETTINGS_FILE_NAME = "settings.json";
|
|
1736
|
+
const AMP_SETTINGS_JSONC_FILE_NAME = "settings.jsonc";
|
|
1728
1737
|
//#endregion
|
|
1729
1738
|
//#region src/types/ai-file.ts
|
|
1730
1739
|
var AiFile = class {
|
|
@@ -1798,6 +1807,414 @@ var AiFile = class {
|
|
|
1798
1807
|
}
|
|
1799
1808
|
};
|
|
1800
1809
|
//#endregion
|
|
1810
|
+
//#region src/types/rulesync-file.ts
|
|
1811
|
+
var RulesyncFile = class extends AiFile {
|
|
1812
|
+
static async fromFile(_params) {
|
|
1813
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
//#endregion
|
|
1817
|
+
//#region src/features/checks/rulesync-check.ts
|
|
1818
|
+
const RulesyncCheckFrontmatterSchema = zod_mini.z.looseObject({
|
|
1819
|
+
targets: zod_mini.z._default(RulesyncTargetsSchema, ["*"]),
|
|
1820
|
+
description: zod_mini.z.optional(zod_mini.z.string()),
|
|
1821
|
+
severity: zod_mini.z.optional(zod_mini.z.enum([
|
|
1822
|
+
"low",
|
|
1823
|
+
"medium",
|
|
1824
|
+
"high",
|
|
1825
|
+
"critical"
|
|
1826
|
+
])),
|
|
1827
|
+
tools: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string()))
|
|
1828
|
+
});
|
|
1829
|
+
var RulesyncCheck = class RulesyncCheck extends RulesyncFile {
|
|
1830
|
+
frontmatter;
|
|
1831
|
+
body;
|
|
1832
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
1833
|
+
const parseResult = RulesyncCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1834
|
+
if (!parseResult.success && rest.validate !== false) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`);
|
|
1835
|
+
const parsedFrontmatter = parseResult.success ? {
|
|
1836
|
+
...frontmatter,
|
|
1837
|
+
...parseResult.data
|
|
1838
|
+
} : {
|
|
1839
|
+
...frontmatter,
|
|
1840
|
+
targets: frontmatter?.targets ?? ["*"]
|
|
1841
|
+
};
|
|
1842
|
+
super({
|
|
1843
|
+
...rest,
|
|
1844
|
+
fileContent: stringifyFrontmatter(body, parsedFrontmatter)
|
|
1845
|
+
});
|
|
1846
|
+
this.frontmatter = parsedFrontmatter;
|
|
1847
|
+
this.body = body;
|
|
1848
|
+
}
|
|
1849
|
+
static getSettablePaths() {
|
|
1850
|
+
return { relativeDirPath: RULESYNC_CHECKS_RELATIVE_DIR_PATH };
|
|
1851
|
+
}
|
|
1852
|
+
getFrontmatter() {
|
|
1853
|
+
return this.frontmatter;
|
|
1854
|
+
}
|
|
1855
|
+
getBody() {
|
|
1856
|
+
return this.body;
|
|
1857
|
+
}
|
|
1858
|
+
validate() {
|
|
1859
|
+
if (!this.frontmatter) return {
|
|
1860
|
+
success: true,
|
|
1861
|
+
error: null
|
|
1862
|
+
};
|
|
1863
|
+
const result = RulesyncCheckFrontmatterSchema.safeParse(this.frontmatter);
|
|
1864
|
+
if (result.success) return {
|
|
1865
|
+
success: true,
|
|
1866
|
+
error: null
|
|
1867
|
+
};
|
|
1868
|
+
else return {
|
|
1869
|
+
success: false,
|
|
1870
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath }) {
|
|
1874
|
+
const filePath = (0, node_path.join)(outputRoot, RULESYNC_CHECKS_RELATIVE_DIR_PATH, relativeFilePath);
|
|
1875
|
+
const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
1876
|
+
if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${filePath}. Rulesync files must begin with a YAML frontmatter block delimited by '---'.`);
|
|
1877
|
+
const result = RulesyncCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1878
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
|
|
1879
|
+
const filename = (0, node_path.basename)(relativeFilePath);
|
|
1880
|
+
return new RulesyncCheck({
|
|
1881
|
+
outputRoot,
|
|
1882
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
1883
|
+
relativeFilePath: filename,
|
|
1884
|
+
frontmatter: result.data,
|
|
1885
|
+
body: content.trim()
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
};
|
|
1889
|
+
//#endregion
|
|
1890
|
+
//#region src/types/tool-file.ts
|
|
1891
|
+
var ToolFile = class extends AiFile {};
|
|
1892
|
+
//#endregion
|
|
1893
|
+
//#region src/features/checks/tool-check.ts
|
|
1894
|
+
var ToolCheck = class extends ToolFile {
|
|
1895
|
+
static getSettablePaths(_options = {}) {
|
|
1896
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1897
|
+
}
|
|
1898
|
+
static async fromFile(_params) {
|
|
1899
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1900
|
+
}
|
|
1901
|
+
/**
|
|
1902
|
+
* Create a minimal instance for deletion purposes.
|
|
1903
|
+
* This method does not read or parse file content, making it safe to use
|
|
1904
|
+
* even when files have old/incompatible formats.
|
|
1905
|
+
*/
|
|
1906
|
+
static forDeletion(_params) {
|
|
1907
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1908
|
+
}
|
|
1909
|
+
static fromRulesyncCheck(_params) {
|
|
1910
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1911
|
+
}
|
|
1912
|
+
static isTargetedByRulesyncCheck(_rulesyncCheck) {
|
|
1913
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1914
|
+
}
|
|
1915
|
+
static isTargetedByRulesyncCheckDefault({ rulesyncCheck, toolTarget }) {
|
|
1916
|
+
const targets = rulesyncCheck.getFrontmatter().targets;
|
|
1917
|
+
if (!targets) return true;
|
|
1918
|
+
if (targets.includes("*")) return true;
|
|
1919
|
+
if (targets.includes(toolTarget)) return true;
|
|
1920
|
+
return false;
|
|
1921
|
+
}
|
|
1922
|
+
static filterToolSpecificSection(rawSection, excludeFields) {
|
|
1923
|
+
const filtered = {};
|
|
1924
|
+
for (const [key, value] of Object.entries(rawSection)) if (!excludeFields.includes(key)) filtered[key] = value;
|
|
1925
|
+
return filtered;
|
|
1926
|
+
}
|
|
1927
|
+
};
|
|
1928
|
+
//#endregion
|
|
1929
|
+
//#region src/features/checks/amp-check.ts
|
|
1930
|
+
const AmpCheckFrontmatterSchema = zod_mini.z.looseObject({
|
|
1931
|
+
name: zod_mini.z.string(),
|
|
1932
|
+
description: zod_mini.z.optional(zod_mini.z.string()),
|
|
1933
|
+
"severity-default": zod_mini.z.optional(zod_mini.z.enum([
|
|
1934
|
+
"low",
|
|
1935
|
+
"medium",
|
|
1936
|
+
"high",
|
|
1937
|
+
"critical"
|
|
1938
|
+
])),
|
|
1939
|
+
tools: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string()))
|
|
1940
|
+
});
|
|
1941
|
+
/**
|
|
1942
|
+
* Represents an Amp code review check.
|
|
1943
|
+
*
|
|
1944
|
+
* Amp natively reads code review checks as Markdown files with YAML frontmatter,
|
|
1945
|
+
* scoped to the project (`.agents/checks/`) and user-wide (`~/.config/amp/checks/`).
|
|
1946
|
+
* Each check runs as a per-check subagent during code review.
|
|
1947
|
+
* @see https://ampcode.com/manual
|
|
1948
|
+
*/
|
|
1949
|
+
var AmpCheck = class AmpCheck extends ToolCheck {
|
|
1950
|
+
frontmatter;
|
|
1951
|
+
body;
|
|
1952
|
+
constructor({ frontmatter, body, fileContent, ...rest }) {
|
|
1953
|
+
if (rest.validate !== false) {
|
|
1954
|
+
const result = AmpCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1955
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
1956
|
+
}
|
|
1957
|
+
super({
|
|
1958
|
+
...rest,
|
|
1959
|
+
fileContent: fileContent ?? stringifyFrontmatter(body, frontmatter)
|
|
1960
|
+
});
|
|
1961
|
+
this.frontmatter = frontmatter;
|
|
1962
|
+
this.body = body;
|
|
1963
|
+
}
|
|
1964
|
+
static getSettablePaths({ global = false } = {}) {
|
|
1965
|
+
return { relativeDirPath: global ? AMP_CHECKS_GLOBAL_DIR : AMP_CHECKS_PROJECT_DIR };
|
|
1966
|
+
}
|
|
1967
|
+
getFrontmatter() {
|
|
1968
|
+
return this.frontmatter;
|
|
1969
|
+
}
|
|
1970
|
+
getBody() {
|
|
1971
|
+
return this.body;
|
|
1972
|
+
}
|
|
1973
|
+
toRulesyncCheck() {
|
|
1974
|
+
const { name: _name, description, "severity-default": severityDefault, tools, ...restFields } = this.frontmatter;
|
|
1975
|
+
return new RulesyncCheck({
|
|
1976
|
+
outputRoot: ".",
|
|
1977
|
+
frontmatter: {
|
|
1978
|
+
targets: ["*"],
|
|
1979
|
+
...description !== void 0 && { description },
|
|
1980
|
+
...severityDefault !== void 0 && { severity: severityDefault },
|
|
1981
|
+
...tools !== void 0 && { tools },
|
|
1982
|
+
...restFields
|
|
1983
|
+
},
|
|
1984
|
+
body: this.body,
|
|
1985
|
+
relativeDirPath: RULESYNC_CHECKS_RELATIVE_DIR_PATH,
|
|
1986
|
+
relativeFilePath: this.getRelativeFilePath(),
|
|
1987
|
+
validate: true
|
|
1988
|
+
});
|
|
1989
|
+
}
|
|
1990
|
+
static fromRulesyncCheck({ outputRoot = process.cwd(), rulesyncCheck, validate = true, global = false }) {
|
|
1991
|
+
const rulesyncFrontmatter = rulesyncCheck.getFrontmatter();
|
|
1992
|
+
const relativeFilePath = rulesyncCheck.getRelativeFilePath();
|
|
1993
|
+
const name = (0, node_path.basename)(relativeFilePath, ".md");
|
|
1994
|
+
const { targets: _targets, description, severity, tools, ...restFields } = rulesyncFrontmatter;
|
|
1995
|
+
const toolTargetKeys = new Set(ALL_TOOL_TARGETS);
|
|
1996
|
+
const passthroughFields = Object.fromEntries(Object.entries(restFields).filter(([key]) => !toolTargetKeys.has(key) && key !== "name"));
|
|
1997
|
+
const ampSection = this.filterToolSpecificSection(rulesyncFrontmatter.amp ?? {}, ["name"]);
|
|
1998
|
+
const rawAmpFrontmatter = {
|
|
1999
|
+
name,
|
|
2000
|
+
...description !== void 0 && { description },
|
|
2001
|
+
...severity !== void 0 && { "severity-default": severity },
|
|
2002
|
+
...tools !== void 0 && { tools },
|
|
2003
|
+
...passthroughFields,
|
|
2004
|
+
...ampSection
|
|
2005
|
+
};
|
|
2006
|
+
const result = AmpCheckFrontmatterSchema.safeParse(rawAmpFrontmatter);
|
|
2007
|
+
if (!result.success) throw new Error(`Invalid amp check frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
|
|
2008
|
+
const ampFrontmatter = result.data;
|
|
2009
|
+
const body = rulesyncCheck.getBody();
|
|
2010
|
+
const fileContent = stringifyFrontmatter(body, ampFrontmatter);
|
|
2011
|
+
const paths = this.getSettablePaths({ global });
|
|
2012
|
+
return new AmpCheck({
|
|
2013
|
+
outputRoot,
|
|
2014
|
+
frontmatter: ampFrontmatter,
|
|
2015
|
+
body,
|
|
2016
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2017
|
+
relativeFilePath,
|
|
2018
|
+
fileContent,
|
|
2019
|
+
validate
|
|
2020
|
+
});
|
|
2021
|
+
}
|
|
2022
|
+
validate() {
|
|
2023
|
+
if (!this.frontmatter) return {
|
|
2024
|
+
success: true,
|
|
2025
|
+
error: null
|
|
2026
|
+
};
|
|
2027
|
+
const result = AmpCheckFrontmatterSchema.safeParse(this.frontmatter);
|
|
2028
|
+
if (result.success) return {
|
|
2029
|
+
success: true,
|
|
2030
|
+
error: null
|
|
2031
|
+
};
|
|
2032
|
+
else return {
|
|
2033
|
+
success: false,
|
|
2034
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
2035
|
+
};
|
|
2036
|
+
}
|
|
2037
|
+
static isTargetedByRulesyncCheck(rulesyncCheck) {
|
|
2038
|
+
return this.isTargetedByRulesyncCheckDefault({
|
|
2039
|
+
rulesyncCheck,
|
|
2040
|
+
toolTarget: "amp"
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
2044
|
+
const paths = this.getSettablePaths({ global });
|
|
2045
|
+
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
2046
|
+
const fileContent = await readFileContent(filePath);
|
|
2047
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
|
|
2048
|
+
const result = AmpCheckFrontmatterSchema.safeParse(frontmatter);
|
|
2049
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
2050
|
+
return new AmpCheck({
|
|
2051
|
+
outputRoot,
|
|
2052
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2053
|
+
relativeFilePath,
|
|
2054
|
+
frontmatter: result.data,
|
|
2055
|
+
body: content.trim(),
|
|
2056
|
+
fileContent,
|
|
2057
|
+
validate
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
2061
|
+
return new AmpCheck({
|
|
2062
|
+
outputRoot,
|
|
2063
|
+
relativeDirPath,
|
|
2064
|
+
relativeFilePath,
|
|
2065
|
+
frontmatter: { name: "" },
|
|
2066
|
+
body: "",
|
|
2067
|
+
fileContent: "",
|
|
2068
|
+
validate: false
|
|
2069
|
+
});
|
|
2070
|
+
}
|
|
2071
|
+
};
|
|
2072
|
+
//#endregion
|
|
2073
|
+
//#region src/features/checks/checks-processor.ts
|
|
2074
|
+
const ChecksProcessorToolTargetSchema = zod_mini.z.enum(checksProcessorToolTargetTuple);
|
|
2075
|
+
/**
|
|
2076
|
+
* Factory Map mapping tool targets to their check factories.
|
|
2077
|
+
* Using Map to preserve insertion order for consistent iteration.
|
|
2078
|
+
*/
|
|
2079
|
+
const toolCheckFactories = /* @__PURE__ */ new Map([["amp", {
|
|
2080
|
+
class: AmpCheck,
|
|
2081
|
+
meta: {
|
|
2082
|
+
supportsGlobal: true,
|
|
2083
|
+
filePattern: "*.md"
|
|
2084
|
+
}
|
|
2085
|
+
}]]);
|
|
2086
|
+
const defaultGetFactory$6 = (target) => {
|
|
2087
|
+
const factory = toolCheckFactories.get(target);
|
|
2088
|
+
if (!factory) throw new Error(`Unsupported tool target: ${target}`);
|
|
2089
|
+
return factory;
|
|
2090
|
+
};
|
|
2091
|
+
const allToolTargetKeys$5 = [...toolCheckFactories.keys()];
|
|
2092
|
+
const checksProcessorToolTargets = allToolTargetKeys$5;
|
|
2093
|
+
const checksProcessorToolTargetsGlobal = allToolTargetKeys$5.filter((target) => {
|
|
2094
|
+
return toolCheckFactories.get(target)?.meta.supportsGlobal ?? false;
|
|
2095
|
+
});
|
|
2096
|
+
var ChecksProcessor = class extends FeatureProcessor {
|
|
2097
|
+
toolTarget;
|
|
2098
|
+
global;
|
|
2099
|
+
getFactory;
|
|
2100
|
+
constructor({ outputRoot = process.cwd(), inputRoot = process.cwd(), toolTarget, global = false, getFactory = defaultGetFactory$6, dryRun = false, logger }) {
|
|
2101
|
+
super({
|
|
2102
|
+
outputRoot,
|
|
2103
|
+
inputRoot,
|
|
2104
|
+
dryRun,
|
|
2105
|
+
logger
|
|
2106
|
+
});
|
|
2107
|
+
const result = ChecksProcessorToolTargetSchema.safeParse(toolTarget);
|
|
2108
|
+
if (!result.success) throw new Error(`Invalid tool target for ChecksProcessor: ${toolTarget}. ${formatError(result.error)}`);
|
|
2109
|
+
this.toolTarget = result.data;
|
|
2110
|
+
this.global = global;
|
|
2111
|
+
this.getFactory = getFactory;
|
|
2112
|
+
}
|
|
2113
|
+
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
2114
|
+
const rulesyncChecks = rulesyncFiles.filter((file) => file instanceof RulesyncCheck);
|
|
2115
|
+
const factory = this.getFactory(this.toolTarget);
|
|
2116
|
+
return rulesyncChecks.filter((rulesyncCheck) => factory.class.isTargetedByRulesyncCheck(rulesyncCheck)).map((rulesyncCheck) => factory.class.fromRulesyncCheck({
|
|
2117
|
+
outputRoot: this.outputRoot,
|
|
2118
|
+
relativeDirPath: RulesyncCheck.getSettablePaths().relativeDirPath,
|
|
2119
|
+
rulesyncCheck,
|
|
2120
|
+
global: this.global
|
|
2121
|
+
}));
|
|
2122
|
+
}
|
|
2123
|
+
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
2124
|
+
return toolFiles.filter((file) => file instanceof ToolCheck).map((toolCheck) => toolCheck.toRulesyncCheck());
|
|
2125
|
+
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Implementation of abstract method from Processor
|
|
2128
|
+
* Load and parse rulesync check files from .rulesync/checks/ directory
|
|
2129
|
+
*/
|
|
2130
|
+
async loadRulesyncFiles() {
|
|
2131
|
+
const checksDir = (0, node_path.join)(this.inputRoot, RulesyncCheck.getSettablePaths().relativeDirPath);
|
|
2132
|
+
if (!await directoryExists(checksDir)) {
|
|
2133
|
+
this.logger.debug(`Rulesync checks directory not found: ${checksDir}`);
|
|
2134
|
+
return [];
|
|
2135
|
+
}
|
|
2136
|
+
const mdFiles = (await listDirectoryFiles(checksDir)).filter((file) => file.endsWith(".md"));
|
|
2137
|
+
if (mdFiles.length === 0) {
|
|
2138
|
+
this.logger.debug(`No markdown files found in rulesync checks directory: ${checksDir}`);
|
|
2139
|
+
return [];
|
|
2140
|
+
}
|
|
2141
|
+
this.logger.debug(`Found ${mdFiles.length} check files in ${checksDir}`);
|
|
2142
|
+
const rulesyncChecks = [];
|
|
2143
|
+
for (const mdFile of mdFiles) {
|
|
2144
|
+
const filepath = (0, node_path.join)(checksDir, mdFile);
|
|
2145
|
+
try {
|
|
2146
|
+
const rulesyncCheck = await RulesyncCheck.fromFile({
|
|
2147
|
+
outputRoot: this.inputRoot,
|
|
2148
|
+
relativeFilePath: mdFile,
|
|
2149
|
+
validate: true
|
|
2150
|
+
});
|
|
2151
|
+
rulesyncChecks.push(rulesyncCheck);
|
|
2152
|
+
this.logger.debug(`Successfully loaded check: ${mdFile}`);
|
|
2153
|
+
} catch (error) {
|
|
2154
|
+
this.logger.warn(`Failed to load check file ${filepath}: ${formatError(error)}`);
|
|
2155
|
+
continue;
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
this.logger.debug(`Successfully loaded ${rulesyncChecks.length} rulesync checks`);
|
|
2159
|
+
return rulesyncChecks;
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* Implementation of abstract method from Processor
|
|
2163
|
+
* Load tool-specific check files and parse them into ToolCheck instances
|
|
2164
|
+
*/
|
|
2165
|
+
async loadToolFiles({ forDeletion = false } = {}) {
|
|
2166
|
+
const factory = this.getFactory(this.toolTarget);
|
|
2167
|
+
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
2168
|
+
const baseDir = (0, node_path.join)(this.outputRoot, paths.relativeDirPath);
|
|
2169
|
+
const checkFilePaths = await findFilesByGlobs((0, node_path.join)(baseDir, factory.meta.filePattern));
|
|
2170
|
+
const toRelativeFilePath = (path) => (0, node_path.relative)(baseDir, path);
|
|
2171
|
+
if (forDeletion) return checkFilePaths.map((path) => factory.class.forDeletion({
|
|
2172
|
+
outputRoot: this.outputRoot,
|
|
2173
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2174
|
+
relativeFilePath: toRelativeFilePath(path),
|
|
2175
|
+
global: this.global
|
|
2176
|
+
})).filter((check) => check.isDeletable());
|
|
2177
|
+
const loaded = await Promise.all(checkFilePaths.map((path) => factory.class.fromFile({
|
|
2178
|
+
outputRoot: this.outputRoot,
|
|
2179
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2180
|
+
relativeFilePath: toRelativeFilePath(path),
|
|
2181
|
+
global: this.global
|
|
2182
|
+
})));
|
|
2183
|
+
this.logger.debug(`Successfully loaded ${loaded.length} ${this.toolTarget} checks from ${paths.relativeDirPath}`);
|
|
2184
|
+
return loaded;
|
|
2185
|
+
}
|
|
2186
|
+
/**
|
|
2187
|
+
* Implementation of abstract method from FeatureProcessor
|
|
2188
|
+
* Return the tool targets that this processor supports
|
|
2189
|
+
*/
|
|
2190
|
+
static getToolTargets({ global = false } = {}) {
|
|
2191
|
+
if (global) return [...checksProcessorToolTargetsGlobal];
|
|
2192
|
+
return [...checksProcessorToolTargets];
|
|
2193
|
+
}
|
|
2194
|
+
static getToolTargetsSimulated() {
|
|
2195
|
+
return [];
|
|
2196
|
+
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Get the factory for a specific tool target.
|
|
2199
|
+
* This is a static version of the internal getFactory for external use.
|
|
2200
|
+
* @param target - The tool target. Must be a valid ChecksProcessorToolTarget.
|
|
2201
|
+
* @returns The factory for the target, or undefined if not found.
|
|
2202
|
+
*/
|
|
2203
|
+
static getFactory(target) {
|
|
2204
|
+
const result = ChecksProcessorToolTargetSchema.safeParse(target);
|
|
2205
|
+
if (!result.success) return;
|
|
2206
|
+
return toolCheckFactories.get(result.data);
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
//#endregion
|
|
2210
|
+
//#region src/constants/agentsmd-paths.ts
|
|
2211
|
+
const AGENTSMD_DIR = ".agents";
|
|
2212
|
+
const AGENTSMD_MEMORIES_DIR_PATH = (0, node_path.join)(AGENTSMD_DIR, "memories");
|
|
2213
|
+
const AGENTSMD_COMMANDS_DIR_PATH = (0, node_path.join)(AGENTSMD_DIR, "commands");
|
|
2214
|
+
const AGENTSMD_SKILLS_DIR_PATH = (0, node_path.join)(AGENTSMD_DIR, "skills");
|
|
2215
|
+
const AGENTSMD_SUBAGENTS_DIR_PATH = (0, node_path.join)(AGENTSMD_DIR, "subagents");
|
|
2216
|
+
const AGENTSMD_RULE_FILE_NAME = "AGENTS.md";
|
|
2217
|
+
//#endregion
|
|
1801
2218
|
//#region src/features/commands/tool-command.ts
|
|
1802
2219
|
/**
|
|
1803
2220
|
* Abstract base class for AI development tool-specific command formats.
|
|
@@ -2045,13 +2462,6 @@ const AntigravityCommandFrontmatterSchema = zod_mini.z.looseObject({
|
|
|
2045
2462
|
...AntigravityWorkflowFrontmatterSchema.shape
|
|
2046
2463
|
});
|
|
2047
2464
|
//#endregion
|
|
2048
|
-
//#region src/types/rulesync-file.ts
|
|
2049
|
-
var RulesyncFile = class extends AiFile {
|
|
2050
|
-
static async fromFile(_params) {
|
|
2051
|
-
throw new Error("Please implement this method in the subclass.");
|
|
2052
|
-
}
|
|
2053
|
-
};
|
|
2054
|
-
//#endregion
|
|
2055
2465
|
//#region src/features/commands/rulesync-command.ts
|
|
2056
2466
|
const RulesyncCommandFrontmatterSchema = zod_mini.z.looseObject({
|
|
2057
2467
|
targets: zod_mini.z._default(RulesyncTargetsSchema, ["*"]),
|
|
@@ -3112,135 +3522,118 @@ var CursorCommand = class CursorCommand extends ToolCommand {
|
|
|
3112
3522
|
//#endregion
|
|
3113
3523
|
//#region src/constants/devin-paths.ts
|
|
3114
3524
|
const DEVIN_DIR = ".devin";
|
|
3115
|
-
const CODEIUM_WINDSURF_DIR = (0, node_path.join)(".codeium", "windsurf");
|
|
3116
|
-
const DEVIN_WORKFLOWS_DIR_PATH = (0, node_path.join)(DEVIN_DIR, "workflows");
|
|
3117
3525
|
const DEVIN_SKILLS_DIR_PATH = (0, node_path.join)(DEVIN_DIR, "skills");
|
|
3118
3526
|
const DEVIN_AGENTS_DIR_PATH = (0, node_path.join)(DEVIN_DIR, "agents");
|
|
3119
3527
|
const DEVIN_GLOBAL_CONFIG_DIR_PATH = (0, node_path.join)(".config", "devin");
|
|
3120
3528
|
const DEVIN_GLOBAL_AGENTS_DIR_PATH = (0, node_path.join)(DEVIN_GLOBAL_CONFIG_DIR_PATH, "agents");
|
|
3121
3529
|
const DEVIN_GLOBAL_SKILLS_DIR_PATH = (0, node_path.join)(DEVIN_GLOBAL_CONFIG_DIR_PATH, "skills");
|
|
3122
|
-
const CODEIUM_WINDSURF_GLOBAL_WORKFLOWS_DIR_PATH = (0, node_path.join)(CODEIUM_WINDSURF_DIR, "global_workflows");
|
|
3123
3530
|
const DEVIN_CONFIG_FILE_NAME = "config.json";
|
|
3124
3531
|
const DEVIN_HOOKS_V1_FILE_NAME = "hooks.v1.json";
|
|
3125
3532
|
const DEVIN_GLOBAL_AGENTS_FILE_NAME = "AGENTS.md";
|
|
3126
3533
|
const DEVIN_IGNORE_FILE_NAME = ".devinignore";
|
|
3127
3534
|
const DEVIN_LEGACY_IGNORE_FILE_NAME = ".codeiumignore";
|
|
3128
3535
|
//#endregion
|
|
3536
|
+
//#region src/constants/general.ts
|
|
3537
|
+
const SKILL_FILE_NAME$1 = "SKILL.md";
|
|
3538
|
+
//#endregion
|
|
3539
|
+
//#region src/features/commands/command-skill-ownership.ts
|
|
3540
|
+
/**
|
|
3541
|
+
* Slug used for the per-command `<slug>/SKILL.md` directory when a tool's
|
|
3542
|
+
* commands are emitted onto its skills surface (Devin, Hermes Agent).
|
|
3543
|
+
*/
|
|
3544
|
+
function commandSlug(relativeFilePath) {
|
|
3545
|
+
return (0, node_path.basename)(relativeFilePath, ".md").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* Whether a rulesync command exists whose slug matches `dirName`.
|
|
3549
|
+
*
|
|
3550
|
+
* Used by the skills-surface `isDirOwned` hooks of tools whose commands are
|
|
3551
|
+
* emitted as `<slug>/SKILL.md` into the skills tree: a directory matching a
|
|
3552
|
+
* current command slug is owned by the commands feature, so the skills
|
|
3553
|
+
* feature must neither import it as a skill nor delete it as an orphan
|
|
3554
|
+
* skill. Once the command is removed from `.rulesync/commands/`, the
|
|
3555
|
+
* directory stops matching and the skills feature cleans it up as a regular
|
|
3556
|
+
* orphan.
|
|
3557
|
+
*/
|
|
3558
|
+
async function rulesyncCommandSlugExists({ inputRoot, dirName }) {
|
|
3559
|
+
return (await findFilesByGlobs((0, node_path.join)(inputRoot, RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "**", "*.md"))).some((filePath) => commandSlug((0, node_path.basename)(filePath)) === dirName);
|
|
3560
|
+
}
|
|
3561
|
+
//#endregion
|
|
3129
3562
|
//#region src/features/commands/devin-command.ts
|
|
3130
|
-
|
|
3563
|
+
function commandSkillContent$1(rulesyncCommand) {
|
|
3564
|
+
const slug = commandSlug(rulesyncCommand.getRelativeFilePath());
|
|
3565
|
+
const description = rulesyncCommand.getFrontmatter().description ?? `${slug} command`;
|
|
3566
|
+
return stringifyFrontmatter(rulesyncCommand.getBody().trim(), {
|
|
3567
|
+
name: slug,
|
|
3568
|
+
description
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
3131
3571
|
/**
|
|
3132
|
-
* Represents a Devin
|
|
3133
|
-
*
|
|
3134
|
-
*
|
|
3135
|
-
*
|
|
3136
|
-
*
|
|
3572
|
+
* Represents a Devin slash command, emitted as a Devin Skill.
|
|
3573
|
+
*
|
|
3574
|
+
* Devin's extensibility docs no longer document a standalone
|
|
3575
|
+
* workflows/commands component — reusable prompts invoked as slash commands
|
|
3576
|
+
* are Skills (`/name`). Commands are therefore emitted onto the native skills
|
|
3577
|
+
* surface, one `SKILL.md` per command: `.devin/skills/<slug>/SKILL.md`
|
|
3578
|
+
* (project) and `~/.config/devin/skills/<slug>/SKILL.md` (global). The legacy
|
|
3579
|
+
* Windsurf/Cascade-era `.devin/workflows/` and
|
|
3580
|
+
* `~/.codeium/windsurf/global_workflows/` locations are no longer emitted.
|
|
3581
|
+
*
|
|
3582
|
+
* Import and deletion are intentionally no-ops for this target: the skills
|
|
3583
|
+
* feature owns the `.devin/skills/` tree, so importing it as commands would
|
|
3584
|
+
* double-import every skill (mirrors the Hermes Agent commands target).
|
|
3585
|
+
*
|
|
3586
|
+
* @see https://docs.devin.ai/cli/extensibility
|
|
3587
|
+
* @see https://docs.devin.ai/cli/extensibility/skills/overview
|
|
3137
3588
|
*/
|
|
3138
3589
|
var DevinCommand = class DevinCommand extends ToolCommand {
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
const result = DevinCommandFrontmatterSchema.safeParse(frontmatter);
|
|
3144
|
-
if (!result.success) throw new Error(`Invalid frontmatter in ${(0, node_path.join)(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
3145
|
-
}
|
|
3146
|
-
super({
|
|
3147
|
-
...rest,
|
|
3148
|
-
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
3590
|
+
static isTargetedByRulesyncCommand(rulesyncCommand) {
|
|
3591
|
+
return this.isTargetedByRulesyncCommandDefault({
|
|
3592
|
+
rulesyncCommand,
|
|
3593
|
+
toolTarget: "devin"
|
|
3149
3594
|
});
|
|
3150
|
-
this.frontmatter = frontmatter;
|
|
3151
|
-
this.body = body;
|
|
3152
3595
|
}
|
|
3153
3596
|
static getSettablePaths({ global = false } = {}) {
|
|
3154
|
-
|
|
3155
|
-
return { relativeDirPath: DEVIN_WORKFLOWS_DIR_PATH };
|
|
3156
|
-
}
|
|
3157
|
-
getBody() {
|
|
3158
|
-
return this.body;
|
|
3159
|
-
}
|
|
3160
|
-
getFrontmatter() {
|
|
3161
|
-
return this.frontmatter;
|
|
3162
|
-
}
|
|
3163
|
-
toRulesyncCommand() {
|
|
3164
|
-
const { description, ...restFields } = this.frontmatter;
|
|
3165
|
-
const rulesyncFrontmatter = {
|
|
3166
|
-
targets: ["*"],
|
|
3167
|
-
description,
|
|
3168
|
-
...Object.keys(restFields).length > 0 && { devin: restFields }
|
|
3169
|
-
};
|
|
3170
|
-
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
3171
|
-
return new RulesyncCommand({
|
|
3172
|
-
outputRoot: process.cwd(),
|
|
3173
|
-
frontmatter: rulesyncFrontmatter,
|
|
3174
|
-
body: this.body,
|
|
3175
|
-
relativeDirPath: RulesyncCommand.getSettablePaths().relativeDirPath,
|
|
3176
|
-
relativeFilePath: this.relativeFilePath,
|
|
3177
|
-
fileContent,
|
|
3178
|
-
validate: true
|
|
3179
|
-
});
|
|
3597
|
+
return { relativeDirPath: global ? DEVIN_GLOBAL_SKILLS_DIR_PATH : DEVIN_SKILLS_DIR_PATH };
|
|
3180
3598
|
}
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
const body = rulesyncCommand.getBody();
|
|
3189
|
-
const paths = this.getSettablePaths({ global });
|
|
3190
|
-
return new DevinCommand({
|
|
3191
|
-
outputRoot,
|
|
3192
|
-
frontmatter: devinFrontmatter,
|
|
3193
|
-
body,
|
|
3194
|
-
relativeDirPath: paths.relativeDirPath,
|
|
3195
|
-
relativeFilePath: rulesyncCommand.getRelativeFilePath(),
|
|
3196
|
-
validate
|
|
3599
|
+
constructor({ slug, ...params }) {
|
|
3600
|
+
super({
|
|
3601
|
+
...params,
|
|
3602
|
+
...slug !== void 0 && {
|
|
3603
|
+
relativeDirPath: (0, node_path.join)(params.relativeDirPath, slug),
|
|
3604
|
+
relativeFilePath: "SKILL.md"
|
|
3605
|
+
}
|
|
3197
3606
|
});
|
|
3198
3607
|
}
|
|
3199
3608
|
validate() {
|
|
3200
|
-
|
|
3201
|
-
success: true,
|
|
3202
|
-
error: null
|
|
3203
|
-
};
|
|
3204
|
-
const result = DevinCommandFrontmatterSchema.safeParse(this.frontmatter);
|
|
3205
|
-
if (result.success) return {
|
|
3609
|
+
return {
|
|
3206
3610
|
success: true,
|
|
3207
3611
|
error: null
|
|
3208
3612
|
};
|
|
3209
|
-
else return {
|
|
3210
|
-
success: false,
|
|
3211
|
-
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${(0, node_path.join)(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
3212
|
-
};
|
|
3213
3613
|
}
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3614
|
+
toRulesyncCommand() {
|
|
3615
|
+
const slug = (0, node_path.basename)((0, node_path.dirname)(this.getRelativePathFromCwd()));
|
|
3616
|
+
const { frontmatter, body } = parseFrontmatter(this.getFileContent(), this.getFilePath());
|
|
3617
|
+
const description = typeof frontmatter.description === "string" ? frontmatter.description : void 0;
|
|
3618
|
+
return new RulesyncCommand({
|
|
3619
|
+
relativeDirPath: RULESYNC_COMMANDS_RELATIVE_DIR_PATH,
|
|
3620
|
+
relativeFilePath: `${slug}.md`,
|
|
3621
|
+
frontmatter: { description },
|
|
3622
|
+
body: body.trimStart()
|
|
3218
3623
|
});
|
|
3219
3624
|
}
|
|
3220
|
-
static
|
|
3221
|
-
const paths =
|
|
3222
|
-
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
3223
|
-
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
3224
|
-
const result = DevinCommandFrontmatterSchema.safeParse(frontmatter);
|
|
3225
|
-
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
3625
|
+
static fromRulesyncCommand({ outputRoot, rulesyncCommand, global = false }) {
|
|
3626
|
+
const paths = DevinCommand.getSettablePaths({ global });
|
|
3226
3627
|
return new DevinCommand({
|
|
3227
3628
|
outputRoot,
|
|
3228
3629
|
relativeDirPath: paths.relativeDirPath,
|
|
3229
|
-
relativeFilePath,
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
validate
|
|
3630
|
+
relativeFilePath: SKILL_FILE_NAME$1,
|
|
3631
|
+
slug: commandSlug(rulesyncCommand.getRelativeFilePath()),
|
|
3632
|
+
fileContent: commandSkillContent$1(rulesyncCommand)
|
|
3233
3633
|
});
|
|
3234
3634
|
}
|
|
3235
|
-
|
|
3236
|
-
return
|
|
3237
|
-
outputRoot,
|
|
3238
|
-
relativeDirPath,
|
|
3239
|
-
relativeFilePath,
|
|
3240
|
-
frontmatter: { description: "" },
|
|
3241
|
-
body: "",
|
|
3242
|
-
validate: false
|
|
3243
|
-
});
|
|
3635
|
+
getFileContent() {
|
|
3636
|
+
return this.fileContent;
|
|
3244
3637
|
}
|
|
3245
3638
|
};
|
|
3246
3639
|
//#endregion
|
|
@@ -3569,10 +3962,7 @@ const HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_MANIFEST_PATH = (0, node_path.join)(
|
|
|
3569
3962
|
const HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_INIT_PATH = (0, node_path.join)(HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_DIR_PATH, "__init__.py");
|
|
3570
3963
|
//#endregion
|
|
3571
3964
|
//#region src/features/commands/hermesagent-command.ts
|
|
3572
|
-
const SKILL_FILE_NAME
|
|
3573
|
-
function commandSlug(relativeFilePath) {
|
|
3574
|
-
return (0, node_path.basename)(relativeFilePath, ".md").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
3575
|
-
}
|
|
3965
|
+
const SKILL_FILE_NAME = "SKILL.md";
|
|
3576
3966
|
function commandSkillContent(rulesyncCommand) {
|
|
3577
3967
|
const slug = commandSlug(rulesyncCommand.getRelativeFilePath());
|
|
3578
3968
|
const description = rulesyncCommand.getFrontmatter().description ?? `${slug} command`;
|
|
@@ -3589,7 +3979,7 @@ var HermesagentCommand = class HermesagentCommand extends ToolCommand {
|
|
|
3589
3979
|
static getSettablePaths({ slug = "command" } = {}) {
|
|
3590
3980
|
return {
|
|
3591
3981
|
relativeDirPath: (0, node_path.join)(HERMESAGENT_SKILLS_DIR_PATH, slug),
|
|
3592
|
-
relativeFilePath: SKILL_FILE_NAME
|
|
3982
|
+
relativeFilePath: SKILL_FILE_NAME
|
|
3593
3983
|
};
|
|
3594
3984
|
}
|
|
3595
3985
|
constructor({ slug, ...params }) {
|
|
@@ -3620,7 +4010,7 @@ var HermesagentCommand = class HermesagentCommand extends ToolCommand {
|
|
|
3620
4010
|
return new HermesagentCommand({
|
|
3621
4011
|
outputRoot,
|
|
3622
4012
|
relativeDirPath: "",
|
|
3623
|
-
relativeFilePath: SKILL_FILE_NAME
|
|
4013
|
+
relativeFilePath: SKILL_FILE_NAME,
|
|
3624
4014
|
slug: commandSlug(rulesyncCommand.getRelativeFilePath()),
|
|
3625
4015
|
fileContent: commandSkillContent(rulesyncCommand)
|
|
3626
4016
|
});
|
|
@@ -4855,6 +5245,7 @@ const PI_AGENT_SKILLS_DIR_PATH = (0, node_path.join)(PI_AGENT_DIR, "skills");
|
|
|
4855
5245
|
const PI_PROMPTS_DIR_PATH = (0, node_path.join)(".pi", "prompts");
|
|
4856
5246
|
const PI_SKILLS_DIR_PATH = (0, node_path.join)(".pi", "skills");
|
|
4857
5247
|
const PI_RULE_FILE_NAME = "AGENTS.md";
|
|
5248
|
+
const PI_APPEND_SYSTEM_FILE_NAME = "APPEND_SYSTEM.md";
|
|
4858
5249
|
//#endregion
|
|
4859
5250
|
//#region src/features/commands/pi-command.ts
|
|
4860
5251
|
/**
|
|
@@ -5389,9 +5780,6 @@ const ROVODEV_AGENTS_SKILLS_DIR_PATH = (0, node_path.join)(".agents", "skills");
|
|
|
5389
5780
|
const ROVODEV_PROMPTS_FILE_NAME = "prompts.yml";
|
|
5390
5781
|
const ROVODEV_PROMPTS_DIR_PATH = (0, node_path.join)(ROVODEV_DIR, "prompts");
|
|
5391
5782
|
//#endregion
|
|
5392
|
-
//#region src/types/tool-file.ts
|
|
5393
|
-
var ToolFile = class extends AiFile {};
|
|
5394
|
-
//#endregion
|
|
5395
5783
|
//#region src/features/commands/rovodev-command.ts
|
|
5396
5784
|
/**
|
|
5397
5785
|
* Rovo Dev CLI "saved prompts": a file-based custom-command surface made of a
|
|
@@ -5880,7 +6268,8 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
5880
6268
|
supportsProject: false,
|
|
5881
6269
|
supportsGlobal: true,
|
|
5882
6270
|
isSimulated: false,
|
|
5883
|
-
supportsSubdirectory: true
|
|
6271
|
+
supportsSubdirectory: true,
|
|
6272
|
+
skipToolFileScan: true
|
|
5884
6273
|
}
|
|
5885
6274
|
}],
|
|
5886
6275
|
["junie", {
|
|
@@ -6010,7 +6399,8 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
6010
6399
|
supportsProject: true,
|
|
6011
6400
|
supportsGlobal: true,
|
|
6012
6401
|
isSimulated: false,
|
|
6013
|
-
supportsSubdirectory: false
|
|
6402
|
+
supportsSubdirectory: false,
|
|
6403
|
+
skipToolFileScan: true
|
|
6014
6404
|
}
|
|
6015
6405
|
}]
|
|
6016
6406
|
]);
|
|
@@ -6113,6 +6503,7 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
6113
6503
|
*/
|
|
6114
6504
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
6115
6505
|
const factory = this.getFactory(this.toolTarget);
|
|
6506
|
+
if (factory.meta.skipToolFileScan) return [];
|
|
6116
6507
|
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
6117
6508
|
const outputRootFull = (0, node_path.join)(this.outputRoot, paths.relativeDirPath);
|
|
6118
6509
|
const commandFilePaths = await findFilesByGlobs(factory.meta.supportsSubdirectory ? (0, node_path.join)(outputRootFull, "**", `*.${factory.meta.extension}`) : (0, node_path.join)(outputRootFull, `*.${factory.meta.extension}`));
|
|
@@ -6222,7 +6613,10 @@ const HookDefinitionSchema = zod_mini.z.looseObject({
|
|
|
6222
6613
|
type: zod_mini.z.optional(zod_mini.z.enum([
|
|
6223
6614
|
"command",
|
|
6224
6615
|
"prompt",
|
|
6225
|
-
"http"
|
|
6616
|
+
"http",
|
|
6617
|
+
"agent",
|
|
6618
|
+
"mcp_tool",
|
|
6619
|
+
"function"
|
|
6226
6620
|
])),
|
|
6227
6621
|
url: zod_mini.z.optional(safeString),
|
|
6228
6622
|
timeout: zod_mini.z.optional(zod_mini.z.number()),
|
|
@@ -6235,12 +6629,71 @@ const HookDefinitionSchema = zod_mini.z.looseObject({
|
|
|
6235
6629
|
sequential: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
6236
6630
|
async: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
6237
6631
|
env: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), safeString)),
|
|
6238
|
-
shell: zod_mini.z.optional(
|
|
6632
|
+
shell: zod_mini.z.optional(zod_mini.z.enum(["bash", "powershell"])),
|
|
6239
6633
|
statusMessage: zod_mini.z.optional(safeString),
|
|
6240
6634
|
headers: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), safeString)),
|
|
6241
6635
|
allowedEnvVars: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string())),
|
|
6242
|
-
once: zod_mini.z.optional(zod_mini.z.boolean())
|
|
6636
|
+
once: zod_mini.z.optional(zod_mini.z.boolean()),
|
|
6637
|
+
server: zod_mini.z.optional(safeString),
|
|
6638
|
+
tool: zod_mini.z.optional(safeString),
|
|
6639
|
+
input: zod_mini.z.optional(zod_mini.z.looseObject({})),
|
|
6640
|
+
model: zod_mini.z.optional(safeString)
|
|
6243
6641
|
});
|
|
6642
|
+
/**
|
|
6643
|
+
* All canonical hook event names.
|
|
6644
|
+
* Each tool supports a subset of these events.
|
|
6645
|
+
*/
|
|
6646
|
+
const HOOK_EVENTS = [
|
|
6647
|
+
"sessionStart",
|
|
6648
|
+
"sessionEnd",
|
|
6649
|
+
"preToolUse",
|
|
6650
|
+
"postToolUse",
|
|
6651
|
+
"preModelInvocation",
|
|
6652
|
+
"postModelInvocation",
|
|
6653
|
+
"beforeSubmitPrompt",
|
|
6654
|
+
"stop",
|
|
6655
|
+
"subagentStop",
|
|
6656
|
+
"preCompact",
|
|
6657
|
+
"postCompact",
|
|
6658
|
+
"contextOffload",
|
|
6659
|
+
"postToolUseFailure",
|
|
6660
|
+
"subagentStart",
|
|
6661
|
+
"beforeShellExecution",
|
|
6662
|
+
"afterShellExecution",
|
|
6663
|
+
"beforeMCPExecution",
|
|
6664
|
+
"afterMCPExecution",
|
|
6665
|
+
"beforeReadFile",
|
|
6666
|
+
"afterFileEdit",
|
|
6667
|
+
"beforeAgentResponse",
|
|
6668
|
+
"afterAgentResponse",
|
|
6669
|
+
"afterAgentThought",
|
|
6670
|
+
"beforeTabFileRead",
|
|
6671
|
+
"afterTabFileEdit",
|
|
6672
|
+
"permissionRequest",
|
|
6673
|
+
"notification",
|
|
6674
|
+
"setup",
|
|
6675
|
+
"afterError",
|
|
6676
|
+
"beforeToolSelection",
|
|
6677
|
+
"worktreeCreate",
|
|
6678
|
+
"worktreeRemove",
|
|
6679
|
+
"workspaceOpen",
|
|
6680
|
+
"messageDisplay",
|
|
6681
|
+
"todoCreated",
|
|
6682
|
+
"todoCompleted",
|
|
6683
|
+
"stopFailure",
|
|
6684
|
+
"instructionsLoaded",
|
|
6685
|
+
"userPromptExpansion",
|
|
6686
|
+
"postToolBatch",
|
|
6687
|
+
"permissionDenied",
|
|
6688
|
+
"taskCreated",
|
|
6689
|
+
"taskCompleted",
|
|
6690
|
+
"teammateIdle",
|
|
6691
|
+
"configChange",
|
|
6692
|
+
"cwdChanged",
|
|
6693
|
+
"fileChanged",
|
|
6694
|
+
"elicitation",
|
|
6695
|
+
"elicitationResult"
|
|
6696
|
+
];
|
|
6244
6697
|
/** Hook events supported by Cursor. */
|
|
6245
6698
|
const CURSOR_HOOK_EVENTS = [
|
|
6246
6699
|
"sessionStart",
|
|
@@ -6715,12 +7168,28 @@ const CANONICAL_TO_HERMESAGENT_EVENT_NAMES = {
|
|
|
6715
7168
|
*/
|
|
6716
7169
|
const HERMESAGENT_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_HERMESAGENT_EVENT_NAMES).map(([k, v]) => [v, k]));
|
|
6717
7170
|
const hooksRecordSchema = zod_mini.z.record(zod_mini.z.string(), zod_mini.z.array(HookDefinitionSchema));
|
|
7171
|
+
const HOOK_EVENT_SET = new Set(HOOK_EVENTS);
|
|
7172
|
+
/** Whether `value` is a canonical hook event name. */
|
|
7173
|
+
const isHookEvent = (value) => HOOK_EVENT_SET.has(value);
|
|
7174
|
+
/**
|
|
7175
|
+
* Top-level `hooks` record whose keys must be canonical event names, so typos
|
|
7176
|
+
* are rejected at parse time. Keys are validated with a refinement (instead of
|
|
7177
|
+
* an enum key schema) to keep the inferred type a plain string record.
|
|
7178
|
+
*
|
|
7179
|
+
* The per-tool override blocks below deliberately keep the lenient
|
|
7180
|
+
* `hooksRecordSchema`: some are documented to pass tool-native event keys
|
|
7181
|
+
* through verbatim (e.g. kiro-ide's IDE-only `PostFileSave`/`PreTaskExec`
|
|
7182
|
+
* triggers), which the canonical enum would reject.
|
|
7183
|
+
*/
|
|
7184
|
+
const canonicalHooksRecordSchema = zod_mini.z.record(zod_mini.z.string(), zod_mini.z.array(HookDefinitionSchema)).check(zod_mini.z.refine((record) => Object.keys(record).every((key) => HOOK_EVENT_SET.has(key)), { error: (issue) => {
|
|
7185
|
+
return `unknown hook event name(s): ${Object.keys(issue.input ?? {}).filter((key) => !HOOK_EVENT_SET.has(key)).join(", ")}`;
|
|
7186
|
+
} }));
|
|
6718
7187
|
/**
|
|
6719
7188
|
* Canonical hooks config (canonical event names in camelCase).
|
|
6720
7189
|
*/
|
|
6721
7190
|
const HooksConfigSchema = zod_mini.z.looseObject({
|
|
6722
7191
|
version: zod_mini.z.optional(zod_mini.z.number()),
|
|
6723
|
-
hooks:
|
|
7192
|
+
hooks: canonicalHooksRecordSchema,
|
|
6724
7193
|
cursor: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
6725
7194
|
claudecode: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
6726
7195
|
copilot: zod_mini.z.optional(zod_mini.z.looseObject({ hooks: zod_mini.z.optional(hooksRecordSchema) })),
|
|
@@ -7157,6 +7626,20 @@ const CANONICAL_TO_GROKCLI_EVENT_NAMES = {
|
|
|
7157
7626
|
*/
|
|
7158
7627
|
const GROKCLI_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_GROKCLI_EVENT_NAMES).map(([k, v]) => [v, k]));
|
|
7159
7628
|
//#endregion
|
|
7629
|
+
//#region src/utils/object.ts
|
|
7630
|
+
/**
|
|
7631
|
+
* Return a shallow copy of `obj` keeping only the entries whose value is
|
|
7632
|
+
* neither `undefined` nor `null`.
|
|
7633
|
+
*
|
|
7634
|
+
* Used to assemble generated config objects without one conditional spread per
|
|
7635
|
+
* optional field (which would otherwise exceed the lint complexity budget).
|
|
7636
|
+
*/
|
|
7637
|
+
function compact(obj) {
|
|
7638
|
+
const result = {};
|
|
7639
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== null) result[key] = value;
|
|
7640
|
+
return result;
|
|
7641
|
+
}
|
|
7642
|
+
//#endregion
|
|
7160
7643
|
//#region src/features/hooks/tool-hooks-converter.ts
|
|
7161
7644
|
function isToolMatcherEntry(x) {
|
|
7162
7645
|
if (x === null || typeof x !== "object") return false;
|
|
@@ -7214,6 +7697,25 @@ function importBooleanPassthroughFields({ h, converterConfig }) {
|
|
|
7214
7697
|
return Object.fromEntries((converterConfig.booleanPassthroughFields ?? []).filter(({ tool }) => typeof h[tool] === "boolean").map(({ canonical, tool }) => [canonical, h[tool]]));
|
|
7215
7698
|
}
|
|
7216
7699
|
/**
|
|
7700
|
+
* Emit the payload fields specific to a hook type — `url`/`headers`/
|
|
7701
|
+
* `allowedEnvVars` for http, `server`/`tool`/`input` for mcp_tool, `model`
|
|
7702
|
+
* for prompt/agent. https://code.claude.com/docs/en/hooks
|
|
7703
|
+
*/
|
|
7704
|
+
function emitTypePayloadFields({ def, hookType, converterConfig }) {
|
|
7705
|
+
if (hookType === "http") return compact({
|
|
7706
|
+
url: def.url,
|
|
7707
|
+
headers: def.headers,
|
|
7708
|
+
allowedEnvVars: def.allowedEnvVars
|
|
7709
|
+
});
|
|
7710
|
+
if (hookType === "mcp_tool") return compact({
|
|
7711
|
+
server: def.server,
|
|
7712
|
+
tool: def.tool,
|
|
7713
|
+
input: def.input
|
|
7714
|
+
});
|
|
7715
|
+
if ((hookType === "prompt" || hookType === "agent") && converterConfig.emitsPromptModel) return compact({ model: def.model });
|
|
7716
|
+
return {};
|
|
7717
|
+
}
|
|
7718
|
+
/**
|
|
7217
7719
|
* Convert the definitions of a single matcher group into tool hook entries,
|
|
7218
7720
|
* honoring supported hook types and passthrough fields.
|
|
7219
7721
|
*/
|
|
@@ -7235,6 +7737,11 @@ function buildToolHooks({ defs, converterConfig }) {
|
|
|
7235
7737
|
...command !== void 0 && command !== null && { command },
|
|
7236
7738
|
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
7237
7739
|
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt },
|
|
7740
|
+
...emitTypePayloadFields({
|
|
7741
|
+
def,
|
|
7742
|
+
hookType,
|
|
7743
|
+
converterConfig
|
|
7744
|
+
}),
|
|
7238
7745
|
...converterConfig.passthroughFields?.includes("name") && def.name !== void 0 && def.name !== null && { name: def.name },
|
|
7239
7746
|
...converterConfig.passthroughFields?.includes("description") && def.description !== void 0 && def.description !== null && { description: def.description }
|
|
7240
7747
|
});
|
|
@@ -7301,6 +7808,46 @@ function stripCommandPrefix({ command, converterConfig }) {
|
|
|
7301
7808
|
return cmd;
|
|
7302
7809
|
}
|
|
7303
7810
|
/**
|
|
7811
|
+
* Hook types preserved verbatim on import — Claude Code's five documented
|
|
7812
|
+
* handler types. Anything else is coerced to `command` as before.
|
|
7813
|
+
* https://code.claude.com/docs/en/hooks
|
|
7814
|
+
*/
|
|
7815
|
+
const IMPORTED_HOOK_TYPES = /* @__PURE__ */ new Set([
|
|
7816
|
+
"command",
|
|
7817
|
+
"prompt",
|
|
7818
|
+
"http",
|
|
7819
|
+
"mcp_tool",
|
|
7820
|
+
"agent"
|
|
7821
|
+
]);
|
|
7822
|
+
function isImportedHookType(value) {
|
|
7823
|
+
return typeof value === "string" && IMPORTED_HOOK_TYPES.has(value);
|
|
7824
|
+
}
|
|
7825
|
+
function isStringRecord(value) {
|
|
7826
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
7827
|
+
return Object.values(value).every((v) => typeof v === "string");
|
|
7828
|
+
}
|
|
7829
|
+
function isStringArray(value) {
|
|
7830
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
7831
|
+
}
|
|
7832
|
+
/**
|
|
7833
|
+
* Import the payload fields specific to a hook type, type-checking each raw
|
|
7834
|
+
* value before it enters the canonical definition.
|
|
7835
|
+
*/
|
|
7836
|
+
function importTypePayloadFields({ h, hookType }) {
|
|
7837
|
+
if (hookType === "http") return {
|
|
7838
|
+
...typeof h.url === "string" && { url: h.url },
|
|
7839
|
+
...isStringRecord(h.headers) && { headers: h.headers },
|
|
7840
|
+
...isStringArray(h.allowedEnvVars) && { allowedEnvVars: h.allowedEnvVars }
|
|
7841
|
+
};
|
|
7842
|
+
if (hookType === "mcp_tool") return {
|
|
7843
|
+
...typeof h.server === "string" && { server: h.server },
|
|
7844
|
+
...typeof h.tool === "string" && { tool: h.tool },
|
|
7845
|
+
...h.input !== null && typeof h.input === "object" && !Array.isArray(h.input) && { input: h.input }
|
|
7846
|
+
};
|
|
7847
|
+
if (hookType === "prompt" || hookType === "agent") return typeof h.model === "string" ? { model: h.model } : {};
|
|
7848
|
+
return {};
|
|
7849
|
+
}
|
|
7850
|
+
/**
|
|
7304
7851
|
* Convert a single tool hook record into a canonical hook definition.
|
|
7305
7852
|
*/
|
|
7306
7853
|
function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
@@ -7308,7 +7855,7 @@ function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
|
7308
7855
|
command: h.command,
|
|
7309
7856
|
converterConfig
|
|
7310
7857
|
});
|
|
7311
|
-
const hookType = h.type
|
|
7858
|
+
const hookType = isImportedHookType(h.type) ? h.type : "command";
|
|
7312
7859
|
const timeout = typeof h.timeout === "number" ? h.timeout : void 0;
|
|
7313
7860
|
const prompt = typeof h.prompt === "string" ? h.prompt : void 0;
|
|
7314
7861
|
return {
|
|
@@ -7316,6 +7863,10 @@ function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
|
7316
7863
|
...command !== void 0 && command !== null && { command },
|
|
7317
7864
|
...timeout !== void 0 && timeout !== null && { timeout },
|
|
7318
7865
|
...prompt !== void 0 && prompt !== null && { prompt },
|
|
7866
|
+
...importTypePayloadFields({
|
|
7867
|
+
h,
|
|
7868
|
+
hookType
|
|
7869
|
+
}),
|
|
7319
7870
|
...converterConfig.passthroughFields?.includes("name") && typeof h.name === "string" && { name: h.name },
|
|
7320
7871
|
...converterConfig.passthroughFields?.includes("description") && typeof h.description === "string" && { description: h.description },
|
|
7321
7872
|
...importBooleanPassthroughFields({
|
|
@@ -7335,6 +7886,32 @@ function toolMatcherEntryToCanonical({ rawEntry, converterConfig }) {
|
|
|
7335
7886
|
converterConfig
|
|
7336
7887
|
}));
|
|
7337
7888
|
}
|
|
7889
|
+
/**
|
|
7890
|
+
* Assemble the canonical hooks config a tool importer writes to
|
|
7891
|
+
* `.rulesync/hooks.json`.
|
|
7892
|
+
*
|
|
7893
|
+
* The top-level `hooks` record only accepts canonical event names, so any
|
|
7894
|
+
* imported native event key without a canonical mapping is moved under the
|
|
7895
|
+
* importing tool's own override block (`<overrideKey>.hooks`), whose keys stay
|
|
7896
|
+
* lenient. This mirrors the generate direction — override blocks pass
|
|
7897
|
+
* tool-native keys through verbatim — so documented native triggers (e.g.
|
|
7898
|
+
* kiro-ide's `PostFileSave`) survive an import → generate round-trip instead
|
|
7899
|
+
* of failing canonical validation.
|
|
7900
|
+
*/
|
|
7901
|
+
function buildImportedHooksConfig({ hooks, overrideKey, version = 1, extraOverride }) {
|
|
7902
|
+
const canonical = {};
|
|
7903
|
+
const native = {};
|
|
7904
|
+
for (const [event, defs] of Object.entries(hooks)) if (isHookEvent(event)) canonical[event] = defs;
|
|
7905
|
+
else native[event] = defs;
|
|
7906
|
+
const override = { ...extraOverride };
|
|
7907
|
+
if (Object.keys(native).length > 0) override.hooks = native;
|
|
7908
|
+
const config = {
|
|
7909
|
+
version,
|
|
7910
|
+
hooks: canonical
|
|
7911
|
+
};
|
|
7912
|
+
if (Object.keys(override).length > 0) config[overrideKey] = override;
|
|
7913
|
+
return config;
|
|
7914
|
+
}
|
|
7338
7915
|
function toolHooksToCanonical({ hooks, converterConfig }) {
|
|
7339
7916
|
if (hooks === null || hooks === void 0 || typeof hooks !== "object") return {};
|
|
7340
7917
|
const canonical = {};
|
|
@@ -7505,7 +8082,8 @@ const ANTIGRAVITY_CONVERTER_CONFIG = {
|
|
|
7505
8082
|
"preModelInvocation",
|
|
7506
8083
|
"postModelInvocation",
|
|
7507
8084
|
"stop"
|
|
7508
|
-
])
|
|
8085
|
+
]),
|
|
8086
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command"])
|
|
7509
8087
|
};
|
|
7510
8088
|
/**
|
|
7511
8089
|
* Antigravity's `hooks.json` is keyed by a named hook whose value holds the
|
|
@@ -7612,10 +8190,11 @@ var AntigravityHooks = class extends ToolHooks {
|
|
|
7612
8190
|
hooks: flattenAntigravityHooks(parsed),
|
|
7613
8191
|
converterConfig: ANTIGRAVITY_CONVERTER_CONFIG
|
|
7614
8192
|
});
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
hooks
|
|
7618
|
-
|
|
8193
|
+
const overrideKey = this.constructor.getOverrideKey();
|
|
8194
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8195
|
+
hooks,
|
|
8196
|
+
overrideKey
|
|
8197
|
+
}), null, 2) });
|
|
7619
8198
|
}
|
|
7620
8199
|
validate() {
|
|
7621
8200
|
return {
|
|
@@ -7736,7 +8315,8 @@ const AUGMENTCODE_CONVERTER_CONFIG = {
|
|
|
7736
8315
|
"sessionEnd",
|
|
7737
8316
|
"stop",
|
|
7738
8317
|
"notification"
|
|
7739
|
-
])
|
|
8318
|
+
]),
|
|
8319
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command"])
|
|
7740
8320
|
};
|
|
7741
8321
|
/**
|
|
7742
8322
|
* AugmentCode (Auggie CLI) lifecycle hooks.
|
|
@@ -7818,10 +8398,10 @@ var AugmentcodeHooks = class AugmentcodeHooks extends ToolHooks {
|
|
|
7818
8398
|
hooks: settings.hooks,
|
|
7819
8399
|
converterConfig: AUGMENTCODE_CONVERTER_CONFIG
|
|
7820
8400
|
});
|
|
7821
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
}, null, 2) });
|
|
8401
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8402
|
+
hooks,
|
|
8403
|
+
overrideKey: "augmentcode"
|
|
8404
|
+
}), null, 2) });
|
|
7825
8405
|
}
|
|
7826
8406
|
validate() {
|
|
7827
8407
|
return {
|
|
@@ -7856,7 +8436,15 @@ const CLAUDE_CONVERTER_CONFIG = {
|
|
|
7856
8436
|
"taskCompleted",
|
|
7857
8437
|
"teammateIdle",
|
|
7858
8438
|
"cwdChanged"
|
|
7859
|
-
])
|
|
8439
|
+
]),
|
|
8440
|
+
supportedHookTypes: /* @__PURE__ */ new Set([
|
|
8441
|
+
"command",
|
|
8442
|
+
"prompt",
|
|
8443
|
+
"http",
|
|
8444
|
+
"mcp_tool",
|
|
8445
|
+
"agent"
|
|
8446
|
+
]),
|
|
8447
|
+
emitsPromptModel: true
|
|
7860
8448
|
};
|
|
7861
8449
|
var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
7862
8450
|
constructor(params) {
|
|
@@ -7921,10 +8509,10 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
7921
8509
|
hooks: settings.hooks,
|
|
7922
8510
|
converterConfig: CLAUDE_CONVERTER_CONFIG
|
|
7923
8511
|
});
|
|
7924
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
}, null, 2) });
|
|
8512
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8513
|
+
hooks,
|
|
8514
|
+
overrideKey: "claudecode"
|
|
8515
|
+
}), null, 2) });
|
|
7928
8516
|
}
|
|
7929
8517
|
validate() {
|
|
7930
8518
|
return {
|
|
@@ -8067,10 +8655,10 @@ var CodexcliHooks = class CodexcliHooks extends ToolHooks {
|
|
|
8067
8655
|
hooks: parsed.hooks,
|
|
8068
8656
|
converterConfig: CODEXCLI_CONVERTER_CONFIG
|
|
8069
8657
|
});
|
|
8070
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
}, null, 2) });
|
|
8658
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8659
|
+
hooks,
|
|
8660
|
+
overrideKey: "codexcli"
|
|
8661
|
+
}), null, 2) });
|
|
8074
8662
|
}
|
|
8075
8663
|
validate() {
|
|
8076
8664
|
return {
|
|
@@ -8238,10 +8826,10 @@ var CopilotHooks = class CopilotHooks extends ToolHooks {
|
|
|
8238
8826
|
throw new Error(`Failed to parse Copilot hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8239
8827
|
}
|
|
8240
8828
|
const hooks = copilotHooksToCanonical(parsed.hooks, options?.logger);
|
|
8241
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
}, null, 2) });
|
|
8829
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8830
|
+
hooks,
|
|
8831
|
+
overrideKey: "copilot"
|
|
8832
|
+
}), null, 2) });
|
|
8245
8833
|
}
|
|
8246
8834
|
validate() {
|
|
8247
8835
|
return {
|
|
@@ -8260,20 +8848,6 @@ var CopilotHooks = class CopilotHooks extends ToolHooks {
|
|
|
8260
8848
|
}
|
|
8261
8849
|
};
|
|
8262
8850
|
//#endregion
|
|
8263
|
-
//#region src/utils/object.ts
|
|
8264
|
-
/**
|
|
8265
|
-
* Return a shallow copy of `obj` keeping only the entries whose value is
|
|
8266
|
-
* neither `undefined` nor `null`.
|
|
8267
|
-
*
|
|
8268
|
-
* Used to assemble generated config objects without one conditional spread per
|
|
8269
|
-
* optional field (which would otherwise exceed the lint complexity budget).
|
|
8270
|
-
*/
|
|
8271
|
-
function compact(obj) {
|
|
8272
|
-
const result = {};
|
|
8273
|
-
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== null) result[key] = value;
|
|
8274
|
-
return result;
|
|
8275
|
-
}
|
|
8276
|
-
//#endregion
|
|
8277
8851
|
//#region src/features/hooks/copilotcli-hooks.ts
|
|
8278
8852
|
/**
|
|
8279
8853
|
* GitHub Copilot CLI hooks.
|
|
@@ -8406,7 +8980,7 @@ function buildCopilotCliEntriesForEvent({ eventName, definitions, canonicalSchem
|
|
|
8406
8980
|
...timeoutPart,
|
|
8407
8981
|
...rest
|
|
8408
8982
|
});
|
|
8409
|
-
else entries.push({
|
|
8983
|
+
else if (hookType === "command") entries.push({
|
|
8410
8984
|
type: "command",
|
|
8411
8985
|
...matcherPart,
|
|
8412
8986
|
...compact({
|
|
@@ -8558,10 +9132,10 @@ var CopilotcliHooks = class CopilotcliHooks extends ToolHooks {
|
|
|
8558
9132
|
throw new Error(`Failed to parse Copilot CLI hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8559
9133
|
}
|
|
8560
9134
|
const hooks = copilotCliHooksToCanonical(parsed.hooks, options?.logger);
|
|
8561
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
}, null, 2) });
|
|
9135
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9136
|
+
hooks,
|
|
9137
|
+
overrideKey: "copilotcli"
|
|
9138
|
+
}), null, 2) });
|
|
8565
9139
|
}
|
|
8566
9140
|
validate() {
|
|
8567
9141
|
return {
|
|
@@ -8616,9 +9190,10 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8616
9190
|
...config.cursor?.hooks
|
|
8617
9191
|
};
|
|
8618
9192
|
const mappedHooks = {};
|
|
9193
|
+
const cursorSupportedTypes = /* @__PURE__ */ new Set(["command", "prompt"]);
|
|
8619
9194
|
for (const [eventName, defs] of Object.entries(mergedHooks)) {
|
|
8620
9195
|
const cursorEventName = CANONICAL_TO_CURSOR_EVENT_NAMES[eventName] ?? eventName;
|
|
8621
|
-
|
|
9196
|
+
const mappedDefs = defs.filter((def) => cursorSupportedTypes.has(def.type ?? "command")).map((def) => ({
|
|
8622
9197
|
...def.type !== void 0 && def.type !== null && { type: def.type },
|
|
8623
9198
|
...def.command !== void 0 && def.command !== null && { command: def.command },
|
|
8624
9199
|
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
@@ -8627,6 +9202,7 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8627
9202
|
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt },
|
|
8628
9203
|
...def.failClosed !== void 0 && def.failClosed !== null && { failClosed: def.failClosed }
|
|
8629
9204
|
}));
|
|
9205
|
+
if (mappedDefs.length > 0) mappedHooks[cursorEventName] = mappedDefs;
|
|
8630
9206
|
}
|
|
8631
9207
|
const cursorConfig = {
|
|
8632
9208
|
version: config.version ?? 1,
|
|
@@ -8653,10 +9229,11 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8653
9229
|
canonicalHooks[eventName] = defs;
|
|
8654
9230
|
}
|
|
8655
9231
|
const version = parsed.version ?? 1;
|
|
8656
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
9232
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9233
|
+
hooks: canonicalHooks,
|
|
9234
|
+
overrideKey: "cursor",
|
|
9235
|
+
version
|
|
9236
|
+
}), null, 2) });
|
|
8660
9237
|
}
|
|
8661
9238
|
validate() {
|
|
8662
9239
|
return {
|
|
@@ -8711,7 +9288,7 @@ function canonicalToDeepagentsHooks(config) {
|
|
|
8711
9288
|
const deepagentsEvent = CANONICAL_TO_DEEPAGENTS_EVENT_NAMES[canonicalEvent];
|
|
8712
9289
|
if (!deepagentsEvent) continue;
|
|
8713
9290
|
for (const def of definitions) {
|
|
8714
|
-
if (def.type
|
|
9291
|
+
if ((def.type ?? "command") !== "command") continue;
|
|
8715
9292
|
if (!def.command) continue;
|
|
8716
9293
|
if (def.matcher) continue;
|
|
8717
9294
|
entries.push({
|
|
@@ -8801,10 +9378,10 @@ var DeepagentsHooks = class DeepagentsHooks extends ToolHooks {
|
|
|
8801
9378
|
throw new Error(`Failed to parse deepagents hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8802
9379
|
}
|
|
8803
9380
|
const hooks = deepagentsToCanonicalHooks(isDeepagentsHooksFile(parsed) ? parsed.hooks : []);
|
|
8804
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
}, null, 2) });
|
|
9381
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9382
|
+
hooks,
|
|
9383
|
+
overrideKey: "deepagents"
|
|
9384
|
+
}), null, 2) });
|
|
8808
9385
|
}
|
|
8809
9386
|
validate() {
|
|
8810
9387
|
return {
|
|
@@ -8933,10 +9510,10 @@ var DevinHooks = class DevinHooks extends ToolHooks {
|
|
|
8933
9510
|
hooks: this.getRelativeFilePath() === "config.json" ? isRecord(parsed) && isRecord(parsed.hooks) ? parsed.hooks : {} : parsed,
|
|
8934
9511
|
converterConfig: DEVIN_CONVERTER_CONFIG
|
|
8935
9512
|
});
|
|
8936
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8937
|
-
|
|
8938
|
-
|
|
8939
|
-
}, null, 2) });
|
|
9513
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9514
|
+
hooks,
|
|
9515
|
+
overrideKey: "devin"
|
|
9516
|
+
}), null, 2) });
|
|
8940
9517
|
}
|
|
8941
9518
|
validate() {
|
|
8942
9519
|
return {
|
|
@@ -8960,7 +9537,8 @@ const FACTORYDROID_CONVERTER_CONFIG = {
|
|
|
8960
9537
|
supportedEvents: FACTORYDROID_HOOK_EVENTS,
|
|
8961
9538
|
canonicalToToolEventNames: CANONICAL_TO_FACTORYDROID_EVENT_NAMES,
|
|
8962
9539
|
toolToCanonicalEventNames: FACTORYDROID_TO_CANONICAL_EVENT_NAMES,
|
|
8963
|
-
projectDirVar: "$FACTORY_PROJECT_DIR"
|
|
9540
|
+
projectDirVar: "$FACTORY_PROJECT_DIR",
|
|
9541
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command", "prompt"])
|
|
8964
9542
|
};
|
|
8965
9543
|
var FactorydroidHooks = class FactorydroidHooks extends ToolHooks {
|
|
8966
9544
|
constructor(params) {
|
|
@@ -9028,10 +9606,10 @@ var FactorydroidHooks = class FactorydroidHooks extends ToolHooks {
|
|
|
9028
9606
|
hooks: settings.hooks,
|
|
9029
9607
|
converterConfig: FACTORYDROID_CONVERTER_CONFIG
|
|
9030
9608
|
});
|
|
9031
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
}, null, 2) });
|
|
9609
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9610
|
+
hooks,
|
|
9611
|
+
overrideKey: "factorydroid"
|
|
9612
|
+
}), null, 2) });
|
|
9035
9613
|
}
|
|
9036
9614
|
validate() {
|
|
9037
9615
|
return {
|
|
@@ -9122,10 +9700,10 @@ var GooseHooks = class GooseHooks extends ToolHooks {
|
|
|
9122
9700
|
hooks: parsed.hooks && typeof parsed.hooks === "object" && !Array.isArray(parsed.hooks) ? Object.fromEntries(Object.entries(parsed.hooks).filter(([eventName]) => Object.hasOwn(GOOSE_TO_CANONICAL_EVENT_NAMES, eventName))) : parsed.hooks,
|
|
9123
9701
|
converterConfig: GOOSE_CONVERTER_CONFIG
|
|
9124
9702
|
});
|
|
9125
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9126
|
-
|
|
9127
|
-
|
|
9128
|
-
}, null, 2) });
|
|
9703
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9704
|
+
hooks,
|
|
9705
|
+
overrideKey: "goose"
|
|
9706
|
+
}), null, 2) });
|
|
9129
9707
|
}
|
|
9130
9708
|
validate() {
|
|
9131
9709
|
return {
|
|
@@ -9283,10 +9861,10 @@ var GrokcliHooks = class GrokcliHooks extends ToolHooks {
|
|
|
9283
9861
|
hooks: isRecord(parsed) && isRecord(parsed.hooks) ? parsed.hooks : {},
|
|
9284
9862
|
converterConfig: GROKCLI_CONVERTER_CONFIG
|
|
9285
9863
|
});
|
|
9286
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
}, null, 2) });
|
|
9864
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9865
|
+
hooks,
|
|
9866
|
+
overrideKey: "grokcli"
|
|
9867
|
+
}), null, 2) });
|
|
9290
9868
|
}
|
|
9291
9869
|
validate() {
|
|
9292
9870
|
return {
|
|
@@ -9447,10 +10025,10 @@ var HermesagentHooks = class HermesagentHooks extends ToolHooks {
|
|
|
9447
10025
|
format: "yaml",
|
|
9448
10026
|
fileContent: this.getFileContent()
|
|
9449
10027
|
}).hooks);
|
|
9450
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
}, null, 2) });
|
|
10028
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10029
|
+
hooks,
|
|
10030
|
+
overrideKey: "hermesagent"
|
|
10031
|
+
}), null, 2) });
|
|
9454
10032
|
}
|
|
9455
10033
|
static fromRulesyncHooks({ outputRoot, rulesyncHooks, logger }) {
|
|
9456
10034
|
const config = rulesyncHooks.getJson();
|
|
@@ -9553,10 +10131,10 @@ var JunieHooks = class JunieHooks extends ToolHooks {
|
|
|
9553
10131
|
hooks: settings.hooks,
|
|
9554
10132
|
converterConfig: JUNIE_CONVERTER_CONFIG
|
|
9555
10133
|
});
|
|
9556
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
}, null, 2) });
|
|
10134
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10135
|
+
hooks,
|
|
10136
|
+
overrideKey: "junie"
|
|
10137
|
+
}), null, 2) });
|
|
9560
10138
|
}
|
|
9561
10139
|
validate() {
|
|
9562
10140
|
return {
|
|
@@ -9601,7 +10179,7 @@ function collectOpencodeStyleHandlers({ effectiveHooks, eventMap, namedEventHand
|
|
|
9601
10179
|
if (!toolEvent) continue;
|
|
9602
10180
|
const handlers = [];
|
|
9603
10181
|
for (const def of definitions) {
|
|
9604
|
-
if (def.type
|
|
10182
|
+
if ((def.type ?? "command") !== "command") continue;
|
|
9605
10183
|
if (!def.command) continue;
|
|
9606
10184
|
handlers.push({
|
|
9607
10185
|
command: def.command,
|
|
@@ -9906,10 +10484,11 @@ var KiroHooks = class KiroHooks extends ToolHooks {
|
|
|
9906
10484
|
throw new Error(`Failed to parse Kiro hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
9907
10485
|
}
|
|
9908
10486
|
const hooks = kiroHooksToCanonical(agentConfig.hooks);
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
hooks
|
|
9912
|
-
|
|
10487
|
+
const overrideKey = this.constructor.getOverrideKey();
|
|
10488
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10489
|
+
hooks,
|
|
10490
|
+
overrideKey
|
|
10491
|
+
}), null, 2) });
|
|
9913
10492
|
}
|
|
9914
10493
|
validate() {
|
|
9915
10494
|
return {
|
|
@@ -10118,10 +10697,10 @@ var KiroIdeHooks = class KiroIdeHooks extends ToolHooks {
|
|
|
10118
10697
|
throw new Error(`Failed to parse Kiro IDE hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10119
10698
|
}
|
|
10120
10699
|
const hooks = kiroIdeHooksToCanonical(parsed.hooks ?? []);
|
|
10121
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10122
|
-
|
|
10123
|
-
|
|
10124
|
-
}, null, 2) });
|
|
10700
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10701
|
+
hooks,
|
|
10702
|
+
overrideKey: "kiro-ide"
|
|
10703
|
+
}), null, 2) });
|
|
10125
10704
|
}
|
|
10126
10705
|
validate() {
|
|
10127
10706
|
return {
|
|
@@ -10245,11 +10824,18 @@ function canonicalToQwencodeHooks(config) {
|
|
|
10245
10824
|
...sharedHooks,
|
|
10246
10825
|
...config.qwencode?.hooks
|
|
10247
10826
|
};
|
|
10827
|
+
const qwencodeSupportedTypes = /* @__PURE__ */ new Set([
|
|
10828
|
+
"command",
|
|
10829
|
+
"prompt",
|
|
10830
|
+
"http",
|
|
10831
|
+
"function"
|
|
10832
|
+
]);
|
|
10248
10833
|
const qwencode = {};
|
|
10249
10834
|
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
10250
10835
|
const qwencodeEventName = CANONICAL_TO_QWENCODE_EVENT_NAMES[eventName] ?? eventName;
|
|
10251
10836
|
const byMatcher = /* @__PURE__ */ new Map();
|
|
10252
10837
|
for (const def of definitions) {
|
|
10838
|
+
if (!qwencodeSupportedTypes.has(def.type ?? "command")) continue;
|
|
10253
10839
|
const key = def.matcher ?? "";
|
|
10254
10840
|
const list = byMatcher.get(key);
|
|
10255
10841
|
if (list) list.push(def);
|
|
@@ -10309,9 +10895,10 @@ function qwencodeMatcherEntryToCanonical(entry) {
|
|
|
10309
10895
|
const sequential = entry.sequential === true;
|
|
10310
10896
|
const matcher = entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" ? entry.matcher : void 0;
|
|
10311
10897
|
for (const h of hooks) {
|
|
10312
|
-
const hookType = h.type === "command" || h.type === "prompt" || h.type === "http" ? h.type : "command";
|
|
10898
|
+
const hookType = h.type === "command" || h.type === "prompt" || h.type === "http" || h.type === "function" ? h.type : "command";
|
|
10313
10899
|
const isHttp = hookType === "http";
|
|
10314
10900
|
const isCommand = hookType === "command";
|
|
10901
|
+
const shell = h.shell === "bash" || h.shell === "powershell" ? h.shell : void 0;
|
|
10315
10902
|
defs.push({
|
|
10316
10903
|
type: hookType,
|
|
10317
10904
|
...compact({
|
|
@@ -10323,7 +10910,7 @@ function qwencodeMatcherEntryToCanonical(entry) {
|
|
|
10323
10910
|
statusMessage: h.statusMessage,
|
|
10324
10911
|
async: isCommand ? h.async : void 0,
|
|
10325
10912
|
env: isCommand ? h.env : void 0,
|
|
10326
|
-
shell: isCommand ?
|
|
10913
|
+
shell: isCommand ? shell : void 0,
|
|
10327
10914
|
headers: isHttp ? h.headers : void 0,
|
|
10328
10915
|
allowedEnvVars: isHttp ? h.allowedEnvVars : void 0,
|
|
10329
10916
|
once: isHttp ? h.once : void 0,
|
|
@@ -10410,15 +10997,11 @@ var QwencodeHooks = class QwencodeHooks extends ToolHooks {
|
|
|
10410
10997
|
} catch (error) {
|
|
10411
10998
|
throw new Error(`Failed to parse Qwen Code hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10412
10999
|
}
|
|
10413
|
-
const
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
} : {
|
|
10419
|
-
version: 1,
|
|
10420
|
-
hooks
|
|
10421
|
-
};
|
|
11000
|
+
const canonical = buildImportedHooksConfig({
|
|
11001
|
+
hooks: qwencodeHooksToCanonical(settings.hooks),
|
|
11002
|
+
overrideKey: "qwencode",
|
|
11003
|
+
...typeof settings.disableAllHooks === "boolean" && { extraOverride: { disableAllHooks: settings.disableAllHooks } }
|
|
11004
|
+
});
|
|
10422
11005
|
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(canonical, null, 2) });
|
|
10423
11006
|
}
|
|
10424
11007
|
validate() {
|
|
@@ -10580,10 +11163,10 @@ var ReasonixHooks = class ReasonixHooks extends ToolHooks {
|
|
|
10580
11163
|
throw new Error(`Failed to parse Reasonix hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10581
11164
|
}
|
|
10582
11165
|
const hooks = reasonixHooksToCanonical(settings.hooks);
|
|
10583
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
}, null, 2) });
|
|
11166
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
11167
|
+
hooks,
|
|
11168
|
+
overrideKey: "reasonix"
|
|
11169
|
+
}), null, 2) });
|
|
10587
11170
|
}
|
|
10588
11171
|
validate() {
|
|
10589
11172
|
return {
|
|
@@ -10806,10 +11389,10 @@ var VibeHooks = class VibeHooks extends ToolHooks {
|
|
|
10806
11389
|
throw new Error(`Failed to parse Vibe hooks content in ${(0, node_path.join)(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10807
11390
|
}
|
|
10808
11391
|
const hooks = vibeHooksToCanonical(parsed);
|
|
10809
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10810
|
-
|
|
10811
|
-
|
|
10812
|
-
}, null, 2) });
|
|
11392
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
11393
|
+
hooks,
|
|
11394
|
+
overrideKey: "vibe"
|
|
11395
|
+
}), null, 2) });
|
|
10813
11396
|
}
|
|
10814
11397
|
validate() {
|
|
10815
11398
|
try {
|
|
@@ -10896,7 +11479,13 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
10896
11479
|
supportsImport: true
|
|
10897
11480
|
},
|
|
10898
11481
|
supportedEvents: CLAUDE_HOOK_EVENTS,
|
|
10899
|
-
supportedHookTypes: [
|
|
11482
|
+
supportedHookTypes: [
|
|
11483
|
+
"command",
|
|
11484
|
+
"prompt",
|
|
11485
|
+
"http",
|
|
11486
|
+
"mcp_tool",
|
|
11487
|
+
"agent"
|
|
11488
|
+
],
|
|
10900
11489
|
supportsMatcher: true
|
|
10901
11490
|
}],
|
|
10902
11491
|
["codexcli", {
|
|
@@ -11088,7 +11677,12 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
11088
11677
|
supportsImport: true
|
|
11089
11678
|
},
|
|
11090
11679
|
supportedEvents: QWENCODE_HOOK_EVENTS,
|
|
11091
|
-
supportedHookTypes: [
|
|
11680
|
+
supportedHookTypes: [
|
|
11681
|
+
"command",
|
|
11682
|
+
"prompt",
|
|
11683
|
+
"http",
|
|
11684
|
+
"function"
|
|
11685
|
+
],
|
|
11092
11686
|
supportsMatcher: true
|
|
11093
11687
|
}],
|
|
11094
11688
|
["reasonix", {
|
|
@@ -12390,16 +12984,6 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
12390
12984
|
}
|
|
12391
12985
|
};
|
|
12392
12986
|
//#endregion
|
|
12393
|
-
//#region src/constants/amp-paths.ts
|
|
12394
|
-
const AMP_DIR = ".amp";
|
|
12395
|
-
const AMP_GLOBAL_DIR = (0, node_path.join)(".config", "amp");
|
|
12396
|
-
const AMP_AGENTS_DIR = ".agents";
|
|
12397
|
-
const AMP_SKILLS_PROJECT_DIR = (0, node_path.join)(AMP_AGENTS_DIR, "skills");
|
|
12398
|
-
const AMP_SKILLS_GLOBAL_DIR = (0, node_path.join)(".config", "agents", "skills");
|
|
12399
|
-
const AMP_RULE_FILE_NAME = "AGENTS.md";
|
|
12400
|
-
const AMP_SETTINGS_FILE_NAME = "settings.json";
|
|
12401
|
-
const AMP_SETTINGS_JSONC_FILE_NAME = "settings.jsonc";
|
|
12402
|
-
//#endregion
|
|
12403
12987
|
//#region src/types/mcp.ts
|
|
12404
12988
|
const EnvVarNameSchema = zod_mini.z.string().check((0, zod_mini.refine)((value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), "envVars entries must be valid environment variable names"));
|
|
12405
12989
|
const McpServerSchema = zod_mini.z.looseObject({
|
|
@@ -13491,10 +14075,19 @@ function mapOauthFromCodex(oauth) {
|
|
|
13491
14075
|
}
|
|
13492
14076
|
const CODEX_MCP_SERVER_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
13493
14077
|
function normalizeCodexMcpServerName(name) {
|
|
13494
|
-
if (PROTOTYPE_POLLUTION_KEYS.has(name)) return
|
|
13495
|
-
|
|
14078
|
+
if (!PROTOTYPE_POLLUTION_KEYS.has(name) && CODEX_MCP_SERVER_NAME_PATTERN.test(name)) return {
|
|
14079
|
+
codexName: name,
|
|
14080
|
+
usedFallback: false
|
|
14081
|
+
};
|
|
13496
14082
|
const normalizedName = name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13497
|
-
|
|
14083
|
+
if (normalizedName && !PROTOTYPE_POLLUTION_KEYS.has(normalizedName)) return {
|
|
14084
|
+
codexName: normalizedName,
|
|
14085
|
+
usedFallback: false
|
|
14086
|
+
};
|
|
14087
|
+
return {
|
|
14088
|
+
codexName: `mcp_${(0, node_crypto.createHash)("sha256").update(name).digest("hex").slice(0, 8)}`,
|
|
14089
|
+
usedFallback: true
|
|
14090
|
+
};
|
|
13498
14091
|
}
|
|
13499
14092
|
function convertFromCodexFormat(codexMcp) {
|
|
13500
14093
|
const result = {};
|
|
@@ -13508,7 +14101,7 @@ function convertFromCodexFormat(codexMcp) {
|
|
|
13508
14101
|
} else if (key === "oauth" && isRecord(value)) converted[key] = mapOauthFromCodex(value);
|
|
13509
14102
|
else if (Object.hasOwn(CODEX_TO_RULESYNC_FIELD_MAP, key)) {
|
|
13510
14103
|
const mappedKey = CODEX_TO_RULESYNC_FIELD_MAP[key];
|
|
13511
|
-
if (mappedKey) if (isStringArray(value)) converted[mappedKey] = value;
|
|
14104
|
+
if (mappedKey) if (isStringArray$1(value)) converted[mappedKey] = value;
|
|
13512
14105
|
else warnWithFallback(void 0, `Ignored malformed array for ${key} in MCP server ${name}`);
|
|
13513
14106
|
} else converted[key] = value;
|
|
13514
14107
|
}
|
|
@@ -13520,12 +14113,9 @@ function convertToCodexFormat(mcpServers) {
|
|
|
13520
14113
|
const result = {};
|
|
13521
14114
|
const originalNames = /* @__PURE__ */ new Map();
|
|
13522
14115
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
13523
|
-
const codexName = normalizeCodexMcpServerName(name);
|
|
13524
|
-
if (codexName === null) {
|
|
13525
|
-
warnWithFallback(void 0, `MCP server "${name}" could not be normalized to a valid Codex MCP server name and was skipped.`);
|
|
13526
|
-
continue;
|
|
13527
|
-
}
|
|
13528
14116
|
if (!isRecord(config)) continue;
|
|
14117
|
+
const { codexName, usedFallback } = normalizeCodexMcpServerName(name);
|
|
14118
|
+
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.json to choose a readable Codex name.`);
|
|
13529
14119
|
const converted = {};
|
|
13530
14120
|
for (const [key, value] of Object.entries(config)) {
|
|
13531
14121
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
@@ -13534,12 +14124,12 @@ function convertToCodexFormat(mcpServers) {
|
|
|
13534
14124
|
} else if (key === "oauth" && isRecord(value)) converted[key] = mapOauthToCodex(value);
|
|
13535
14125
|
else if (Object.hasOwn(RULESYNC_TO_CODEX_FIELD_MAP, key)) {
|
|
13536
14126
|
const mappedKey = RULESYNC_TO_CODEX_FIELD_MAP[key];
|
|
13537
|
-
if (mappedKey) if (isStringArray(value)) converted[mappedKey] = value;
|
|
14127
|
+
if (mappedKey) if (isStringArray$1(value)) converted[mappedKey] = value;
|
|
13538
14128
|
else warnWithFallback(void 0, `[CodexCliMcp] Skipping invalid value type for mapped key '${key}': expected string array, got ${typeof value}`);
|
|
13539
14129
|
} else converted[key] = value;
|
|
13540
14130
|
}
|
|
13541
14131
|
const previousName = originalNames.get(codexName);
|
|
13542
|
-
if (previousName !== void 0) warnWithFallback(void 0, `Codex MCP server name collision: "${previousName}" and "${name}" both normalize to "${codexName}"
|
|
14132
|
+
if (previousName !== void 0) warnWithFallback(void 0, `Codex MCP server name collision: "${previousName}" and "${name}" both normalize to "${codexName}"; "${name}" (processed last) overwrites "${previousName}".`);
|
|
13543
14133
|
originalNames.set(codexName, name);
|
|
13544
14134
|
result[codexName] = converted;
|
|
13545
14135
|
}
|
|
@@ -13606,7 +14196,7 @@ var CodexcliMcp = class CodexcliMcp extends ToolMcp {
|
|
|
13606
14196
|
const rawServer = isRecord(rawMcpServers) ? rawMcpServers[serverName] : void 0;
|
|
13607
14197
|
return [serverName, {
|
|
13608
14198
|
...serverConfig,
|
|
13609
|
-
...isRecord(rawServer) && isStringArray(rawServer.envVars) ? { envVars: rawServer.envVars } : {}
|
|
14199
|
+
...isRecord(rawServer) && isStringArray$1(rawServer.envVars) ? { envVars: rawServer.envVars } : {}
|
|
13610
14200
|
}];
|
|
13611
14201
|
})));
|
|
13612
14202
|
const filteredMcpServers = this.removeEmptyEntries(converted);
|
|
@@ -14343,11 +14933,11 @@ function applyGooseStdioFields(ext, config) {
|
|
|
14343
14933
|
if (Array.isArray(command)) {
|
|
14344
14934
|
if (typeof command[0] === "string") ext.cmd = command[0];
|
|
14345
14935
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14346
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
14936
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14347
14937
|
if (rest.length > 0 || args.length > 0) ext.args = [...rest, ...args];
|
|
14348
14938
|
} else if (typeof command === "string") {
|
|
14349
14939
|
ext.cmd = command;
|
|
14350
|
-
if (isStringArray(config.args)) ext.args = config.args;
|
|
14940
|
+
if (isStringArray$1(config.args)) ext.args = config.args;
|
|
14351
14941
|
}
|
|
14352
14942
|
if (isPlainObject$1(config.env)) ext.envs = omitPrototypePollutionKeys(config.env);
|
|
14353
14943
|
}
|
|
@@ -14405,7 +14995,7 @@ function convertFromGooseFormat(extensions) {
|
|
|
14405
14995
|
else if (type === "streamable_http") server.type = "http";
|
|
14406
14996
|
else if (type === "stdio") server.type = "stdio";
|
|
14407
14997
|
if (typeof ext.cmd === "string") server.command = ext.cmd;
|
|
14408
|
-
if (isStringArray(ext.args)) server.args = ext.args;
|
|
14998
|
+
if (isStringArray$1(ext.args)) server.args = ext.args;
|
|
14409
14999
|
if (isPlainObject$1(ext.envs)) server.env = omitPrototypePollutionKeys(ext.envs);
|
|
14410
15000
|
if (typeof ext.uri === "string") server.url = ext.uri;
|
|
14411
15001
|
if (isPlainObject$1(ext.headers)) server.headers = omitPrototypePollutionKeys(ext.headers);
|
|
@@ -14425,11 +15015,11 @@ function buildGoosePluginStdioServer(config) {
|
|
|
14425
15015
|
if (Array.isArray(command)) {
|
|
14426
15016
|
if (typeof command[0] === "string") server.command = command[0];
|
|
14427
15017
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14428
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
15018
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14429
15019
|
if (rest.length > 0 || args.length > 0) server.args = [...rest, ...args];
|
|
14430
15020
|
} else if (typeof command === "string") {
|
|
14431
15021
|
server.command = command;
|
|
14432
|
-
if (isStringArray(config.args)) server.args = config.args;
|
|
15022
|
+
if (isStringArray$1(config.args)) server.args = config.args;
|
|
14433
15023
|
}
|
|
14434
15024
|
if (isPlainObject$1(config.env)) server.env = omitPrototypePollutionKeys(config.env);
|
|
14435
15025
|
if (typeof config.cwd === "string") server.cwd = config.cwd;
|
|
@@ -14742,7 +15332,7 @@ function resolveHermesTimeout(config) {
|
|
|
14742
15332
|
*/
|
|
14743
15333
|
function copyHermesAdvancedFields(source, target) {
|
|
14744
15334
|
if (typeof source.auth === "string") target.auth = source.auth;
|
|
14745
|
-
if (typeof source.client_cert === "string" || isStringArray(source.client_cert)) target.client_cert = source.client_cert;
|
|
15335
|
+
if (typeof source.client_cert === "string" || isStringArray$1(source.client_cert)) target.client_cert = source.client_cert;
|
|
14746
15336
|
if (typeof source.client_key === "string") target.client_key = source.client_key;
|
|
14747
15337
|
if (typeof source.connect_timeout === "number") target.connect_timeout = source.connect_timeout;
|
|
14748
15338
|
if (typeof source.supports_parallel_tool_calls === "boolean") target.supports_parallel_tool_calls = source.supports_parallel_tool_calls;
|
|
@@ -14761,8 +15351,8 @@ function copyHermesAdvancedFields(source, target) {
|
|
|
14761
15351
|
*/
|
|
14762
15352
|
function buildHermesToolsBlock(config) {
|
|
14763
15353
|
const tools = {};
|
|
14764
|
-
if (isStringArray(config.enabledTools)) tools.include = config.enabledTools;
|
|
14765
|
-
if (isStringArray(config.disabledTools)) tools.exclude = config.disabledTools;
|
|
15354
|
+
if (isStringArray$1(config.enabledTools)) tools.include = config.enabledTools;
|
|
15355
|
+
if (isStringArray$1(config.disabledTools)) tools.exclude = config.disabledTools;
|
|
14766
15356
|
if (typeof config.promptsEnabled === "boolean") tools.prompts = config.promptsEnabled;
|
|
14767
15357
|
if (typeof config.resourcesEnabled === "boolean") tools.resources = config.resourcesEnabled;
|
|
14768
15358
|
return tools;
|
|
@@ -14774,8 +15364,8 @@ function buildHermesToolsBlock(config) {
|
|
|
14774
15364
|
* `promptsEnabled`/`resourcesEnabled` top-level toggles.
|
|
14775
15365
|
*/
|
|
14776
15366
|
function applyHermesToolsBlock(hermesTools, server) {
|
|
14777
|
-
if (isStringArray(hermesTools.include)) server.enabledTools = hermesTools.include;
|
|
14778
|
-
if (isStringArray(hermesTools.exclude)) server.disabledTools = hermesTools.exclude;
|
|
15367
|
+
if (isStringArray$1(hermesTools.include)) server.enabledTools = hermesTools.include;
|
|
15368
|
+
if (isStringArray$1(hermesTools.exclude)) server.disabledTools = hermesTools.exclude;
|
|
14779
15369
|
if (typeof hermesTools.prompts === "boolean") server.promptsEnabled = hermesTools.prompts;
|
|
14780
15370
|
if (typeof hermesTools.resources === "boolean") server.resourcesEnabled = hermesTools.resources;
|
|
14781
15371
|
}
|
|
@@ -14799,11 +15389,11 @@ function convertServerToHermes(config) {
|
|
|
14799
15389
|
if (Array.isArray(command)) {
|
|
14800
15390
|
if (typeof command[0] === "string") out.command = command[0];
|
|
14801
15391
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14802
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
15392
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14803
15393
|
if (rest.length > 0 || args.length > 0) out.args = [...rest, ...args];
|
|
14804
15394
|
} else if (typeof command === "string") {
|
|
14805
15395
|
out.command = command;
|
|
14806
|
-
if (isStringArray(config.args)) out.args = config.args;
|
|
15396
|
+
if (isStringArray$1(config.args)) out.args = config.args;
|
|
14807
15397
|
}
|
|
14808
15398
|
if (isPlainObject$1(config.env)) out.env = omitPrototypePollutionKeys(config.env);
|
|
14809
15399
|
} else if (url !== void 0) {
|
|
@@ -14851,7 +15441,7 @@ function convertFromHermesFormat(mcpServers) {
|
|
|
14851
15441
|
if (PROTOTYPE_POLLUTION_KEYS.has(name) || !isRecord(config)) continue;
|
|
14852
15442
|
const server = {};
|
|
14853
15443
|
if (typeof config.command === "string") server.command = config.command;
|
|
14854
|
-
if (isStringArray(config.args)) server.args = config.args;
|
|
15444
|
+
if (isStringArray$1(config.args)) server.args = config.args;
|
|
14855
15445
|
if (isPlainObject$1(config.env)) server.env = omitPrototypePollutionKeys(config.env);
|
|
14856
15446
|
if (typeof config.url === "string") server.url = config.url;
|
|
14857
15447
|
if (isPlainObject$1(config.headers)) server.headers = omitPrototypePollutionKeys(config.headers);
|
|
@@ -17176,7 +17766,11 @@ const VibePermissionsOverrideSchema = zod_mini.z.looseObject({ permission: zod_m
|
|
|
17176
17766
|
*/
|
|
17177
17767
|
const CursorPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
17178
17768
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17179
|
-
approvalMode: zod_mini.z.optional(zod_mini.z.
|
|
17769
|
+
approvalMode: zod_mini.z.optional(zod_mini.z.enum([
|
|
17770
|
+
"allowlist",
|
|
17771
|
+
"auto-review",
|
|
17772
|
+
"unrestricted"
|
|
17773
|
+
])),
|
|
17180
17774
|
sandbox: zod_mini.z.optional(zod_mini.z.looseObject({}))
|
|
17181
17775
|
});
|
|
17182
17776
|
/**
|
|
@@ -17264,7 +17858,11 @@ const FactorydroidPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
|
17264
17858
|
*/
|
|
17265
17859
|
const WarpPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
17266
17860
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17267
|
-
agent_mode_coding_permissions: zod_mini.z.optional(zod_mini.z.
|
|
17861
|
+
agent_mode_coding_permissions: zod_mini.z.optional(zod_mini.z.enum([
|
|
17862
|
+
"always_ask_before_reading",
|
|
17863
|
+
"always_allow_reading",
|
|
17864
|
+
"allow_reading_specific_files"
|
|
17865
|
+
])),
|
|
17268
17866
|
agent_mode_coding_file_read_allowlist: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string())),
|
|
17269
17867
|
agent_mode_execute_readonly_commands: zod_mini.z.optional(zod_mini.z.boolean())
|
|
17270
17868
|
});
|
|
@@ -17310,7 +17908,11 @@ const JuniePermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
|
17310
17908
|
*/
|
|
17311
17909
|
const TaktPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
17312
17910
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17313
|
-
step_permission_overrides: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), zod_mini.z.
|
|
17911
|
+
step_permission_overrides: zod_mini.z.optional(zod_mini.z.record(zod_mini.z.string(), zod_mini.z.enum([
|
|
17912
|
+
"readonly",
|
|
17913
|
+
"edit",
|
|
17914
|
+
"full"
|
|
17915
|
+
]))),
|
|
17314
17916
|
provider_options: zod_mini.z.optional(zod_mini.z.looseObject({}))
|
|
17315
17917
|
});
|
|
17316
17918
|
/**
|
|
@@ -17340,9 +17942,15 @@ const AmpPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
|
17340
17942
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17341
17943
|
permissions: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.looseObject({
|
|
17342
17944
|
tool: zod_mini.z.string(),
|
|
17343
|
-
action: zod_mini.z.
|
|
17945
|
+
action: zod_mini.z.enum([
|
|
17946
|
+
"allow",
|
|
17947
|
+
"ask",
|
|
17948
|
+
"reject",
|
|
17949
|
+
"delegate"
|
|
17950
|
+
]),
|
|
17951
|
+
context: zod_mini.z.optional(zod_mini.z.enum(["thread", "subagent"]))
|
|
17344
17952
|
}))),
|
|
17345
|
-
mcpPermissions: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.looseObject({}))),
|
|
17953
|
+
mcpPermissions: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.looseObject({ action: zod_mini.z.enum(["allow", "reject"]) }))),
|
|
17346
17954
|
guardedFiles: zod_mini.z.optional(zod_mini.z.looseObject({ allowlist: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.string())) })),
|
|
17347
17955
|
dangerouslyAllowAll: zod_mini.z.optional(zod_mini.z.boolean())
|
|
17348
17956
|
});
|
|
@@ -17367,7 +17975,12 @@ const AmpPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
|
17367
17975
|
*/
|
|
17368
17976
|
const AntigravityCliPermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
17369
17977
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17370
|
-
toolPermission: zod_mini.z.optional(zod_mini.z.
|
|
17978
|
+
toolPermission: zod_mini.z.optional(zod_mini.z.enum([
|
|
17979
|
+
"request-review",
|
|
17980
|
+
"proceed-in-sandbox",
|
|
17981
|
+
"always-proceed",
|
|
17982
|
+
"strict"
|
|
17983
|
+
])),
|
|
17371
17984
|
enableTerminalSandbox: zod_mini.z.optional(zod_mini.z.boolean())
|
|
17372
17985
|
});
|
|
17373
17986
|
/**
|
|
@@ -17396,7 +18009,14 @@ const AugmentcodePermissionsOverrideSchema = zod_mini.z.looseObject({
|
|
|
17396
18009
|
permission: zod_mini.z.optional(ToolScopedPermissionSchema),
|
|
17397
18010
|
toolPermissions: zod_mini.z.optional(zod_mini.z.array(zod_mini.z.looseObject({
|
|
17398
18011
|
toolName: zod_mini.z.string(),
|
|
17399
|
-
|
|
18012
|
+
eventType: zod_mini.z.optional(zod_mini.z.enum(["tool-call", "tool-response"])),
|
|
18013
|
+
permission: zod_mini.z.looseObject({ type: zod_mini.z.enum([
|
|
18014
|
+
"allow",
|
|
18015
|
+
"deny",
|
|
18016
|
+
"ask-user",
|
|
18017
|
+
"webhook-policy",
|
|
18018
|
+
"script-policy"
|
|
18019
|
+
]) })
|
|
17400
18020
|
})))
|
|
17401
18021
|
});
|
|
17402
18022
|
/**
|
|
@@ -17486,12 +18106,20 @@ const CodexApprovalsReviewerSchema = zod_mini.z.enum([
|
|
|
17486
18106
|
* `[permissions.rulesync]` profile may extend. Codex ships three built-in
|
|
17487
18107
|
* profiles (`:read-only`, `:workspace`, `:danger-full-access`; the leading
|
|
17488
18108
|
* colon is reserved for built-ins), but `extends` rejects
|
|
17489
|
-
* `:danger-full-access` at config load time, so only
|
|
17490
|
-
*
|
|
17491
|
-
*
|
|
18109
|
+
* `:danger-full-access` at config load time, so only these two are valid
|
|
18110
|
+
* `extends` parents. The value list is exported so the Codex CLI translator
|
|
18111
|
+
* derives its import-side baseline check from the same source.
|
|
17492
18112
|
* @see https://learn.chatgpt.com/docs/permissions
|
|
17493
18113
|
*/
|
|
17494
|
-
const
|
|
18114
|
+
const CODEX_EXTENDABLE_BASELINE_PROFILES = [":read-only", ":workspace"];
|
|
18115
|
+
/**
|
|
18116
|
+
* All accepted `codexcli.base_permission_profile` values. `:danger-full-access`
|
|
18117
|
+
* cannot be an `extends` parent, so selecting it makes rulesync emit
|
|
18118
|
+
* `default_permissions = ":danger-full-access"` directly and skip the managed
|
|
18119
|
+
* `[permissions.rulesync]` profile entirely (there is no sandbox for
|
|
18120
|
+
* filesystem/network rules to refine in that mode).
|
|
18121
|
+
*/
|
|
18122
|
+
const CODEX_BASE_PERMISSION_PROFILES = [...CODEX_EXTENDABLE_BASELINE_PROFILES, ":danger-full-access"];
|
|
17495
18123
|
const CodexBasePermissionProfileSchema = zod_mini.z.enum(CODEX_BASE_PERMISSION_PROFILES);
|
|
17496
18124
|
/**
|
|
17497
18125
|
* Codex CLI-scoped permission override.
|
|
@@ -17502,10 +18130,14 @@ const CodexBasePermissionProfileSchema = zod_mini.z.enum(CODEX_BASE_PERMISSION_P
|
|
|
17502
18130
|
* override whose fields are written verbatim as top-level `.codex/config.toml`
|
|
17503
18131
|
* keys (the override wins per key; existing sibling keys the user set directly
|
|
17504
18132
|
* are preserved):
|
|
17505
|
-
* - `base_permission_profile` — the built-in profile
|
|
17506
|
-
*
|
|
17507
|
-
*
|
|
17508
|
-
*
|
|
18133
|
+
* - `base_permission_profile` — the built-in baseline profile (`:read-only` |
|
|
18134
|
+
* `:workspace` | `:danger-full-access`). Unlike the other keys it is not a
|
|
18135
|
+
* top-level config key: the extendable baselines are emitted as the managed
|
|
18136
|
+
* `[permissions.rulesync]` profile's `extends` value, while
|
|
18137
|
+
* `:danger-full-access` (which Codex rejects as an `extends` parent) is
|
|
18138
|
+
* selected directly via `default_permissions` and skips the managed profile
|
|
18139
|
+
* entirely — canonical filesystem/network rules are ignored in that mode.
|
|
18140
|
+
* Defaults to `:workspace` when unspecified.
|
|
17509
18141
|
* - `approval_policy` — `untrusted` | `on-request` (legacy alias `on-failure`) |
|
|
17510
18142
|
* `never`, or a `{ granular = { … } }` table (kept verbatim; the granular
|
|
17511
18143
|
* schema has required fields that are brittle to model as typed keys).
|
|
@@ -17526,13 +18158,14 @@ const CodexBasePermissionProfileSchema = zod_mini.z.enum(CODEX_BASE_PERMISSION_P
|
|
|
17526
18158
|
* Defaults to `auto_review` when neither the override nor the existing
|
|
17527
18159
|
* config sets it.
|
|
17528
18160
|
* - `git_write_rules` — whether the managed profile's `:workspace_roots` table
|
|
17529
|
-
* emits the default `.git` carve-
|
|
17530
|
-
* `".git/config" = "read"` kept read-only as a security guard). Codex's
|
|
18161
|
+
* emits the default `.git` carve-out (`".git/**" = "write"`). Codex's
|
|
17531
18162
|
* `:workspace` baseline makes `.git` read-only, which denies basic git
|
|
17532
18163
|
* workflows (commit/stage writes to `.git/index`, `.git/objects`, refs,
|
|
17533
|
-
* logs
|
|
17534
|
-
*
|
|
17535
|
-
*
|
|
18164
|
+
* logs; everyday commands like `git remote add` or `git push -u` write to
|
|
18165
|
+
* `.git/config`), so the carve-out is emitted by default. Defaults to
|
|
18166
|
+
* `true`; only an explicit `false` suppresses it. Like
|
|
18167
|
+
* `base_permission_profile` it is consumed by the profile builder, not
|
|
18168
|
+
* written as a top-level config key.
|
|
17536
18169
|
*
|
|
17537
18170
|
* Two surfaces are deliberately NOT authorable here so the override can never
|
|
17538
18171
|
* clobber a feature-owned key: `mcp_servers.*` per-MCP gating is owned by the
|
|
@@ -19529,15 +20162,13 @@ const RULESYNC_PROFILE_NAME = "rulesync";
|
|
|
19529
20162
|
const CODEX_WORKSPACE_ROOTS_KEY = ":workspace_roots";
|
|
19530
20163
|
const CODEX_WORKSPACE_BASELINE = ":workspace";
|
|
19531
20164
|
const CODEX_READ_ONLY_BASELINE = ":read-only";
|
|
19532
|
-
const
|
|
20165
|
+
const CODEX_DANGER_FULL_ACCESS_BASELINE = ":danger-full-access";
|
|
20166
|
+
const CODEX_EXTENDABLE_BASELINES = new Set(CODEX_EXTENDABLE_BASELINE_PROFILES);
|
|
19533
20167
|
const CODEX_DEFAULT_APPROVAL_POLICY = "on-request";
|
|
19534
20168
|
const CODEX_DEFAULT_APPROVALS_REVIEWER = "auto_review";
|
|
19535
20169
|
const CODEX_GLOB_SCAN_MAX_DEPTH = 8;
|
|
19536
20170
|
const CODEX_MINIMAL_KEY = ":minimal";
|
|
19537
|
-
const CODEX_GIT_WRITE_RULES = {
|
|
19538
|
-
".git/**": "write",
|
|
19539
|
-
".git/config": "read"
|
|
19540
|
-
};
|
|
20171
|
+
const CODEX_GIT_WRITE_RULES = { ".git/**": "write" };
|
|
19541
20172
|
const GLOBAL_WILDCARD_DOMAIN = "*";
|
|
19542
20173
|
var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
19543
20174
|
static getSettablePaths(_options = {}) {
|
|
@@ -19565,8 +20196,40 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
|
19565
20196
|
const filePath = (0, node_path.join)(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
19566
20197
|
const existingContent = await readFileContentOrNull(filePath) ?? "";
|
|
19567
20198
|
const existing = toMutableTable(smol_toml.parse(existingContent || smol_toml.stringify({})));
|
|
20199
|
+
const canonicalConfig = rulesyncPermissions.getJson();
|
|
20200
|
+
if (canonicalConfig.codexcli?.base_permission_profile === CODEX_DANGER_FULL_ACCESS_BASELINE) {
|
|
20201
|
+
const ignoredCategories = Object.entries(canonicalConfig.permission).filter(([category, rules]) => category !== "bash" && Object.keys(rules).length > 0).map(([category]) => category);
|
|
20202
|
+
if (ignoredCategories.length > 0) logger?.warn(`Codex CLI baseline ":danger-full-access" removes the sandbox, so canonical ${ignoredCategories.join("/")} rules are not representable and are ignored for Codex CLI.`);
|
|
20203
|
+
const permissionsTable = toMutableTable(existing.permissions);
|
|
20204
|
+
if (permissionsTable[RULESYNC_PROFILE_NAME] !== void 0) {
|
|
20205
|
+
logger?.warn(`Codex CLI baseline ":danger-full-access" prunes the managed "[permissions.${RULESYNC_PROFILE_NAME}]" profile; any hand-written keys inside it (e.g. network settings) are removed. Move them to a sibling profile or re-add them after switching baselines.`);
|
|
20206
|
+
delete permissionsTable[RULESYNC_PROFILE_NAME];
|
|
20207
|
+
}
|
|
20208
|
+
const overridePatch = computeCodexcliOverridePatch({
|
|
20209
|
+
existing,
|
|
20210
|
+
override: canonicalConfig.codexcli,
|
|
20211
|
+
logger
|
|
20212
|
+
});
|
|
20213
|
+
return new CodexcliPermissions({
|
|
20214
|
+
outputRoot,
|
|
20215
|
+
relativeDirPath: paths.relativeDirPath,
|
|
20216
|
+
relativeFilePath: paths.relativeFilePath,
|
|
20217
|
+
fileContent: applySharedConfigPatch({
|
|
20218
|
+
fileKey: sharedConfigFileKey(paths),
|
|
20219
|
+
feature: "permissions",
|
|
20220
|
+
existingContent,
|
|
20221
|
+
patch: {
|
|
20222
|
+
permissions: Object.keys(permissionsTable).length > 0 ? permissionsTable : void 0,
|
|
20223
|
+
default_permissions: CODEX_DANGER_FULL_ACCESS_BASELINE,
|
|
20224
|
+
...overridePatch
|
|
20225
|
+
},
|
|
20226
|
+
filePath
|
|
20227
|
+
}),
|
|
20228
|
+
validate
|
|
20229
|
+
});
|
|
20230
|
+
}
|
|
19568
20231
|
const newProfile = convertRulesyncToCodexProfile({
|
|
19569
|
-
config:
|
|
20232
|
+
config: canonicalConfig,
|
|
19570
20233
|
logger
|
|
19571
20234
|
});
|
|
19572
20235
|
const permissionsTable = toMutableTable(existing.permissions);
|
|
@@ -19627,6 +20290,7 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
|
19627
20290
|
});
|
|
19628
20291
|
const override = extractCodexcliOverride(table);
|
|
19629
20292
|
if (typeof profile?.extends === "string" && CODEX_EXTENDABLE_BASELINES.has(profile.extends)) override.base_permission_profile = profile.extends;
|
|
20293
|
+
if (defaultProfile === CODEX_DANGER_FULL_ACCESS_BASELINE) override.base_permission_profile = CODEX_DANGER_FULL_ACCESS_BASELINE;
|
|
19630
20294
|
const result = Object.keys(override).length > 0 ? {
|
|
19631
20295
|
...config,
|
|
19632
20296
|
codexcli: override
|
|
@@ -19682,16 +20346,10 @@ function convertRulesyncToCodexProfile({ config, logger }) {
|
|
|
19682
20346
|
const filesystem = { [CODEX_MINIMAL_KEY]: "read" };
|
|
19683
20347
|
const workspaceRootFilesystem = {};
|
|
19684
20348
|
const domains = {};
|
|
20349
|
+
const filesystemCategoryRules = {};
|
|
19685
20350
|
for (const [toolName, rules] of Object.entries(config.permission)) {
|
|
19686
20351
|
if (toolName === "read" || toolName === "edit" || toolName === "write") {
|
|
19687
|
-
|
|
19688
|
-
for (const [pattern, action] of Object.entries(rules)) addFilesystemRule({
|
|
19689
|
-
filesystem,
|
|
19690
|
-
workspaceRootFilesystem,
|
|
19691
|
-
pattern,
|
|
19692
|
-
access: mapAction(action),
|
|
19693
|
-
logger
|
|
19694
|
-
});
|
|
20352
|
+
filesystemCategoryRules[toolName] = rules;
|
|
19695
20353
|
continue;
|
|
19696
20354
|
}
|
|
19697
20355
|
if (toolName === "webfetch") {
|
|
@@ -19704,6 +20362,16 @@ function convertRulesyncToCodexProfile({ config, logger }) {
|
|
|
19704
20362
|
}
|
|
19705
20363
|
logger?.warn(`Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`);
|
|
19706
20364
|
}
|
|
20365
|
+
for (const [pattern, access] of mergeFilesystemCategoryRules({
|
|
20366
|
+
categoryRules: filesystemCategoryRules,
|
|
20367
|
+
logger
|
|
20368
|
+
})) addFilesystemRule({
|
|
20369
|
+
filesystem,
|
|
20370
|
+
workspaceRootFilesystem,
|
|
20371
|
+
pattern,
|
|
20372
|
+
access,
|
|
20373
|
+
logger
|
|
20374
|
+
});
|
|
19707
20375
|
applyDefaultGitWriteRules({
|
|
19708
20376
|
config,
|
|
19709
20377
|
filesystem,
|
|
@@ -19984,6 +20652,67 @@ function mapReadAction(action) {
|
|
|
19984
20652
|
function mapWriteAction(action) {
|
|
19985
20653
|
return action === "allow" ? "write" : "deny";
|
|
19986
20654
|
}
|
|
20655
|
+
/**
|
|
20656
|
+
* Merge the canonical read/edit/write category rules into one Codex access
|
|
20657
|
+
* level per path pattern (Codex models a single `deny` < `read` < `write`
|
|
20658
|
+
* level, with no `ask`).
|
|
20659
|
+
*
|
|
20660
|
+
* - `edit` and `write` collapse onto Codex's write side; when both carry the
|
|
20661
|
+
* same pattern, the more restrictive action wins (`deny` > `ask` > `allow`).
|
|
20662
|
+
* - `read: allow` + write-side `allow` → `"write"`.
|
|
20663
|
+
* - `read: allow` + write-side non-allow → `"read"` (readable but not
|
|
20664
|
+
* writable — exactly what Codex's `"read"` level expresses).
|
|
20665
|
+
* - `read` non-allow → `"deny"` regardless of the write side; a contradictory
|
|
20666
|
+
* write-side `allow` (unreadable but writable is not expressible in Codex)
|
|
20667
|
+
* is warned about.
|
|
20668
|
+
* - Single-category patterns keep the existing mapReadAction/mapWriteAction
|
|
20669
|
+
* mappings.
|
|
20670
|
+
*
|
|
20671
|
+
* Iteration order is read → edit → write with first-seen pattern order, so
|
|
20672
|
+
* the emitted table is stable regardless of the authored category order.
|
|
20673
|
+
* Note the merge is one-way: `"{path}" = "read"` imports back as
|
|
20674
|
+
* `read: allow` only (the explicit write-side deny is implied by Codex's
|
|
20675
|
+
* access level and not re-materialized).
|
|
20676
|
+
*/
|
|
20677
|
+
function mergeFilesystemCategoryRules({ categoryRules, logger }) {
|
|
20678
|
+
const readRules = categoryRules.read ?? {};
|
|
20679
|
+
const writeSideRestrictiveness = {
|
|
20680
|
+
deny: 2,
|
|
20681
|
+
ask: 1,
|
|
20682
|
+
allow: 0
|
|
20683
|
+
};
|
|
20684
|
+
const writeSideRules = {};
|
|
20685
|
+
for (const category of ["edit", "write"]) for (const [pattern, action] of Object.entries(categoryRules[category] ?? {})) {
|
|
20686
|
+
const existing = writeSideRules[pattern];
|
|
20687
|
+
if (existing === void 0 || writeSideRestrictiveness[action] > writeSideRestrictiveness[existing]) writeSideRules[pattern] = action;
|
|
20688
|
+
}
|
|
20689
|
+
const patterns = [];
|
|
20690
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20691
|
+
for (const pattern of [...Object.keys(readRules), ...Object.keys(writeSideRules)]) if (!seen.has(pattern)) {
|
|
20692
|
+
seen.add(pattern);
|
|
20693
|
+
patterns.push(pattern);
|
|
20694
|
+
}
|
|
20695
|
+
const merged = [];
|
|
20696
|
+
for (const pattern of patterns) {
|
|
20697
|
+
const readAction = readRules[pattern];
|
|
20698
|
+
const writeAction = writeSideRules[pattern];
|
|
20699
|
+
if (readAction === void 0) {
|
|
20700
|
+
merged.push([pattern, mapWriteAction(writeAction)]);
|
|
20701
|
+
continue;
|
|
20702
|
+
}
|
|
20703
|
+
if (writeAction === void 0) {
|
|
20704
|
+
merged.push([pattern, mapReadAction(readAction)]);
|
|
20705
|
+
continue;
|
|
20706
|
+
}
|
|
20707
|
+
if (readAction === "allow") {
|
|
20708
|
+
merged.push([pattern, writeAction === "allow" ? "write" : "read"]);
|
|
20709
|
+
continue;
|
|
20710
|
+
}
|
|
20711
|
+
if (writeAction === "allow") logger?.warn(`Codex CLI cannot express "writable but not readable": pattern "${pattern}" has read: ${readAction} and a write-side allow. Emitting "deny".`);
|
|
20712
|
+
merged.push([pattern, "deny"]);
|
|
20713
|
+
}
|
|
20714
|
+
return merged;
|
|
20715
|
+
}
|
|
19987
20716
|
function buildCodexBashRulesContent(config) {
|
|
19988
20717
|
const bashRules = config.permission.bash ?? {};
|
|
19989
20718
|
const entries = Object.entries(bashRules);
|
|
@@ -20935,7 +21664,7 @@ function convertRulesyncToGoosePermissionConfig({ config, logger }) {
|
|
|
20935
21664
|
function convertGoosePermissionConfigToRulesync(userPermission) {
|
|
20936
21665
|
const permission = {};
|
|
20937
21666
|
for (const key of GOOSE_PERMISSION_LIST_KEYS) {
|
|
20938
|
-
const toolNames = isStringArray(userPermission[key]) ? userPermission[key] : [];
|
|
21667
|
+
const toolNames = isStringArray$1(userPermission[key]) ? userPermission[key] : [];
|
|
20939
21668
|
const action = GOOSE_LIST_TO_ACTION[key];
|
|
20940
21669
|
for (const toolName of toolNames) {
|
|
20941
21670
|
const category = GOOSE_TO_RULESYNC_TOOL_NAME[toolName] ?? toolName;
|
|
@@ -21175,7 +21904,7 @@ const ACTION_RANK = {
|
|
|
21175
21904
|
* (mirrors the Cursor adapter's preservation of unmanaged types).
|
|
21176
21905
|
*/
|
|
21177
21906
|
function unmanagedEntries(existingPermission, key) {
|
|
21178
|
-
return (isStringArray(existingPermission[key]) ? existingPermission[key] : []).filter((entry) => parseGrokEntry(entry) === null);
|
|
21907
|
+
return (isStringArray$1(existingPermission[key]) ? existingPermission[key] : []).filter((entry) => parseGrokEntry(entry) === null);
|
|
21179
21908
|
}
|
|
21180
21909
|
/**
|
|
21181
21910
|
* Bucket canonical rules into Grok's `[permission]` allow/deny/ask arrays of
|
|
@@ -21216,9 +21945,9 @@ function buildGrokPermissionArrays(config, existingPermission, logger) {
|
|
|
21216
21945
|
* arrays resolves to the strictest action.
|
|
21217
21946
|
*/
|
|
21218
21947
|
function parseGrokPermissionArrays(permission) {
|
|
21219
|
-
const allow = isStringArray(permission.allow) ? permission.allow : void 0;
|
|
21220
|
-
const deny = isStringArray(permission.deny) ? permission.deny : void 0;
|
|
21221
|
-
const ask = isStringArray(permission.ask) ? permission.ask : void 0;
|
|
21948
|
+
const allow = isStringArray$1(permission.allow) ? permission.allow : void 0;
|
|
21949
|
+
const deny = isStringArray$1(permission.deny) ? permission.deny : void 0;
|
|
21950
|
+
const ask = isStringArray$1(permission.ask) ? permission.ask : void 0;
|
|
21222
21951
|
if ((allow?.length ?? 0) + (deny?.length ?? 0) + (ask?.length ?? 0) === 0) return null;
|
|
21223
21952
|
const result = {};
|
|
21224
21953
|
const apply = (entries, action) => {
|
|
@@ -22999,7 +23728,7 @@ function convertRovodevToolPermissionsToRulesync(toolPermissions) {
|
|
|
22999
23728
|
permission[category][CATCH_ALL_PATTERN$1] = value;
|
|
23000
23729
|
}
|
|
23001
23730
|
}
|
|
23002
|
-
if (isStringArray(toolPermissions.allowedExternalPaths)) for (const path of toolPermissions.allowedExternalPaths) {
|
|
23731
|
+
if (isStringArray$1(toolPermissions.allowedExternalPaths)) for (const path of toolPermissions.allowedExternalPaths) {
|
|
23003
23732
|
permission.read ??= {};
|
|
23004
23733
|
permission.read[path] = "allow";
|
|
23005
23734
|
}
|
|
@@ -23559,8 +24288,8 @@ var WarpPermissions = class WarpPermissions extends ToolPermissions {
|
|
|
23559
24288
|
const agents = isRecord(settings.agents) ? settings.agents : {};
|
|
23560
24289
|
const profiles = isRecord(agents.profiles) ? agents.profiles : {};
|
|
23561
24290
|
const config = convertWarpToRulesyncPermissions({
|
|
23562
|
-
allow: isStringArray(profiles[ALLOWLIST_KEY]) ? profiles[ALLOWLIST_KEY] : [],
|
|
23563
|
-
deny: isStringArray(profiles[DENYLIST_KEY]) ? profiles[DENYLIST_KEY] : []
|
|
24291
|
+
allow: isStringArray$1(profiles[ALLOWLIST_KEY]) ? profiles[ALLOWLIST_KEY] : [],
|
|
24292
|
+
deny: isStringArray$1(profiles[DENYLIST_KEY]) ? profiles[DENYLIST_KEY] : []
|
|
23564
24293
|
});
|
|
23565
24294
|
const warpOverride = {};
|
|
23566
24295
|
for (const key of WARP_OVERRIDE_KEYS) if (profiles[key] !== void 0) warpOverride[key] = profiles[key];
|
|
@@ -24140,9 +24869,6 @@ var PermissionsProcessor = class extends FeatureProcessor {
|
|
|
24140
24869
|
}
|
|
24141
24870
|
};
|
|
24142
24871
|
//#endregion
|
|
24143
|
-
//#region src/constants/general.ts
|
|
24144
|
-
const SKILL_FILE_NAME = "SKILL.md";
|
|
24145
|
-
//#endregion
|
|
24146
24872
|
//#region src/types/ai-dir.ts
|
|
24147
24873
|
var AiDir = class {
|
|
24148
24874
|
/**
|
|
@@ -24343,10 +25069,10 @@ var ToolSkill = class extends AiDir {
|
|
|
24343
25069
|
const settablePaths = getSettablePaths({ global });
|
|
24344
25070
|
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
24345
25071
|
const skillDirPath = (0, node_path.join)(outputRoot, actualRelativeDirPath, dirName);
|
|
24346
|
-
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME);
|
|
24347
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25072
|
+
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1);
|
|
25073
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24348
25074
|
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24349
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25075
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24350
25076
|
return {
|
|
24351
25077
|
outputRoot,
|
|
24352
25078
|
relativeDirPath: actualRelativeDirPath,
|
|
@@ -24388,7 +25114,7 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
24388
25114
|
relativeDirPath,
|
|
24389
25115
|
dirName,
|
|
24390
25116
|
mainFile: {
|
|
24391
|
-
name: SKILL_FILE_NAME,
|
|
25117
|
+
name: SKILL_FILE_NAME$1,
|
|
24392
25118
|
body,
|
|
24393
25119
|
frontmatter: { ...frontmatter }
|
|
24394
25120
|
},
|
|
@@ -24446,12 +25172,12 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
24446
25172
|
const settablePaths = this.getSettablePaths();
|
|
24447
25173
|
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
24448
25174
|
const skillDirPath = (0, node_path.join)(outputRoot, actualRelativeDirPath, dirName);
|
|
24449
|
-
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME);
|
|
24450
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25175
|
+
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1);
|
|
25176
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24451
25177
|
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24452
25178
|
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
24453
25179
|
if (!result.success) throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
24454
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25180
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24455
25181
|
return {
|
|
24456
25182
|
outputRoot,
|
|
24457
25183
|
relativeDirPath: actualRelativeDirPath,
|
|
@@ -24661,7 +25387,7 @@ var RulesyncSkill = class RulesyncSkill extends AiDir {
|
|
|
24661
25387
|
relativeDirPath,
|
|
24662
25388
|
dirName,
|
|
24663
25389
|
mainFile: {
|
|
24664
|
-
name: SKILL_FILE_NAME,
|
|
25390
|
+
name: SKILL_FILE_NAME$1,
|
|
24665
25391
|
body,
|
|
24666
25392
|
frontmatter: { ...frontmatter }
|
|
24667
25393
|
},
|
|
@@ -24696,13 +25422,13 @@ var RulesyncSkill = class RulesyncSkill extends AiDir {
|
|
|
24696
25422
|
}
|
|
24697
25423
|
static async fromDir({ outputRoot = process.cwd(), relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName, global = false }) {
|
|
24698
25424
|
const skillDirPath = (0, node_path.join)(outputRoot, relativeDirPath, dirName);
|
|
24699
|
-
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME);
|
|
24700
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25425
|
+
const skillFilePath = (0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1);
|
|
25426
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24701
25427
|
const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24702
25428
|
if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${skillFilePath}. Rulesync files must begin with a YAML frontmatter block delimited by '---'.`);
|
|
24703
25429
|
const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
|
|
24704
25430
|
if (!result.success) throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
24705
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25431
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24706
25432
|
return new RulesyncSkill({
|
|
24707
25433
|
outputRoot,
|
|
24708
25434
|
relativeDirPath,
|
|
@@ -24742,7 +25468,7 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24742
25468
|
relativeDirPath,
|
|
24743
25469
|
dirName,
|
|
24744
25470
|
mainFile: {
|
|
24745
|
-
name: SKILL_FILE_NAME,
|
|
25471
|
+
name: SKILL_FILE_NAME$1,
|
|
24746
25472
|
body,
|
|
24747
25473
|
frontmatter: { ...frontmatter }
|
|
24748
25474
|
},
|
|
@@ -24769,7 +25495,7 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24769
25495
|
validate() {
|
|
24770
25496
|
if (!this.mainFile) return {
|
|
24771
25497
|
success: false,
|
|
24772
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25498
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
24773
25499
|
};
|
|
24774
25500
|
const result = RovodevSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
24775
25501
|
if (!result.success) return {
|
|
@@ -24845,10 +25571,10 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24845
25571
|
const result = RovodevSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
24846
25572
|
if (!result.success) {
|
|
24847
25573
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
24848
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25574
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
24849
25575
|
}
|
|
24850
25576
|
if (result.data.name !== loaded.dirName) {
|
|
24851
|
-
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
25577
|
+
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
24852
25578
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
24853
25579
|
}
|
|
24854
25580
|
return new RovodevSkill({
|
|
@@ -25013,7 +25739,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
25013
25739
|
relativeDirPath,
|
|
25014
25740
|
dirName,
|
|
25015
25741
|
mainFile: {
|
|
25016
|
-
name: SKILL_FILE_NAME,
|
|
25742
|
+
name: SKILL_FILE_NAME$1,
|
|
25017
25743
|
body,
|
|
25018
25744
|
frontmatter: { ...frontmatter }
|
|
25019
25745
|
},
|
|
@@ -25037,7 +25763,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
25037
25763
|
validate() {
|
|
25038
25764
|
if (!this.mainFile) return {
|
|
25039
25765
|
success: false,
|
|
25040
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25766
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25041
25767
|
};
|
|
25042
25768
|
const result = AgentsSkillsSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25043
25769
|
if (!result.success) return {
|
|
@@ -25109,7 +25835,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
25109
25835
|
const result = AgentsSkillsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25110
25836
|
if (!result.success) {
|
|
25111
25837
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25112
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25838
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25113
25839
|
}
|
|
25114
25840
|
return new this({
|
|
25115
25841
|
outputRoot: loaded.outputRoot,
|
|
@@ -25166,7 +25892,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25166
25892
|
relativeDirPath,
|
|
25167
25893
|
dirName,
|
|
25168
25894
|
mainFile: {
|
|
25169
|
-
name: SKILL_FILE_NAME,
|
|
25895
|
+
name: SKILL_FILE_NAME$1,
|
|
25170
25896
|
body,
|
|
25171
25897
|
frontmatter: { ...frontmatter }
|
|
25172
25898
|
},
|
|
@@ -25191,7 +25917,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25191
25917
|
validate() {
|
|
25192
25918
|
if (!this.mainFile) return {
|
|
25193
25919
|
success: false,
|
|
25194
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25920
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25195
25921
|
};
|
|
25196
25922
|
const result = AiassistantSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25197
25923
|
if (!result.success) return {
|
|
@@ -25251,7 +25977,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25251
25977
|
const result = AiassistantSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25252
25978
|
if (!result.success) {
|
|
25253
25979
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25254
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25980
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25255
25981
|
}
|
|
25256
25982
|
return new AiassistantSkill({
|
|
25257
25983
|
outputRoot: loaded.outputRoot,
|
|
@@ -25302,7 +26028,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25302
26028
|
relativeDirPath,
|
|
25303
26029
|
dirName,
|
|
25304
26030
|
mainFile: {
|
|
25305
|
-
name: SKILL_FILE_NAME,
|
|
26031
|
+
name: SKILL_FILE_NAME$1,
|
|
25306
26032
|
body,
|
|
25307
26033
|
frontmatter: { ...frontmatter }
|
|
25308
26034
|
},
|
|
@@ -25326,7 +26052,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25326
26052
|
validate() {
|
|
25327
26053
|
if (!this.mainFile) return {
|
|
25328
26054
|
success: false,
|
|
25329
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26055
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25330
26056
|
};
|
|
25331
26057
|
const result = AmpSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25332
26058
|
if (!result.success) return {
|
|
@@ -25386,7 +26112,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25386
26112
|
const result = AmpSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25387
26113
|
if (!result.success) {
|
|
25388
26114
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25389
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26115
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25390
26116
|
}
|
|
25391
26117
|
return new AmpSkill({
|
|
25392
26118
|
outputRoot: loaded.outputRoot,
|
|
@@ -25442,7 +26168,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25442
26168
|
relativeDirPath,
|
|
25443
26169
|
dirName,
|
|
25444
26170
|
mainFile: {
|
|
25445
|
-
name: SKILL_FILE_NAME,
|
|
26171
|
+
name: SKILL_FILE_NAME$1,
|
|
25446
26172
|
body,
|
|
25447
26173
|
frontmatter: { ...frontmatter }
|
|
25448
26174
|
},
|
|
@@ -25475,7 +26201,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25475
26201
|
validate() {
|
|
25476
26202
|
if (this.mainFile === void 0) return {
|
|
25477
26203
|
success: false,
|
|
25478
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26204
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25479
26205
|
};
|
|
25480
26206
|
const result = AntigravitySkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25481
26207
|
if (!result.success) return {
|
|
@@ -25535,7 +26261,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25535
26261
|
const result = AntigravitySkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25536
26262
|
if (!result.success) {
|
|
25537
26263
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25538
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26264
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25539
26265
|
}
|
|
25540
26266
|
return new this({
|
|
25541
26267
|
outputRoot: loaded.outputRoot,
|
|
@@ -25619,7 +26345,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25619
26345
|
relativeDirPath,
|
|
25620
26346
|
dirName,
|
|
25621
26347
|
mainFile: {
|
|
25622
|
-
name: SKILL_FILE_NAME,
|
|
26348
|
+
name: SKILL_FILE_NAME$1,
|
|
25623
26349
|
body,
|
|
25624
26350
|
frontmatter: { ...frontmatter }
|
|
25625
26351
|
},
|
|
@@ -25646,7 +26372,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25646
26372
|
validate() {
|
|
25647
26373
|
if (this.mainFile === void 0) return {
|
|
25648
26374
|
success: false,
|
|
25649
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26375
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25650
26376
|
};
|
|
25651
26377
|
const result = AugmentcodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25652
26378
|
if (!result.success) return {
|
|
@@ -25706,7 +26432,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25706
26432
|
const result = AugmentcodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25707
26433
|
if (!result.success) {
|
|
25708
26434
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25709
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26435
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25710
26436
|
}
|
|
25711
26437
|
return new AugmentcodeSkill({
|
|
25712
26438
|
outputRoot: loaded.outputRoot,
|
|
@@ -25847,7 +26573,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25847
26573
|
relativeDirPath,
|
|
25848
26574
|
dirName,
|
|
25849
26575
|
mainFile: {
|
|
25850
|
-
name: SKILL_FILE_NAME,
|
|
26576
|
+
name: SKILL_FILE_NAME$1,
|
|
25851
26577
|
body,
|
|
25852
26578
|
frontmatter: { ...frontmatter }
|
|
25853
26579
|
},
|
|
@@ -25874,7 +26600,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25874
26600
|
validate() {
|
|
25875
26601
|
if (this.mainFile === void 0) return {
|
|
25876
26602
|
success: false,
|
|
25877
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26603
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25878
26604
|
};
|
|
25879
26605
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25880
26606
|
if (!result.success) return {
|
|
@@ -25962,7 +26688,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25962
26688
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25963
26689
|
if (!result.success) {
|
|
25964
26690
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25965
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26691
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25966
26692
|
}
|
|
25967
26693
|
return new ClaudecodeSkill({
|
|
25968
26694
|
outputRoot: loaded.outputRoot,
|
|
@@ -26008,7 +26734,7 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
26008
26734
|
relativeDirPath,
|
|
26009
26735
|
dirName,
|
|
26010
26736
|
mainFile: {
|
|
26011
|
-
name: SKILL_FILE_NAME,
|
|
26737
|
+
name: SKILL_FILE_NAME$1,
|
|
26012
26738
|
body,
|
|
26013
26739
|
frontmatter: { ...frontmatter }
|
|
26014
26740
|
},
|
|
@@ -26032,7 +26758,7 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
26032
26758
|
validate() {
|
|
26033
26759
|
if (!this.mainFile) return {
|
|
26034
26760
|
success: false,
|
|
26035
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26761
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26036
26762
|
};
|
|
26037
26763
|
const result = ClineSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26038
26764
|
if (!result.success) return {
|
|
@@ -26096,10 +26822,10 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
26096
26822
|
const result = ClineSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26097
26823
|
if (!result.success) {
|
|
26098
26824
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26099
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26825
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26100
26826
|
}
|
|
26101
26827
|
if (result.data.name !== loaded.dirName) {
|
|
26102
|
-
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
26828
|
+
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
26103
26829
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
26104
26830
|
}
|
|
26105
26831
|
return new ClineSkill({
|
|
@@ -26213,7 +26939,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26213
26939
|
relativeDirPath,
|
|
26214
26940
|
dirName,
|
|
26215
26941
|
mainFile: {
|
|
26216
|
-
name: SKILL_FILE_NAME,
|
|
26942
|
+
name: SKILL_FILE_NAME$1,
|
|
26217
26943
|
body,
|
|
26218
26944
|
frontmatter: { ...frontmatter }
|
|
26219
26945
|
},
|
|
@@ -26237,7 +26963,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26237
26963
|
validate() {
|
|
26238
26964
|
if (!this.mainFile) return {
|
|
26239
26965
|
success: false,
|
|
26240
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26966
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26241
26967
|
};
|
|
26242
26968
|
const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26243
26969
|
if (!result.success) return {
|
|
@@ -26315,7 +27041,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26315
27041
|
const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26316
27042
|
if (!result.success) {
|
|
26317
27043
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26318
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27044
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26319
27045
|
}
|
|
26320
27046
|
return new CodexCliSkill({
|
|
26321
27047
|
outputRoot: loaded.outputRoot,
|
|
@@ -26367,7 +27093,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26367
27093
|
relativeDirPath,
|
|
26368
27094
|
dirName,
|
|
26369
27095
|
mainFile: {
|
|
26370
|
-
name: SKILL_FILE_NAME,
|
|
27096
|
+
name: SKILL_FILE_NAME$1,
|
|
26371
27097
|
body,
|
|
26372
27098
|
frontmatter: { ...frontmatter }
|
|
26373
27099
|
},
|
|
@@ -26392,7 +27118,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26392
27118
|
validate() {
|
|
26393
27119
|
if (!this.mainFile) return {
|
|
26394
27120
|
success: false,
|
|
26395
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27121
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26396
27122
|
};
|
|
26397
27123
|
const result = CopilotSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26398
27124
|
if (!result.success) return {
|
|
@@ -26459,7 +27185,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26459
27185
|
const result = CopilotSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26460
27186
|
if (!result.success) {
|
|
26461
27187
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26462
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27188
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26463
27189
|
}
|
|
26464
27190
|
return new CopilotSkill({
|
|
26465
27191
|
outputRoot: loaded.outputRoot,
|
|
@@ -26513,7 +27239,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26513
27239
|
relativeDirPath,
|
|
26514
27240
|
dirName,
|
|
26515
27241
|
mainFile: {
|
|
26516
|
-
name: SKILL_FILE_NAME,
|
|
27242
|
+
name: SKILL_FILE_NAME$1,
|
|
26517
27243
|
body,
|
|
26518
27244
|
frontmatter: { ...frontmatter }
|
|
26519
27245
|
},
|
|
@@ -26538,7 +27264,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26538
27264
|
validate() {
|
|
26539
27265
|
if (!this.mainFile) return {
|
|
26540
27266
|
success: false,
|
|
26541
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27267
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26542
27268
|
};
|
|
26543
27269
|
const result = CopilotcliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26544
27270
|
if (!result.success) return {
|
|
@@ -26607,7 +27333,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26607
27333
|
const result = CopilotcliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26608
27334
|
if (!result.success) {
|
|
26609
27335
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26610
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27336
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26611
27337
|
}
|
|
26612
27338
|
return new CopilotcliSkill({
|
|
26613
27339
|
outputRoot: loaded.outputRoot,
|
|
@@ -26657,7 +27383,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26657
27383
|
relativeDirPath,
|
|
26658
27384
|
dirName,
|
|
26659
27385
|
mainFile: {
|
|
26660
|
-
name: SKILL_FILE_NAME,
|
|
27386
|
+
name: SKILL_FILE_NAME$1,
|
|
26661
27387
|
body,
|
|
26662
27388
|
frontmatter: { ...frontmatter }
|
|
26663
27389
|
},
|
|
@@ -26681,7 +27407,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26681
27407
|
validate() {
|
|
26682
27408
|
if (!this.mainFile) return {
|
|
26683
27409
|
success: false,
|
|
26684
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27410
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26685
27411
|
};
|
|
26686
27412
|
const result = CursorSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26687
27413
|
if (!result.success) return {
|
|
@@ -26755,7 +27481,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26755
27481
|
const result = CursorSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26756
27482
|
if (!result.success) {
|
|
26757
27483
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26758
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27484
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26759
27485
|
}
|
|
26760
27486
|
return new CursorSkill({
|
|
26761
27487
|
outputRoot: loaded.outputRoot,
|
|
@@ -26802,7 +27528,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26802
27528
|
relativeDirPath,
|
|
26803
27529
|
dirName,
|
|
26804
27530
|
mainFile: {
|
|
26805
|
-
name: SKILL_FILE_NAME,
|
|
27531
|
+
name: SKILL_FILE_NAME$1,
|
|
26806
27532
|
body,
|
|
26807
27533
|
frontmatter: { ...frontmatter }
|
|
26808
27534
|
},
|
|
@@ -26826,7 +27552,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26826
27552
|
validate() {
|
|
26827
27553
|
if (!this.mainFile) return {
|
|
26828
27554
|
success: false,
|
|
26829
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27555
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26830
27556
|
};
|
|
26831
27557
|
const result = DeepagentsSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26832
27558
|
if (!result.success) return {
|
|
@@ -26902,7 +27628,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26902
27628
|
const result = DeepagentsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26903
27629
|
if (!result.success) {
|
|
26904
27630
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26905
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27631
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26906
27632
|
}
|
|
26907
27633
|
return new DeepagentsSkill({
|
|
26908
27634
|
outputRoot: loaded.outputRoot,
|
|
@@ -26953,7 +27679,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
26953
27679
|
relativeDirPath,
|
|
26954
27680
|
dirName,
|
|
26955
27681
|
mainFile: {
|
|
26956
|
-
name: SKILL_FILE_NAME,
|
|
27682
|
+
name: SKILL_FILE_NAME$1,
|
|
26957
27683
|
body,
|
|
26958
27684
|
frontmatter: { ...frontmatter }
|
|
26959
27685
|
},
|
|
@@ -26978,7 +27704,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
26978
27704
|
validate() {
|
|
26979
27705
|
if (!this.mainFile) return {
|
|
26980
27706
|
success: false,
|
|
26981
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27707
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26982
27708
|
};
|
|
26983
27709
|
const result = DevinSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26984
27710
|
if (!result.success) return {
|
|
@@ -27030,6 +27756,18 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
27030
27756
|
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
27031
27757
|
return targets.includes("*") || targets.includes("devin");
|
|
27032
27758
|
}
|
|
27759
|
+
/**
|
|
27760
|
+
* Commands are emitted into this same skills tree as `<slug>/SKILL.md`
|
|
27761
|
+
* (see `DevinCommand`), so a directory matching a current rulesync command
|
|
27762
|
+
* slug is owned by the commands feature: it must not be imported as a
|
|
27763
|
+
* skill nor deleted as an orphan skill.
|
|
27764
|
+
*/
|
|
27765
|
+
static async isDirOwned({ dirName, inputRoot }) {
|
|
27766
|
+
return !await rulesyncCommandSlugExists({
|
|
27767
|
+
inputRoot,
|
|
27768
|
+
dirName
|
|
27769
|
+
});
|
|
27770
|
+
}
|
|
27033
27771
|
static async fromDir(params) {
|
|
27034
27772
|
const loaded = await this.loadSkillDirContent({
|
|
27035
27773
|
...params,
|
|
@@ -27038,7 +27776,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
27038
27776
|
const result = DevinSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27039
27777
|
if (!result.success) {
|
|
27040
27778
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27041
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27779
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27042
27780
|
}
|
|
27043
27781
|
return new DevinSkill({
|
|
27044
27782
|
outputRoot: loaded.outputRoot,
|
|
@@ -27090,7 +27828,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27090
27828
|
relativeDirPath,
|
|
27091
27829
|
dirName,
|
|
27092
27830
|
mainFile: {
|
|
27093
|
-
name: SKILL_FILE_NAME,
|
|
27831
|
+
name: SKILL_FILE_NAME$1,
|
|
27094
27832
|
body,
|
|
27095
27833
|
frontmatter: { ...frontmatter }
|
|
27096
27834
|
},
|
|
@@ -27114,7 +27852,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27114
27852
|
validate() {
|
|
27115
27853
|
if (this.mainFile === void 0) return {
|
|
27116
27854
|
success: false,
|
|
27117
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27855
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27118
27856
|
};
|
|
27119
27857
|
const result = FactorydroidSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27120
27858
|
if (!result.success) return {
|
|
@@ -27189,7 +27927,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27189
27927
|
const result = FactorydroidSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27190
27928
|
if (!result.success) {
|
|
27191
27929
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27192
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27930
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27193
27931
|
}
|
|
27194
27932
|
return new FactorydroidSkill({
|
|
27195
27933
|
outputRoot: loaded.outputRoot,
|
|
@@ -27236,7 +27974,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27236
27974
|
relativeDirPath,
|
|
27237
27975
|
dirName,
|
|
27238
27976
|
mainFile: {
|
|
27239
|
-
name: SKILL_FILE_NAME,
|
|
27977
|
+
name: SKILL_FILE_NAME$1,
|
|
27240
27978
|
body,
|
|
27241
27979
|
frontmatter: { ...frontmatter }
|
|
27242
27980
|
},
|
|
@@ -27261,7 +27999,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27261
27999
|
validate() {
|
|
27262
28000
|
if (!this.mainFile) return {
|
|
27263
28001
|
success: false,
|
|
27264
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28002
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27265
28003
|
};
|
|
27266
28004
|
const result = GooseSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27267
28005
|
if (!result.success) return {
|
|
@@ -27321,7 +28059,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27321
28059
|
const result = GooseSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27322
28060
|
if (!result.success) {
|
|
27323
28061
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27324
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28062
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27325
28063
|
}
|
|
27326
28064
|
return new GooseSkill({
|
|
27327
28065
|
outputRoot: loaded.outputRoot,
|
|
@@ -27374,7 +28112,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27374
28112
|
relativeDirPath,
|
|
27375
28113
|
dirName,
|
|
27376
28114
|
mainFile: {
|
|
27377
|
-
name: SKILL_FILE_NAME,
|
|
28115
|
+
name: SKILL_FILE_NAME$1,
|
|
27378
28116
|
body,
|
|
27379
28117
|
frontmatter: { ...frontmatter }
|
|
27380
28118
|
},
|
|
@@ -27398,7 +28136,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27398
28136
|
validate() {
|
|
27399
28137
|
if (this.mainFile === void 0) return {
|
|
27400
28138
|
success: false,
|
|
27401
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28139
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27402
28140
|
};
|
|
27403
28141
|
const result = GrokcliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27404
28142
|
if (!result.success) return {
|
|
@@ -27458,7 +28196,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27458
28196
|
const result = GrokcliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27459
28197
|
if (!result.success) {
|
|
27460
28198
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27461
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28199
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27462
28200
|
}
|
|
27463
28201
|
return new GrokcliSkill({
|
|
27464
28202
|
outputRoot: loaded.outputRoot,
|
|
@@ -27493,6 +28231,18 @@ var HermesagentSkill = class extends AgentsSkillsSkill {
|
|
|
27493
28231
|
static getSettablePaths() {
|
|
27494
28232
|
return { relativeDirPath: HERMESAGENT_SKILLS_DIR_PATH };
|
|
27495
28233
|
}
|
|
28234
|
+
/**
|
|
28235
|
+
* Commands are emitted into this same skills tree as `<slug>/SKILL.md`
|
|
28236
|
+
* (see `HermesagentCommand`), so a directory matching a current rulesync
|
|
28237
|
+
* command slug is owned by the commands feature: it must not be imported
|
|
28238
|
+
* as a skill nor deleted as an orphan skill.
|
|
28239
|
+
*/
|
|
28240
|
+
static async isDirOwned({ dirName, inputRoot }) {
|
|
28241
|
+
return !await rulesyncCommandSlugExists({
|
|
28242
|
+
inputRoot,
|
|
28243
|
+
dirName
|
|
28244
|
+
});
|
|
28245
|
+
}
|
|
27496
28246
|
constructor(params) {
|
|
27497
28247
|
super({
|
|
27498
28248
|
...params,
|
|
@@ -27517,7 +28267,7 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27517
28267
|
relativeDirPath,
|
|
27518
28268
|
dirName,
|
|
27519
28269
|
mainFile: {
|
|
27520
|
-
name: SKILL_FILE_NAME,
|
|
28270
|
+
name: SKILL_FILE_NAME$1,
|
|
27521
28271
|
body,
|
|
27522
28272
|
frontmatter: { ...frontmatter }
|
|
27523
28273
|
},
|
|
@@ -27541,7 +28291,7 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27541
28291
|
validate() {
|
|
27542
28292
|
if (!this.mainFile) return {
|
|
27543
28293
|
success: false,
|
|
27544
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28294
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27545
28295
|
};
|
|
27546
28296
|
const result = JunieSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27547
28297
|
if (!result.success) return {
|
|
@@ -27605,10 +28355,10 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27605
28355
|
const result = JunieSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27606
28356
|
if (!result.success) {
|
|
27607
28357
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27608
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28358
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27609
28359
|
}
|
|
27610
28360
|
if (result.data.name !== loaded.dirName) {
|
|
27611
|
-
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
28361
|
+
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
27612
28362
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
27613
28363
|
}
|
|
27614
28364
|
return new JunieSkill({
|
|
@@ -27656,7 +28406,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27656
28406
|
relativeDirPath,
|
|
27657
28407
|
dirName,
|
|
27658
28408
|
mainFile: {
|
|
27659
|
-
name: SKILL_FILE_NAME,
|
|
28409
|
+
name: SKILL_FILE_NAME$1,
|
|
27660
28410
|
body,
|
|
27661
28411
|
frontmatter: { ...frontmatter }
|
|
27662
28412
|
},
|
|
@@ -27680,7 +28430,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27680
28430
|
validate() {
|
|
27681
28431
|
if (this.mainFile === void 0) return {
|
|
27682
28432
|
success: false,
|
|
27683
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28433
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27684
28434
|
};
|
|
27685
28435
|
const result = KiloSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27686
28436
|
if (!result.success) return {
|
|
@@ -27752,7 +28502,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27752
28502
|
const result = KiloSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27753
28503
|
if (!result.success) {
|
|
27754
28504
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27755
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28505
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27756
28506
|
}
|
|
27757
28507
|
return new KiloSkill({
|
|
27758
28508
|
outputRoot: loaded.outputRoot,
|
|
@@ -27798,7 +28548,7 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27798
28548
|
relativeDirPath,
|
|
27799
28549
|
dirName,
|
|
27800
28550
|
mainFile: {
|
|
27801
|
-
name: SKILL_FILE_NAME,
|
|
28551
|
+
name: SKILL_FILE_NAME$1,
|
|
27802
28552
|
body,
|
|
27803
28553
|
frontmatter: { ...frontmatter }
|
|
27804
28554
|
},
|
|
@@ -27822,7 +28572,7 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27822
28572
|
validate() {
|
|
27823
28573
|
if (!this.mainFile) return {
|
|
27824
28574
|
success: false,
|
|
27825
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28575
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27826
28576
|
};
|
|
27827
28577
|
const result = KiroSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27828
28578
|
if (!result.success) return {
|
|
@@ -27886,10 +28636,10 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27886
28636
|
const result = KiroSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27887
28637
|
if (!result.success) {
|
|
27888
28638
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27889
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28639
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27890
28640
|
}
|
|
27891
28641
|
if (result.data.name !== loaded.dirName) {
|
|
27892
|
-
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
28642
|
+
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
27893
28643
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
27894
28644
|
}
|
|
27895
28645
|
return new KiroSkill({
|
|
@@ -27972,7 +28722,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
27972
28722
|
relativeDirPath,
|
|
27973
28723
|
dirName,
|
|
27974
28724
|
mainFile: {
|
|
27975
|
-
name: SKILL_FILE_NAME,
|
|
28725
|
+
name: SKILL_FILE_NAME$1,
|
|
27976
28726
|
body,
|
|
27977
28727
|
frontmatter: { ...frontmatter }
|
|
27978
28728
|
},
|
|
@@ -27999,7 +28749,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
27999
28749
|
validate() {
|
|
28000
28750
|
if (this.mainFile === void 0) return {
|
|
28001
28751
|
success: false,
|
|
28002
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28752
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28003
28753
|
};
|
|
28004
28754
|
const result = OpenCodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28005
28755
|
if (!result.success) return {
|
|
@@ -28078,7 +28828,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
28078
28828
|
const result = OpenCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28079
28829
|
if (!result.success) {
|
|
28080
28830
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28081
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28831
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28082
28832
|
}
|
|
28083
28833
|
return new OpenCodeSkill({
|
|
28084
28834
|
outputRoot: loaded.outputRoot,
|
|
@@ -28139,7 +28889,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28139
28889
|
relativeDirPath: resolvedDirPath,
|
|
28140
28890
|
dirName,
|
|
28141
28891
|
mainFile: {
|
|
28142
|
-
name: SKILL_FILE_NAME,
|
|
28892
|
+
name: SKILL_FILE_NAME$1,
|
|
28143
28893
|
body,
|
|
28144
28894
|
frontmatter: { ...frontmatter }
|
|
28145
28895
|
},
|
|
@@ -28164,7 +28914,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28164
28914
|
validate() {
|
|
28165
28915
|
if (!this.mainFile) return {
|
|
28166
28916
|
success: false,
|
|
28167
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28917
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28168
28918
|
};
|
|
28169
28919
|
const result = PiSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28170
28920
|
if (!result.success) return {
|
|
@@ -28239,7 +28989,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28239
28989
|
const result = PiSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28240
28990
|
if (!result.success) {
|
|
28241
28991
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28242
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28992
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28243
28993
|
}
|
|
28244
28994
|
return new PiSkill({
|
|
28245
28995
|
outputRoot: loaded.outputRoot,
|
|
@@ -28292,7 +29042,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28292
29042
|
relativeDirPath,
|
|
28293
29043
|
dirName,
|
|
28294
29044
|
mainFile: {
|
|
28295
|
-
name: SKILL_FILE_NAME,
|
|
29045
|
+
name: SKILL_FILE_NAME$1,
|
|
28296
29046
|
body,
|
|
28297
29047
|
frontmatter: { ...frontmatter }
|
|
28298
29048
|
},
|
|
@@ -28316,7 +29066,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28316
29066
|
validate() {
|
|
28317
29067
|
if (this.mainFile === void 0) return {
|
|
28318
29068
|
success: false,
|
|
28319
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29069
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28320
29070
|
};
|
|
28321
29071
|
const result = QwencodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28322
29072
|
if (!result.success) return {
|
|
@@ -28396,7 +29146,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28396
29146
|
const result = QwencodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28397
29147
|
if (!result.success) {
|
|
28398
29148
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28399
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29149
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28400
29150
|
}
|
|
28401
29151
|
return new QwencodeSkill({
|
|
28402
29152
|
outputRoot: loaded.outputRoot,
|
|
@@ -28446,7 +29196,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28446
29196
|
relativeDirPath,
|
|
28447
29197
|
dirName,
|
|
28448
29198
|
mainFile: {
|
|
28449
|
-
name: SKILL_FILE_NAME,
|
|
29199
|
+
name: SKILL_FILE_NAME$1,
|
|
28450
29200
|
body,
|
|
28451
29201
|
frontmatter: { ...frontmatter }
|
|
28452
29202
|
},
|
|
@@ -28470,7 +29220,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28470
29220
|
validate() {
|
|
28471
29221
|
if (this.mainFile === void 0) return {
|
|
28472
29222
|
success: false,
|
|
28473
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29223
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28474
29224
|
};
|
|
28475
29225
|
const result = ReasonixSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28476
29226
|
if (!result.success) return {
|
|
@@ -28530,7 +29280,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28530
29280
|
const result = ReasonixSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28531
29281
|
if (!result.success) {
|
|
28532
29282
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28533
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29283
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28534
29284
|
}
|
|
28535
29285
|
return new ReasonixSkill({
|
|
28536
29286
|
outputRoot: loaded.outputRoot,
|
|
@@ -28553,7 +29303,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28553
29303
|
* skills-feature ownership, matching the previous behavior for such dirs.
|
|
28554
29304
|
*/
|
|
28555
29305
|
static async isDirOwned({ outputRoot, relativeDirPath, dirName }) {
|
|
28556
|
-
const skillFilePath = (0, node_path.join)(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME);
|
|
29306
|
+
const skillFilePath = (0, node_path.join)(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
28557
29307
|
try {
|
|
28558
29308
|
const { frontmatter } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
28559
29309
|
return frontmatter["runAs"] !== REASONIX_SUBAGENT_RUN_AS;
|
|
@@ -28603,7 +29353,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28603
29353
|
relativeDirPath,
|
|
28604
29354
|
dirName,
|
|
28605
29355
|
mainFile: {
|
|
28606
|
-
name: SKILL_FILE_NAME,
|
|
29356
|
+
name: SKILL_FILE_NAME$1,
|
|
28607
29357
|
body,
|
|
28608
29358
|
frontmatter: { ...frontmatter }
|
|
28609
29359
|
},
|
|
@@ -28627,7 +29377,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28627
29377
|
validate() {
|
|
28628
29378
|
if (!this.mainFile) return {
|
|
28629
29379
|
success: false,
|
|
28630
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29380
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28631
29381
|
};
|
|
28632
29382
|
const result = ReplitSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28633
29383
|
if (!result.success) return {
|
|
@@ -28695,7 +29445,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28695
29445
|
const result = ReplitSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28696
29446
|
if (!result.success) {
|
|
28697
29447
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28698
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29448
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28699
29449
|
}
|
|
28700
29450
|
return new ReplitSkill({
|
|
28701
29451
|
outputRoot: loaded.outputRoot,
|
|
@@ -28742,7 +29492,7 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28742
29492
|
relativeDirPath,
|
|
28743
29493
|
dirName,
|
|
28744
29494
|
mainFile: {
|
|
28745
|
-
name: SKILL_FILE_NAME,
|
|
29495
|
+
name: SKILL_FILE_NAME$1,
|
|
28746
29496
|
body,
|
|
28747
29497
|
frontmatter: { ...frontmatter }
|
|
28748
29498
|
},
|
|
@@ -28766,7 +29516,7 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28766
29516
|
validate() {
|
|
28767
29517
|
if (!this.mainFile) return {
|
|
28768
29518
|
success: false,
|
|
28769
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29519
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28770
29520
|
};
|
|
28771
29521
|
const result = RooSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28772
29522
|
if (!result.success) return {
|
|
@@ -28830,10 +29580,10 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28830
29580
|
const result = RooSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28831
29581
|
if (!result.success) {
|
|
28832
29582
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28833
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29583
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28834
29584
|
}
|
|
28835
29585
|
if (result.data.name !== loaded.dirName) {
|
|
28836
|
-
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
29586
|
+
const skillFilePath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
28837
29587
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
28838
29588
|
}
|
|
28839
29589
|
return new RooSkill({
|
|
@@ -29050,7 +29800,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29050
29800
|
relativeDirPath,
|
|
29051
29801
|
dirName,
|
|
29052
29802
|
mainFile: {
|
|
29053
|
-
name: SKILL_FILE_NAME,
|
|
29803
|
+
name: SKILL_FILE_NAME$1,
|
|
29054
29804
|
body,
|
|
29055
29805
|
frontmatter: { ...frontmatter }
|
|
29056
29806
|
},
|
|
@@ -29077,7 +29827,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29077
29827
|
validate() {
|
|
29078
29828
|
if (!this.mainFile) return {
|
|
29079
29829
|
success: false,
|
|
29080
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29830
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29081
29831
|
};
|
|
29082
29832
|
const result = VibeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29083
29833
|
if (!result.success) return {
|
|
@@ -29141,7 +29891,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29141
29891
|
const result = VibeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29142
29892
|
if (!result.success) {
|
|
29143
29893
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29144
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29894
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29145
29895
|
}
|
|
29146
29896
|
return new VibeSkill({
|
|
29147
29897
|
outputRoot: loaded.outputRoot,
|
|
@@ -29197,7 +29947,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29197
29947
|
relativeDirPath,
|
|
29198
29948
|
dirName,
|
|
29199
29949
|
mainFile: {
|
|
29200
|
-
name: SKILL_FILE_NAME,
|
|
29950
|
+
name: SKILL_FILE_NAME$1,
|
|
29201
29951
|
body,
|
|
29202
29952
|
frontmatter: { ...frontmatter }
|
|
29203
29953
|
},
|
|
@@ -29221,7 +29971,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29221
29971
|
validate() {
|
|
29222
29972
|
if (this.mainFile === void 0) return {
|
|
29223
29973
|
success: false,
|
|
29224
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29974
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29225
29975
|
};
|
|
29226
29976
|
const result = WarpSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29227
29977
|
if (!result.success) return {
|
|
@@ -29281,7 +30031,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29281
30031
|
const result = WarpSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29282
30032
|
if (!result.success) {
|
|
29283
30033
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29284
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
30034
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29285
30035
|
}
|
|
29286
30036
|
return new WarpSkill({
|
|
29287
30037
|
outputRoot: loaded.outputRoot,
|
|
@@ -29329,7 +30079,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29329
30079
|
relativeDirPath,
|
|
29330
30080
|
dirName,
|
|
29331
30081
|
mainFile: {
|
|
29332
|
-
name: SKILL_FILE_NAME,
|
|
30082
|
+
name: SKILL_FILE_NAME$1,
|
|
29333
30083
|
body,
|
|
29334
30084
|
frontmatter: { ...frontmatter }
|
|
29335
30085
|
},
|
|
@@ -29353,7 +30103,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29353
30103
|
validate() {
|
|
29354
30104
|
if (!this.mainFile) return {
|
|
29355
30105
|
success: false,
|
|
29356
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
30106
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29357
30107
|
};
|
|
29358
30108
|
const result = ZedSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29359
30109
|
if (!result.success) return {
|
|
@@ -29422,7 +30172,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29422
30172
|
const result = ZedSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29423
30173
|
if (!result.success) {
|
|
29424
30174
|
const skillDirPath = (0, node_path.join)(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29425
|
-
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
30175
|
+
throw new Error(`Invalid frontmatter in ${(0, node_path.join)(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29426
30176
|
}
|
|
29427
30177
|
return new ZedSkill({
|
|
29428
30178
|
outputRoot: loaded.outputRoot,
|
|
@@ -29862,7 +30612,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29862
30612
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29863
30613
|
outputRoot: this.outputRoot,
|
|
29864
30614
|
relativeDirPath: root,
|
|
29865
|
-
dirName
|
|
30615
|
+
dirName,
|
|
30616
|
+
inputRoot: this.inputRoot
|
|
29866
30617
|
})) continue;
|
|
29867
30618
|
seenDirNames.add(dirName);
|
|
29868
30619
|
loadEntries.push({
|
|
@@ -29893,7 +30644,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29893
30644
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29894
30645
|
outputRoot: this.outputRoot,
|
|
29895
30646
|
relativeDirPath: root,
|
|
29896
|
-
dirName
|
|
30647
|
+
dirName,
|
|
30648
|
+
inputRoot: this.inputRoot
|
|
29897
30649
|
})) continue;
|
|
29898
30650
|
const toolSkill = factory.class.forDeletion({
|
|
29899
30651
|
outputRoot: this.outputRoot,
|
|
@@ -33294,7 +34046,7 @@ var ReasonixSubagent = class ReasonixSubagent extends ToolSubagent {
|
|
|
33294
34046
|
frontmatter: reasonixFrontmatter,
|
|
33295
34047
|
body,
|
|
33296
34048
|
relativeDirPath: paths.relativeDirPath,
|
|
33297
|
-
relativeFilePath: (0, node_path.join)(subagentName, SKILL_FILE_NAME),
|
|
34049
|
+
relativeFilePath: (0, node_path.join)(subagentName, SKILL_FILE_NAME$1),
|
|
33298
34050
|
fileContent,
|
|
33299
34051
|
validate,
|
|
33300
34052
|
global
|
|
@@ -34300,6 +35052,7 @@ const RulesyncRuleFrontmatterSchema = zod_mini.z.object({
|
|
|
34300
35052
|
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
34301
35053
|
description: zod_mini.z.optional(zod_mini.z.string())
|
|
34302
35054
|
})),
|
|
35055
|
+
pi: zod_mini.z.optional(zod_mini.z.looseObject({ systemPrompt: zod_mini.z.optional(zod_mini.z.enum(["append"])) })),
|
|
34303
35056
|
takt: zod_mini.z.optional(zod_mini.z.looseObject({
|
|
34304
35057
|
name: zod_mini.z.optional(zod_mini.z.string()),
|
|
34305
35058
|
extends: zod_mini.z.optional(zod_mini.z.string()),
|
|
@@ -34463,6 +35216,16 @@ var ToolRule = class extends ToolFile {
|
|
|
34463
35216
|
isRoot() {
|
|
34464
35217
|
return this.root;
|
|
34465
35218
|
}
|
|
35219
|
+
/**
|
|
35220
|
+
* Whether this rule must be left out of the root rule's reference/MCP
|
|
35221
|
+
* instruction listings even though it is a non-root survivor. Used by files
|
|
35222
|
+
* the tool loads through its own mechanism (e.g. Pi's `APPEND_SYSTEM.md`,
|
|
35223
|
+
* which Pi appends to the system prompt itself — referencing it from
|
|
35224
|
+
* `AGENTS.md` would double-load the content).
|
|
35225
|
+
*/
|
|
35226
|
+
isExcludedFromRootReferences() {
|
|
35227
|
+
return false;
|
|
35228
|
+
}
|
|
34466
35229
|
getDescription() {
|
|
34467
35230
|
return this.description;
|
|
34468
35231
|
}
|
|
@@ -36809,6 +37572,15 @@ var FactorydroidRule = class FactorydroidRule extends ToolRule {
|
|
|
36809
37572
|
* is `undefined`). This mirrors the grokcli, warp, and deepagents targets.
|
|
36810
37573
|
*
|
|
36811
37574
|
* Goose uses plain markdown files (.goosehints) without frontmatter.
|
|
37575
|
+
*
|
|
37576
|
+
* Global scope emits only `~/.config/goose/.goosehints`. Goose v1.41.0 (PR
|
|
37577
|
+
* block/goose#9736) additionally loads the vendor-neutral
|
|
37578
|
+
* `~/.agents/AGENTS.md` alongside the config-dir hints, but rulesync
|
|
37579
|
+
* deliberately does not emit that shared path from the goose target: the
|
|
37580
|
+
* config-dir hints remain fully loaded (no capability loss), and the
|
|
37581
|
+
* cross-tool `~/.agents/AGENTS.md` is already written by targets that own it
|
|
37582
|
+
* (e.g. cline in global mode) — a second writer would need cross-target
|
|
37583
|
+
* shared-file coordination for zero gain (decision recorded in issue #2207).
|
|
36812
37584
|
*/
|
|
36813
37585
|
var GooseRule = class GooseRule extends ToolRule {
|
|
36814
37586
|
static getSettablePaths({ global } = {}) {
|
|
@@ -37010,14 +37782,21 @@ var HermesagentRule = class HermesagentRule extends ToolRule {
|
|
|
37010
37782
|
/**
|
|
37011
37783
|
* Rule generator for JetBrains Junie AI coding agent
|
|
37012
37784
|
*
|
|
37013
|
-
* Generates `.junie/AGENTS.md` files based on rulesync rule content.
|
|
37014
|
-
*
|
|
37015
|
-
*
|
|
37016
|
-
*
|
|
37017
|
-
*
|
|
37018
|
-
*
|
|
37019
|
-
*
|
|
37020
|
-
*
|
|
37785
|
+
* Generates `.junie/AGENTS.md` files based on rulesync rule content. Junie CLI
|
|
37786
|
+
* resolves project guidelines **first-match-wins**: `.junie/AGENTS.md` → root
|
|
37787
|
+
* `AGENTS.md` → legacy `.junie/guidelines.md` / `.junie/guidelines/`. Only the
|
|
37788
|
+
* first match is loaded, it documents no `@`-reference or file-inclusion
|
|
37789
|
+
* mechanism, and no `.junie/memories/` read path exists — so non-root rules
|
|
37790
|
+
* are folded into the single root `.junie/AGENTS.md` by the RulesProcessor
|
|
37791
|
+
* (`nonRoot` is `undefined`, mirroring the grokcli / warp / deepagents
|
|
37792
|
+
* targets; decision recorded in issue #2211). The legacy
|
|
37793
|
+
* `.junie/guidelines.md` is still accepted as an import fallback, but
|
|
37794
|
+
* generation always targets `.junie/AGENTS.md`. Junie uses plain markdown
|
|
37795
|
+
* without frontmatter requirements.
|
|
37796
|
+
*
|
|
37797
|
+
* Global (user) scope writes a single `~/.junie/AGENTS.md` file. Junie merges
|
|
37798
|
+
* these user-scope guidelines with the project guidelines (both are included
|
|
37799
|
+
* and marked clearly).
|
|
37021
37800
|
*
|
|
37022
37801
|
* @see https://junie.jetbrains.com/docs/junie-ide-plugin.html
|
|
37023
37802
|
* @see https://junie.jetbrains.com/docs/guidelines-and-memory.html
|
|
@@ -37036,15 +37815,12 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37036
37815
|
alternativeRoots: [{
|
|
37037
37816
|
relativeDirPath: buildToolPath(JUNIE_DIR, ".", excludeToolDir),
|
|
37038
37817
|
relativeFilePath: JUNIE_LEGACY_RULE_FILE_NAME
|
|
37039
|
-
}]
|
|
37040
|
-
nonRoot: { relativeDirPath: buildToolPath(JUNIE_DIR, "memories", excludeToolDir) }
|
|
37818
|
+
}]
|
|
37041
37819
|
};
|
|
37042
37820
|
}
|
|
37043
37821
|
/**
|
|
37044
37822
|
* Determines whether a given relative file path refers to a root guideline file.
|
|
37045
37823
|
* The preferred file is `AGENTS.md`; the legacy `guidelines.md` is still accepted.
|
|
37046
|
-
* Memory files live under `.junie/memories/` and are passed in as bare filenames
|
|
37047
|
-
* (e.g. `memo.md`), so a top-level `AGENTS.md`/`guidelines.md` is the root entry.
|
|
37048
37824
|
*/
|
|
37049
37825
|
static isRootRelativeFilePath(relativeFilePath) {
|
|
37050
37826
|
return relativeFilePath === "AGENTS.md" || relativeFilePath === "guidelines.md";
|
|
@@ -37063,10 +37839,7 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37063
37839
|
root: true
|
|
37064
37840
|
});
|
|
37065
37841
|
}
|
|
37066
|
-
const
|
|
37067
|
-
const settablePaths = this.getSettablePaths();
|
|
37068
|
-
if (!settablePaths.nonRoot) throw new Error("JunieRule project settable paths must include a nonRoot path");
|
|
37069
|
-
const relativeDirPath = isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath;
|
|
37842
|
+
const relativeDirPath = this.getSettablePaths().root.relativeDirPath;
|
|
37070
37843
|
const fileContent = await readFileContent((0, node_path.join)(outputRoot, (0, node_path.join)(relativeDirPath, relativeFilePath)));
|
|
37071
37844
|
return new JunieRule({
|
|
37072
37845
|
outputRoot,
|
|
@@ -37074,7 +37847,7 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37074
37847
|
relativeFilePath,
|
|
37075
37848
|
fileContent,
|
|
37076
37849
|
validate,
|
|
37077
|
-
root:
|
|
37850
|
+
root: JunieRule.isRootRelativeFilePath(relativeFilePath)
|
|
37078
37851
|
});
|
|
37079
37852
|
}
|
|
37080
37853
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
@@ -37089,13 +37862,15 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37089
37862
|
rootPath: paths.root
|
|
37090
37863
|
}));
|
|
37091
37864
|
}
|
|
37092
|
-
|
|
37865
|
+
const { root } = this.getSettablePaths();
|
|
37866
|
+
return new JunieRule({
|
|
37093
37867
|
outputRoot,
|
|
37094
|
-
|
|
37868
|
+
relativeDirPath: root.relativeDirPath,
|
|
37869
|
+
relativeFilePath: root.relativeFilePath,
|
|
37870
|
+
fileContent: rulesyncRule.getBody(),
|
|
37095
37871
|
validate,
|
|
37096
|
-
|
|
37097
|
-
|
|
37098
|
-
}));
|
|
37872
|
+
root: rulesyncRule.getFrontmatter().root ?? false
|
|
37873
|
+
});
|
|
37099
37874
|
}
|
|
37100
37875
|
toRulesyncRule() {
|
|
37101
37876
|
return this.toRulesyncRuleDefault();
|
|
@@ -37498,31 +38273,68 @@ var OpenCodeRule = class OpenCodeRule extends ToolRule {
|
|
|
37498
38273
|
* RulesProcessor (there is no separate non-root output location — `nonRoot` is
|
|
37499
38274
|
* `undefined`). This mirrors the codexcli, grokcli, warp, and deepagents targets.
|
|
37500
38275
|
*
|
|
37501
|
-
* Pi also loads two system-prompt instruction files
|
|
38276
|
+
* Pi also loads two system-prompt instruction files. `.pi/APPEND_SYSTEM.md`
|
|
38277
|
+
* (global `~/.pi/agent/APPEND_SYSTEM.md`) *appends* to the default system prompt,
|
|
38278
|
+
* and rulesync emits it from any rule that opts in via the `pi.systemPrompt:
|
|
38279
|
+
* append` frontmatter block: those bodies are routed here instead of being folded
|
|
38280
|
+
* into `AGENTS.md`, and multiple opted-in rules concatenate in source order.
|
|
37502
38281
|
* `.pi/SYSTEM.md` (global `~/.pi/agent/SYSTEM.md`) *replaces* the default system
|
|
37503
|
-
* prompt entirely
|
|
37504
|
-
*
|
|
37505
|
-
*
|
|
37506
|
-
* for marking a rule as "replace" vs "append" the system prompt, so these
|
|
37507
|
-
* surfaces are documented in docs/reference/file-formats.md and left to be
|
|
37508
|
-
* authored by hand rather than mapped to a speculative new frontmatter flag.
|
|
38282
|
+
* prompt entirely — which silently disables Pi's built-in tool instructions — so
|
|
38283
|
+
* rulesync deliberately never emits it and leaves it to be authored by hand.
|
|
38284
|
+
* See docs/reference/file-formats.md.
|
|
37509
38285
|
*/
|
|
37510
38286
|
var PiRule = class PiRule extends ToolRule {
|
|
37511
|
-
|
|
38287
|
+
appendSystemPrompt;
|
|
38288
|
+
constructor({ fileContent, root, appendSystemPrompt = false, ...rest }) {
|
|
37512
38289
|
super({
|
|
37513
38290
|
...rest,
|
|
37514
38291
|
fileContent,
|
|
37515
38292
|
root: root ?? false
|
|
37516
38293
|
});
|
|
38294
|
+
this.appendSystemPrompt = appendSystemPrompt;
|
|
37517
38295
|
}
|
|
37518
38296
|
static getSettablePaths({ global = false, excludeToolDir } = {}) {
|
|
37519
|
-
return {
|
|
37520
|
-
|
|
37521
|
-
|
|
37522
|
-
|
|
38297
|
+
return {
|
|
38298
|
+
root: {
|
|
38299
|
+
relativeDirPath: global ? buildToolPath(".pi", "agent", excludeToolDir) : ".",
|
|
38300
|
+
relativeFilePath: PI_RULE_FILE_NAME
|
|
38301
|
+
},
|
|
38302
|
+
appendSystemPrompt: {
|
|
38303
|
+
relativeDirPath: global ? buildToolPath(".pi", "agent", excludeToolDir) : ".pi",
|
|
38304
|
+
relativeFilePath: PI_APPEND_SYSTEM_FILE_NAME
|
|
38305
|
+
}
|
|
38306
|
+
};
|
|
37523
38307
|
}
|
|
37524
|
-
|
|
37525
|
-
|
|
38308
|
+
/**
|
|
38309
|
+
* Extra fixed files this tool manages beyond the root rule. The
|
|
38310
|
+
* RulesProcessor enumerates these for import and deletion so a stale
|
|
38311
|
+
* `APPEND_SYSTEM.md` is cleaned up once no rule opts in anymore.
|
|
38312
|
+
*/
|
|
38313
|
+
static getExtraFixedFiles({ global = false } = {}) {
|
|
38314
|
+
return [this.getSettablePaths({ global }).appendSystemPrompt];
|
|
38315
|
+
}
|
|
38316
|
+
/**
|
|
38317
|
+
* Pi appends `APPEND_SYSTEM.md` to the system prompt itself, so listing it in
|
|
38318
|
+
* the root rule's reference section (toon/explicit discovery modes) would
|
|
38319
|
+
* double-load the content.
|
|
38320
|
+
*/
|
|
38321
|
+
isExcludedFromRootReferences() {
|
|
38322
|
+
return this.appendSystemPrompt;
|
|
38323
|
+
}
|
|
38324
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
38325
|
+
const { root, appendSystemPrompt } = this.getSettablePaths({ global });
|
|
38326
|
+
if (relativeFilePath === "APPEND_SYSTEM.md") {
|
|
38327
|
+
const fileContent = await readFileContent((0, node_path.join)(outputRoot, (0, node_path.join)(appendSystemPrompt.relativeDirPath, appendSystemPrompt.relativeFilePath)));
|
|
38328
|
+
return new PiRule({
|
|
38329
|
+
outputRoot,
|
|
38330
|
+
relativeDirPath: appendSystemPrompt.relativeDirPath,
|
|
38331
|
+
relativeFilePath: appendSystemPrompt.relativeFilePath,
|
|
38332
|
+
fileContent,
|
|
38333
|
+
validate,
|
|
38334
|
+
root: false,
|
|
38335
|
+
appendSystemPrompt: true
|
|
38336
|
+
});
|
|
38337
|
+
}
|
|
37526
38338
|
const fileContent = await readFileContent((0, node_path.join)(outputRoot, (0, node_path.join)(root.relativeDirPath, root.relativeFilePath)));
|
|
37527
38339
|
return new PiRule({
|
|
37528
38340
|
outputRoot,
|
|
@@ -37534,8 +38346,18 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37534
38346
|
});
|
|
37535
38347
|
}
|
|
37536
38348
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
37537
|
-
const { root } = this.getSettablePaths({ global });
|
|
37538
|
-
const
|
|
38349
|
+
const { root, appendSystemPrompt } = this.getSettablePaths({ global });
|
|
38350
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
38351
|
+
if (!frontmatter.root && frontmatter.pi?.systemPrompt === "append") return new PiRule({
|
|
38352
|
+
outputRoot,
|
|
38353
|
+
relativeDirPath: appendSystemPrompt.relativeDirPath,
|
|
38354
|
+
relativeFilePath: appendSystemPrompt.relativeFilePath,
|
|
38355
|
+
fileContent: rulesyncRule.getBody(),
|
|
38356
|
+
validate,
|
|
38357
|
+
root: false,
|
|
38358
|
+
appendSystemPrompt: true
|
|
38359
|
+
});
|
|
38360
|
+
const isRoot = frontmatter.root ?? false;
|
|
37539
38361
|
return new PiRule({
|
|
37540
38362
|
outputRoot,
|
|
37541
38363
|
relativeDirPath: root.relativeDirPath,
|
|
@@ -37546,6 +38368,17 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37546
38368
|
});
|
|
37547
38369
|
}
|
|
37548
38370
|
toRulesyncRule() {
|
|
38371
|
+
if (this.appendSystemPrompt) return new RulesyncRule({
|
|
38372
|
+
outputRoot: process.cwd(),
|
|
38373
|
+
relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
|
|
38374
|
+
relativeFilePath: PI_APPEND_SYSTEM_FILE_NAME,
|
|
38375
|
+
frontmatter: {
|
|
38376
|
+
root: false,
|
|
38377
|
+
targets: ["pi"],
|
|
38378
|
+
pi: { systemPrompt: "append" }
|
|
38379
|
+
},
|
|
38380
|
+
body: this.getFileContent()
|
|
38381
|
+
});
|
|
37549
38382
|
return this.toRulesyncRuleDefault();
|
|
37550
38383
|
}
|
|
37551
38384
|
validate() {
|
|
@@ -37556,6 +38389,15 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37556
38389
|
}
|
|
37557
38390
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
37558
38391
|
const { root } = this.getSettablePaths({ global });
|
|
38392
|
+
if (relativeFilePath === "APPEND_SYSTEM.md") return new PiRule({
|
|
38393
|
+
outputRoot,
|
|
38394
|
+
relativeDirPath,
|
|
38395
|
+
relativeFilePath,
|
|
38396
|
+
fileContent: "",
|
|
38397
|
+
validate: false,
|
|
38398
|
+
root: false,
|
|
38399
|
+
appendSystemPrompt: true
|
|
38400
|
+
});
|
|
37559
38401
|
const isRoot = relativeFilePath === "AGENTS.md" && (relativeDirPath === "." || relativeDirPath === root.relativeDirPath);
|
|
37560
38402
|
return new PiRule({
|
|
37561
38403
|
outputRoot,
|
|
@@ -38715,7 +39557,8 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
38715
39557
|
meta: {
|
|
38716
39558
|
extension: "md",
|
|
38717
39559
|
supportsGlobal: true,
|
|
38718
|
-
ruleDiscoveryMode: "
|
|
39560
|
+
ruleDiscoveryMode: "auto",
|
|
39561
|
+
foldsNonRootIntoRoot: true
|
|
38719
39562
|
}
|
|
38720
39563
|
}],
|
|
38721
39564
|
["kilo", {
|
|
@@ -38981,7 +39824,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
38981
39824
|
*/
|
|
38982
39825
|
async buildMcpInstructionFiles({ toolRules, meta }) {
|
|
38983
39826
|
if (!meta.mcpInstructionsRegistrar || this.global) return [];
|
|
38984
|
-
const instructionPaths = toolRules.filter((rule) => !rule.isRoot()).map((rule) => toPosixPath((0, node_path.join)(rule.getRelativeDirPath(), rule.getRelativeFilePath())));
|
|
39827
|
+
const instructionPaths = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences()).map((rule) => toPosixPath((0, node_path.join)(rule.getRelativeDirPath(), rule.getRelativeFilePath())));
|
|
38985
39828
|
if (instructionPaths.length === 0) return [];
|
|
38986
39829
|
return [await meta.mcpInstructionsRegistrar.fromInstructions({
|
|
38987
39830
|
outputRoot: this.outputRoot,
|
|
@@ -39013,7 +39856,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
39013
39856
|
const toolRelativeDirPath = skillClass.getSettablePaths({ global: this.global }).relativeDirPath;
|
|
39014
39857
|
return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
|
|
39015
39858
|
const frontmatter = skill.getFrontmatter();
|
|
39016
|
-
const relativePath = (0, node_path.join)(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
|
|
39859
|
+
const relativePath = (0, node_path.join)(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME$1);
|
|
39017
39860
|
return {
|
|
39018
39861
|
name: frontmatter.name,
|
|
39019
39862
|
description: frontmatter.description,
|
|
@@ -39037,11 +39880,25 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
39037
39880
|
*/
|
|
39038
39881
|
foldNonRootRulesIntoRootRule(toolRules) {
|
|
39039
39882
|
if (toolRules.length <= 1) return;
|
|
39040
|
-
const
|
|
39041
|
-
|
|
39042
|
-
|
|
39043
|
-
|
|
39044
|
-
|
|
39883
|
+
const groups = /* @__PURE__ */ new Map();
|
|
39884
|
+
for (const rule of toolRules) {
|
|
39885
|
+
const path = (0, node_path.join)(rule.getRelativeDirPath(), rule.getRelativeFilePath());
|
|
39886
|
+
const group = groups.get(path);
|
|
39887
|
+
if (group) group.push(rule);
|
|
39888
|
+
else groups.set(path, [rule]);
|
|
39889
|
+
}
|
|
39890
|
+
const survivors = /* @__PURE__ */ new Set();
|
|
39891
|
+
for (const group of groups.values()) {
|
|
39892
|
+
const target = group.find((rule) => rule.isRoot()) ?? group[0];
|
|
39893
|
+
if (!target) continue;
|
|
39894
|
+
const mergedContent = [target, ...group.filter((rule) => rule !== target)].map((rule) => rule.getFileContent().trim()).filter((content) => content.length > 0).join("\n\n");
|
|
39895
|
+
target.setFileContent(mergedContent);
|
|
39896
|
+
survivors.add(target);
|
|
39897
|
+
}
|
|
39898
|
+
for (let i = toolRules.length - 1; i >= 0; i--) {
|
|
39899
|
+
const rule = toolRules[i];
|
|
39900
|
+
if (rule && !survivors.has(rule)) toolRules.splice(i, 1);
|
|
39901
|
+
}
|
|
39045
39902
|
}
|
|
39046
39903
|
/**
|
|
39047
39904
|
* Handle localRoot rule generation based on tool target.
|
|
@@ -39251,6 +40108,27 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39251
40108
|
const mirrorPaths = await findFilesByGlobs(mirrorGlob);
|
|
39252
40109
|
return buildDeletionRulesFromPaths(mirrorPaths);
|
|
39253
40110
|
})();
|
|
40111
|
+
const extraFixedToolRules = await (async () => {
|
|
40112
|
+
const extraFiles = factory.class.getExtraFixedFiles?.({ global: this.global });
|
|
40113
|
+
if (!extraFiles || extraFiles.length === 0) return [];
|
|
40114
|
+
const filePaths = await findFilesByGlobs(extraFiles.map((file) => (0, node_path.join)(this.outputRoot, file.relativeDirPath, file.relativeFilePath)));
|
|
40115
|
+
if (filePaths.length === 0) return [];
|
|
40116
|
+
if (forDeletion) return buildDeletionRulesFromPaths(filePaths);
|
|
40117
|
+
return await Promise.all(filePaths.map((filePath) => {
|
|
40118
|
+
const relativeDirPath = resolveRelativeDirPath(filePath);
|
|
40119
|
+
checkPathTraversal({
|
|
40120
|
+
relativePath: relativeDirPath,
|
|
40121
|
+
intendedRootDir: this.outputRoot
|
|
40122
|
+
});
|
|
40123
|
+
return factory.class.fromFile({
|
|
40124
|
+
outputRoot: this.outputRoot,
|
|
40125
|
+
relativeDirPath,
|
|
40126
|
+
relativeFilePath: (0, node_path.basename)(filePath),
|
|
40127
|
+
global: this.global
|
|
40128
|
+
});
|
|
40129
|
+
}));
|
|
40130
|
+
})();
|
|
40131
|
+
this.logger.debug(`Found ${extraFixedToolRules.length} extra fixed tool rule files`);
|
|
39254
40132
|
const nonRootToolRules = await (async () => {
|
|
39255
40133
|
if (!settablePaths.nonRoot) return [];
|
|
39256
40134
|
const nonRootOutputRoot = (0, node_path.join)(this.outputRoot, settablePaths.nonRoot.relativeDirPath);
|
|
@@ -39286,6 +40164,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39286
40164
|
...rootToolRules,
|
|
39287
40165
|
...localRootToolRules,
|
|
39288
40166
|
...rootMirrorDeletionRules,
|
|
40167
|
+
...extraFixedToolRules,
|
|
39289
40168
|
...nonRootToolRules
|
|
39290
40169
|
];
|
|
39291
40170
|
} catch (error) {
|
|
@@ -39313,7 +40192,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39313
40192
|
return toolRuleFactories.get(result.data);
|
|
39314
40193
|
}
|
|
39315
40194
|
generateToonReferencesSection(toolRules) {
|
|
39316
|
-
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
40195
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences());
|
|
39317
40196
|
if (toolRulesWithoutRoot.length === 0) return "";
|
|
39318
40197
|
const lines = [];
|
|
39319
40198
|
lines.push("Please also reference the following rules as needed. The list below is provided in TOON format, and `@` stands for the project root directory.");
|
|
@@ -39329,7 +40208,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39329
40208
|
return lines.join("\n") + "\n\n";
|
|
39330
40209
|
}
|
|
39331
40210
|
generateReferencesSection(toolRules) {
|
|
39332
|
-
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
40211
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences());
|
|
39333
40212
|
if (toolRulesWithoutRoot.length === 0) return "";
|
|
39334
40213
|
const lines = [];
|
|
39335
40214
|
lines.push("Please also reference the following rules as needed:");
|
|
@@ -39350,7 +40229,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39350
40229
|
*/
|
|
39351
40230
|
async function convertFromTool(params) {
|
|
39352
40231
|
const ctx = params;
|
|
39353
|
-
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount] = [
|
|
40232
|
+
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount, checksCount] = [
|
|
39354
40233
|
await runFeatureConvert(ctx, buildRulesStrategy(ctx)),
|
|
39355
40234
|
await runFeatureConvert(ctx, buildIgnoreStrategy(ctx)),
|
|
39356
40235
|
await runFeatureConvert(ctx, buildMcpStrategy(ctx)),
|
|
@@ -39358,7 +40237,8 @@ async function convertFromTool(params) {
|
|
|
39358
40237
|
await runFeatureConvert(ctx, buildSubagentsStrategy(ctx)),
|
|
39359
40238
|
await runFeatureConvert(ctx, buildSkillsStrategy(ctx)),
|
|
39360
40239
|
await runFeatureConvert(ctx, buildHooksStrategy(ctx)),
|
|
39361
|
-
await runFeatureConvert(ctx, buildPermissionsStrategy(ctx))
|
|
40240
|
+
await runFeatureConvert(ctx, buildPermissionsStrategy(ctx)),
|
|
40241
|
+
await runFeatureConvert(ctx, buildChecksStrategy(ctx))
|
|
39362
40242
|
];
|
|
39363
40243
|
return {
|
|
39364
40244
|
rulesCount,
|
|
@@ -39368,7 +40248,8 @@ async function convertFromTool(params) {
|
|
|
39368
40248
|
subagentsCount,
|
|
39369
40249
|
skillsCount,
|
|
39370
40250
|
hooksCount,
|
|
39371
|
-
permissionsCount
|
|
40251
|
+
permissionsCount,
|
|
40252
|
+
checksCount
|
|
39372
40253
|
};
|
|
39373
40254
|
}
|
|
39374
40255
|
async function runFeatureConvert(ctx, strategy) {
|
|
@@ -39601,6 +40482,27 @@ function buildPermissionsStrategy(ctx) {
|
|
|
39601
40482
|
write: (p, files) => p.writeAiFiles(files)
|
|
39602
40483
|
};
|
|
39603
40484
|
}
|
|
40485
|
+
function buildChecksStrategy(ctx) {
|
|
40486
|
+
const { config, logger } = ctx;
|
|
40487
|
+
const global = config.getGlobal();
|
|
40488
|
+
const outputRoot = getOutputRoot(config);
|
|
40489
|
+
return {
|
|
40490
|
+
feature: "checks",
|
|
40491
|
+
itemLabel: "check file(s)",
|
|
40492
|
+
allTargets: ChecksProcessor.getToolTargets({ global }),
|
|
40493
|
+
createProcessor: ({ toolTarget, dryRun }) => new ChecksProcessor({
|
|
40494
|
+
outputRoot,
|
|
40495
|
+
toolTarget,
|
|
40496
|
+
global,
|
|
40497
|
+
dryRun,
|
|
40498
|
+
logger
|
|
40499
|
+
}),
|
|
40500
|
+
loadSource: (p) => p.loadToolFiles(),
|
|
40501
|
+
toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
|
|
40502
|
+
fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
|
|
40503
|
+
write: (p, files) => p.writeAiFiles(files)
|
|
40504
|
+
};
|
|
40505
|
+
}
|
|
39604
40506
|
//#endregion
|
|
39605
40507
|
//#region src/types/processor-registry.ts
|
|
39606
40508
|
const PROCESSOR_REGISTRY = [
|
|
@@ -39651,6 +40553,12 @@ const PROCESSOR_REGISTRY = [
|
|
|
39651
40553
|
processor: PermissionsProcessor,
|
|
39652
40554
|
schema: PermissionsProcessorToolTargetSchema,
|
|
39653
40555
|
factory: toolPermissionsFactories
|
|
40556
|
+
},
|
|
40557
|
+
{
|
|
40558
|
+
feature: "checks",
|
|
40559
|
+
processor: ChecksProcessor,
|
|
40560
|
+
schema: ChecksProcessorToolTargetSchema,
|
|
40561
|
+
factory: toolCheckFactories
|
|
39654
40562
|
}
|
|
39655
40563
|
];
|
|
39656
40564
|
const getProcessorRegistryEntry = (feature) => {
|
|
@@ -40000,6 +40908,7 @@ const GENERATION_STEP_GRAPH = [
|
|
|
40000
40908
|
id: "permissions",
|
|
40001
40909
|
...sharedWriteMeta("permissions")
|
|
40002
40910
|
},
|
|
40911
|
+
{ id: "checks" },
|
|
40003
40912
|
{
|
|
40004
40913
|
id: "rules",
|
|
40005
40914
|
...sharedWriteMeta("rules"),
|
|
@@ -40085,6 +40994,10 @@ async function generate(params) {
|
|
|
40085
40994
|
config,
|
|
40086
40995
|
logger
|
|
40087
40996
|
}),
|
|
40997
|
+
checks: () => generateChecksCore({
|
|
40998
|
+
config,
|
|
40999
|
+
logger
|
|
41000
|
+
}),
|
|
40088
41001
|
rules: () => generateRulesCore({
|
|
40089
41002
|
config,
|
|
40090
41003
|
logger,
|
|
@@ -40121,6 +41034,8 @@ async function generate(params) {
|
|
|
40121
41034
|
hooksPaths: get("hooks").paths,
|
|
40122
41035
|
permissionsCount: get("permissions").count,
|
|
40123
41036
|
permissionsPaths: get("permissions").paths,
|
|
41037
|
+
checksCount: get("checks").count,
|
|
41038
|
+
checksPaths: get("checks").paths,
|
|
40124
41039
|
skills: skillsResult.skills,
|
|
40125
41040
|
hasDiff
|
|
40126
41041
|
};
|
|
@@ -40489,6 +41404,44 @@ async function generatePermissionsCore(params) {
|
|
|
40489
41404
|
hasDiff
|
|
40490
41405
|
};
|
|
40491
41406
|
}
|
|
41407
|
+
async function generateChecksCore(params) {
|
|
41408
|
+
const { config, logger } = params;
|
|
41409
|
+
let totalCount = 0;
|
|
41410
|
+
const allPaths = [];
|
|
41411
|
+
let hasDiff = false;
|
|
41412
|
+
const supportedChecksTargets = ChecksProcessor.getToolTargets({ global: config.getGlobal() });
|
|
41413
|
+
const toolTargets = (0, es_toolkit.intersection)(config.getTargets(), supportedChecksTargets);
|
|
41414
|
+
warnUnsupportedTargets({
|
|
41415
|
+
config,
|
|
41416
|
+
supportedTargets: supportedChecksTargets,
|
|
41417
|
+
featureName: "checks",
|
|
41418
|
+
logger
|
|
41419
|
+
});
|
|
41420
|
+
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
41421
|
+
if (!config.getFeatures(toolTarget).includes("checks")) continue;
|
|
41422
|
+
const processor = new ChecksProcessor({
|
|
41423
|
+
outputRoot,
|
|
41424
|
+
inputRoot: config.getInputRoot(),
|
|
41425
|
+
toolTarget,
|
|
41426
|
+
global: config.getGlobal(),
|
|
41427
|
+
dryRun: config.isPreviewMode(),
|
|
41428
|
+
logger
|
|
41429
|
+
});
|
|
41430
|
+
const result = await processFeatureWithRulesyncFiles({
|
|
41431
|
+
config,
|
|
41432
|
+
processor,
|
|
41433
|
+
rulesyncFiles: await processor.loadRulesyncFiles()
|
|
41434
|
+
});
|
|
41435
|
+
totalCount += result.count;
|
|
41436
|
+
allPaths.push(...result.paths);
|
|
41437
|
+
if (result.hasDiff) hasDiff = true;
|
|
41438
|
+
}
|
|
41439
|
+
return {
|
|
41440
|
+
count: totalCount,
|
|
41441
|
+
paths: allPaths,
|
|
41442
|
+
hasDiff
|
|
41443
|
+
};
|
|
41444
|
+
}
|
|
40492
41445
|
//#endregion
|
|
40493
41446
|
//#region src/lib/import.ts
|
|
40494
41447
|
/**
|
|
@@ -40546,6 +41499,11 @@ async function importFromTool(params) {
|
|
|
40546
41499
|
config,
|
|
40547
41500
|
tool,
|
|
40548
41501
|
logger
|
|
41502
|
+
}),
|
|
41503
|
+
checksCount: await importChecksCore({
|
|
41504
|
+
config,
|
|
41505
|
+
tool,
|
|
41506
|
+
logger
|
|
40549
41507
|
})
|
|
40550
41508
|
};
|
|
40551
41509
|
}
|
|
@@ -40762,6 +41720,27 @@ async function importPermissionsCore(params) {
|
|
|
40762
41720
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} permissions file(s)`);
|
|
40763
41721
|
return writtenCount;
|
|
40764
41722
|
}
|
|
41723
|
+
async function importChecksCore(params) {
|
|
41724
|
+
const { config, tool, logger } = params;
|
|
41725
|
+
if (!config.getFeatures(tool).includes("checks")) return 0;
|
|
41726
|
+
const global = config.getGlobal();
|
|
41727
|
+
if (!ChecksProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
41728
|
+
const checksProcessor = new ChecksProcessor({
|
|
41729
|
+
outputRoot: config.getOutputRoots()[0] ?? ".",
|
|
41730
|
+
toolTarget: tool,
|
|
41731
|
+
global,
|
|
41732
|
+
logger
|
|
41733
|
+
});
|
|
41734
|
+
const toolFiles = await checksProcessor.loadToolFiles();
|
|
41735
|
+
if (toolFiles.length === 0) {
|
|
41736
|
+
logger.warn(`No check files found for ${tool}. Skipping import.`);
|
|
41737
|
+
return 0;
|
|
41738
|
+
}
|
|
41739
|
+
const rulesyncFiles = await checksProcessor.convertToolFilesToRulesyncFiles(toolFiles);
|
|
41740
|
+
const { count: writtenCount } = await checksProcessor.writeAiFiles(rulesyncFiles);
|
|
41741
|
+
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} check files`);
|
|
41742
|
+
return writtenCount;
|
|
41743
|
+
}
|
|
40765
41744
|
//#endregion
|
|
40766
41745
|
Object.defineProperty(exports, "ALL_FEATURES", {
|
|
40767
41746
|
enumerable: true,
|
|
@@ -40823,12 +41802,24 @@ Object.defineProperty(exports, "CLIError", {
|
|
|
40823
41802
|
return CLIError;
|
|
40824
41803
|
}
|
|
40825
41804
|
});
|
|
41805
|
+
Object.defineProperty(exports, "CODEXCLI_BASH_RULES_FILE_NAME", {
|
|
41806
|
+
enumerable: true,
|
|
41807
|
+
get: function() {
|
|
41808
|
+
return CODEXCLI_BASH_RULES_FILE_NAME;
|
|
41809
|
+
}
|
|
41810
|
+
});
|
|
40826
41811
|
Object.defineProperty(exports, "CODEXCLI_DIR", {
|
|
40827
41812
|
enumerable: true,
|
|
40828
41813
|
get: function() {
|
|
40829
41814
|
return CODEXCLI_DIR;
|
|
40830
41815
|
}
|
|
40831
41816
|
});
|
|
41817
|
+
Object.defineProperty(exports, "ChecksProcessor", {
|
|
41818
|
+
enumerable: true,
|
|
41819
|
+
get: function() {
|
|
41820
|
+
return ChecksProcessor;
|
|
41821
|
+
}
|
|
41822
|
+
});
|
|
40832
41823
|
Object.defineProperty(exports, "CommandsProcessor", {
|
|
40833
41824
|
enumerable: true,
|
|
40834
41825
|
get: function() {
|
|
@@ -40895,6 +41886,12 @@ Object.defineProperty(exports, "RULESYNC_AIIGNORE_RELATIVE_FILE_PATH", {
|
|
|
40895
41886
|
return RULESYNC_AIIGNORE_RELATIVE_FILE_PATH;
|
|
40896
41887
|
}
|
|
40897
41888
|
});
|
|
41889
|
+
Object.defineProperty(exports, "RULESYNC_CHECKS_RELATIVE_DIR_PATH", {
|
|
41890
|
+
enumerable: true,
|
|
41891
|
+
get: function() {
|
|
41892
|
+
return RULESYNC_CHECKS_RELATIVE_DIR_PATH;
|
|
41893
|
+
}
|
|
41894
|
+
});
|
|
40898
41895
|
Object.defineProperty(exports, "RULESYNC_COMMANDS_RELATIVE_DIR_PATH", {
|
|
40899
41896
|
enumerable: true,
|
|
40900
41897
|
get: function() {
|
|
@@ -41039,6 +42036,18 @@ Object.defineProperty(exports, "RulesProcessor", {
|
|
|
41039
42036
|
return RulesProcessor;
|
|
41040
42037
|
}
|
|
41041
42038
|
});
|
|
42039
|
+
Object.defineProperty(exports, "RulesyncCheck", {
|
|
42040
|
+
enumerable: true,
|
|
42041
|
+
get: function() {
|
|
42042
|
+
return RulesyncCheck;
|
|
42043
|
+
}
|
|
42044
|
+
});
|
|
42045
|
+
Object.defineProperty(exports, "RulesyncCheckFrontmatterSchema", {
|
|
42046
|
+
enumerable: true,
|
|
42047
|
+
get: function() {
|
|
42048
|
+
return RulesyncCheckFrontmatterSchema;
|
|
42049
|
+
}
|
|
42050
|
+
});
|
|
41042
42051
|
Object.defineProperty(exports, "RulesyncCommand", {
|
|
41043
42052
|
enumerable: true,
|
|
41044
42053
|
get: function() {
|
|
@@ -41114,7 +42123,7 @@ Object.defineProperty(exports, "RulesyncSubagentFrontmatterSchema", {
|
|
|
41114
42123
|
Object.defineProperty(exports, "SKILL_FILE_NAME", {
|
|
41115
42124
|
enumerable: true,
|
|
41116
42125
|
get: function() {
|
|
41117
|
-
return SKILL_FILE_NAME;
|
|
42126
|
+
return SKILL_FILE_NAME$1;
|
|
41118
42127
|
}
|
|
41119
42128
|
});
|
|
41120
42129
|
Object.defineProperty(exports, "SkillsProcessor", {
|