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
|
@@ -12,6 +12,7 @@ import { parse as parse$1, stringify } from "smol-toml";
|
|
|
12
12
|
import matter from "gray-matter";
|
|
13
13
|
import { YAMLException, dump, load } from "js-yaml";
|
|
14
14
|
import { omit } from "es-toolkit/object";
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
15
16
|
import { encode } from "@toon-format/toon";
|
|
16
17
|
//#region src/types/features.ts
|
|
17
18
|
const ALL_FEATURES = [
|
|
@@ -22,7 +23,8 @@ const ALL_FEATURES = [
|
|
|
22
23
|
"commands",
|
|
23
24
|
"skills",
|
|
24
25
|
"hooks",
|
|
25
|
-
"permissions"
|
|
26
|
+
"permissions",
|
|
27
|
+
"checks"
|
|
26
28
|
];
|
|
27
29
|
const ALL_FEATURES_WITH_WILDCARD = [...ALL_FEATURES, "*"];
|
|
28
30
|
const FeatureSchema = z.enum(ALL_FEATURES);
|
|
@@ -96,6 +98,7 @@ const RULESYNC_RELATIVE_DIR_PATH = ".rulesync";
|
|
|
96
98
|
const RULESYNC_RULES_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "rules");
|
|
97
99
|
const RULESYNC_COMMANDS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "commands");
|
|
98
100
|
const RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "subagents");
|
|
101
|
+
const RULESYNC_CHECKS_RELATIVE_DIR_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "checks");
|
|
99
102
|
const RULESYNC_MCP_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "mcp.json");
|
|
100
103
|
const RULESYNC_HOOKS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "hooks.json");
|
|
101
104
|
const RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH = join$1(RULESYNC_RELATIVE_DIR_PATH, "permissions.json");
|
|
@@ -361,6 +364,7 @@ const permissionsProcessorToolTargetTuple = [
|
|
|
361
364
|
"warp",
|
|
362
365
|
"zed"
|
|
363
366
|
];
|
|
367
|
+
const checksProcessorToolTargetTuple = ["amp"];
|
|
364
368
|
//#endregion
|
|
365
369
|
//#region src/types/tool-targets.ts
|
|
366
370
|
const ALL_TOOL_TARGETS = [...new Set([
|
|
@@ -371,7 +375,8 @@ const ALL_TOOL_TARGETS = [...new Set([
|
|
|
371
375
|
subagentsProcessorToolTargetTuple,
|
|
372
376
|
skillsProcessorToolTargetTuple,
|
|
373
377
|
hooksProcessorToolTargetTuple,
|
|
374
|
-
permissionsProcessorToolTargetTuple
|
|
378
|
+
permissionsProcessorToolTargetTuple,
|
|
379
|
+
checksProcessorToolTargetTuple
|
|
375
380
|
].flat())];
|
|
376
381
|
const ALL_TOOL_TARGETS_WITH_WILDCARD = [...ALL_TOOL_TARGETS, "*"];
|
|
377
382
|
const ToolTargetSchema = z.enum(ALL_TOOL_TARGETS);
|
|
@@ -1445,7 +1450,7 @@ function isPlainObject$1(value) {
|
|
|
1445
1450
|
/**
|
|
1446
1451
|
* Type guard to check if a value is an array of strings.
|
|
1447
1452
|
*/
|
|
1448
|
-
function isStringArray(value) {
|
|
1453
|
+
function isStringArray$1(value) {
|
|
1449
1454
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1450
1455
|
}
|
|
1451
1456
|
//#endregion
|
|
@@ -1693,13 +1698,17 @@ var FeatureProcessor = class {
|
|
|
1693
1698
|
}
|
|
1694
1699
|
};
|
|
1695
1700
|
//#endregion
|
|
1696
|
-
//#region src/constants/
|
|
1697
|
-
const
|
|
1698
|
-
const
|
|
1699
|
-
const
|
|
1700
|
-
const
|
|
1701
|
-
const
|
|
1702
|
-
const
|
|
1701
|
+
//#region src/constants/amp-paths.ts
|
|
1702
|
+
const AMP_DIR = ".amp";
|
|
1703
|
+
const AMP_GLOBAL_DIR = join(".config", "amp");
|
|
1704
|
+
const AMP_AGENTS_DIR = ".agents";
|
|
1705
|
+
const AMP_SKILLS_PROJECT_DIR = join(AMP_AGENTS_DIR, "skills");
|
|
1706
|
+
const AMP_SKILLS_GLOBAL_DIR = join(".config", "agents", "skills");
|
|
1707
|
+
const AMP_CHECKS_PROJECT_DIR = join(AMP_AGENTS_DIR, "checks");
|
|
1708
|
+
const AMP_CHECKS_GLOBAL_DIR = join(AMP_GLOBAL_DIR, "checks");
|
|
1709
|
+
const AMP_RULE_FILE_NAME = "AGENTS.md";
|
|
1710
|
+
const AMP_SETTINGS_FILE_NAME = "settings.json";
|
|
1711
|
+
const AMP_SETTINGS_JSONC_FILE_NAME = "settings.jsonc";
|
|
1703
1712
|
//#endregion
|
|
1704
1713
|
//#region src/types/ai-file.ts
|
|
1705
1714
|
var AiFile = class {
|
|
@@ -1773,6 +1782,414 @@ var AiFile = class {
|
|
|
1773
1782
|
}
|
|
1774
1783
|
};
|
|
1775
1784
|
//#endregion
|
|
1785
|
+
//#region src/types/rulesync-file.ts
|
|
1786
|
+
var RulesyncFile = class extends AiFile {
|
|
1787
|
+
static async fromFile(_params) {
|
|
1788
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1789
|
+
}
|
|
1790
|
+
};
|
|
1791
|
+
//#endregion
|
|
1792
|
+
//#region src/features/checks/rulesync-check.ts
|
|
1793
|
+
const RulesyncCheckFrontmatterSchema = z.looseObject({
|
|
1794
|
+
targets: z._default(RulesyncTargetsSchema, ["*"]),
|
|
1795
|
+
description: z.optional(z.string()),
|
|
1796
|
+
severity: z.optional(z.enum([
|
|
1797
|
+
"low",
|
|
1798
|
+
"medium",
|
|
1799
|
+
"high",
|
|
1800
|
+
"critical"
|
|
1801
|
+
])),
|
|
1802
|
+
tools: z.optional(z.array(z.string()))
|
|
1803
|
+
});
|
|
1804
|
+
var RulesyncCheck = class RulesyncCheck extends RulesyncFile {
|
|
1805
|
+
frontmatter;
|
|
1806
|
+
body;
|
|
1807
|
+
constructor({ frontmatter, body, ...rest }) {
|
|
1808
|
+
const parseResult = RulesyncCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1809
|
+
if (!parseResult.success && rest.validate !== false) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(parseResult.error)}`);
|
|
1810
|
+
const parsedFrontmatter = parseResult.success ? {
|
|
1811
|
+
...frontmatter,
|
|
1812
|
+
...parseResult.data
|
|
1813
|
+
} : {
|
|
1814
|
+
...frontmatter,
|
|
1815
|
+
targets: frontmatter?.targets ?? ["*"]
|
|
1816
|
+
};
|
|
1817
|
+
super({
|
|
1818
|
+
...rest,
|
|
1819
|
+
fileContent: stringifyFrontmatter(body, parsedFrontmatter)
|
|
1820
|
+
});
|
|
1821
|
+
this.frontmatter = parsedFrontmatter;
|
|
1822
|
+
this.body = body;
|
|
1823
|
+
}
|
|
1824
|
+
static getSettablePaths() {
|
|
1825
|
+
return { relativeDirPath: RULESYNC_CHECKS_RELATIVE_DIR_PATH };
|
|
1826
|
+
}
|
|
1827
|
+
getFrontmatter() {
|
|
1828
|
+
return this.frontmatter;
|
|
1829
|
+
}
|
|
1830
|
+
getBody() {
|
|
1831
|
+
return this.body;
|
|
1832
|
+
}
|
|
1833
|
+
validate() {
|
|
1834
|
+
if (!this.frontmatter) return {
|
|
1835
|
+
success: true,
|
|
1836
|
+
error: null
|
|
1837
|
+
};
|
|
1838
|
+
const result = RulesyncCheckFrontmatterSchema.safeParse(this.frontmatter);
|
|
1839
|
+
if (result.success) return {
|
|
1840
|
+
success: true,
|
|
1841
|
+
error: null
|
|
1842
|
+
};
|
|
1843
|
+
else return {
|
|
1844
|
+
success: false,
|
|
1845
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
1846
|
+
};
|
|
1847
|
+
}
|
|
1848
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath }) {
|
|
1849
|
+
const filePath = join(outputRoot, RULESYNC_CHECKS_RELATIVE_DIR_PATH, relativeFilePath);
|
|
1850
|
+
const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
1851
|
+
if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${filePath}. Rulesync files must begin with a YAML frontmatter block delimited by '---'.`);
|
|
1852
|
+
const result = RulesyncCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1853
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
|
|
1854
|
+
const filename = basename(relativeFilePath);
|
|
1855
|
+
return new RulesyncCheck({
|
|
1856
|
+
outputRoot,
|
|
1857
|
+
relativeDirPath: this.getSettablePaths().relativeDirPath,
|
|
1858
|
+
relativeFilePath: filename,
|
|
1859
|
+
frontmatter: result.data,
|
|
1860
|
+
body: content.trim()
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
};
|
|
1864
|
+
//#endregion
|
|
1865
|
+
//#region src/types/tool-file.ts
|
|
1866
|
+
var ToolFile = class extends AiFile {};
|
|
1867
|
+
//#endregion
|
|
1868
|
+
//#region src/features/checks/tool-check.ts
|
|
1869
|
+
var ToolCheck = class extends ToolFile {
|
|
1870
|
+
static getSettablePaths(_options = {}) {
|
|
1871
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1872
|
+
}
|
|
1873
|
+
static async fromFile(_params) {
|
|
1874
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1875
|
+
}
|
|
1876
|
+
/**
|
|
1877
|
+
* Create a minimal instance for deletion purposes.
|
|
1878
|
+
* This method does not read or parse file content, making it safe to use
|
|
1879
|
+
* even when files have old/incompatible formats.
|
|
1880
|
+
*/
|
|
1881
|
+
static forDeletion(_params) {
|
|
1882
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1883
|
+
}
|
|
1884
|
+
static fromRulesyncCheck(_params) {
|
|
1885
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1886
|
+
}
|
|
1887
|
+
static isTargetedByRulesyncCheck(_rulesyncCheck) {
|
|
1888
|
+
throw new Error("Please implement this method in the subclass.");
|
|
1889
|
+
}
|
|
1890
|
+
static isTargetedByRulesyncCheckDefault({ rulesyncCheck, toolTarget }) {
|
|
1891
|
+
const targets = rulesyncCheck.getFrontmatter().targets;
|
|
1892
|
+
if (!targets) return true;
|
|
1893
|
+
if (targets.includes("*")) return true;
|
|
1894
|
+
if (targets.includes(toolTarget)) return true;
|
|
1895
|
+
return false;
|
|
1896
|
+
}
|
|
1897
|
+
static filterToolSpecificSection(rawSection, excludeFields) {
|
|
1898
|
+
const filtered = {};
|
|
1899
|
+
for (const [key, value] of Object.entries(rawSection)) if (!excludeFields.includes(key)) filtered[key] = value;
|
|
1900
|
+
return filtered;
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
//#endregion
|
|
1904
|
+
//#region src/features/checks/amp-check.ts
|
|
1905
|
+
const AmpCheckFrontmatterSchema = z.looseObject({
|
|
1906
|
+
name: z.string(),
|
|
1907
|
+
description: z.optional(z.string()),
|
|
1908
|
+
"severity-default": z.optional(z.enum([
|
|
1909
|
+
"low",
|
|
1910
|
+
"medium",
|
|
1911
|
+
"high",
|
|
1912
|
+
"critical"
|
|
1913
|
+
])),
|
|
1914
|
+
tools: z.optional(z.array(z.string()))
|
|
1915
|
+
});
|
|
1916
|
+
/**
|
|
1917
|
+
* Represents an Amp code review check.
|
|
1918
|
+
*
|
|
1919
|
+
* Amp natively reads code review checks as Markdown files with YAML frontmatter,
|
|
1920
|
+
* scoped to the project (`.agents/checks/`) and user-wide (`~/.config/amp/checks/`).
|
|
1921
|
+
* Each check runs as a per-check subagent during code review.
|
|
1922
|
+
* @see https://ampcode.com/manual
|
|
1923
|
+
*/
|
|
1924
|
+
var AmpCheck = class AmpCheck extends ToolCheck {
|
|
1925
|
+
frontmatter;
|
|
1926
|
+
body;
|
|
1927
|
+
constructor({ frontmatter, body, fileContent, ...rest }) {
|
|
1928
|
+
if (rest.validate !== false) {
|
|
1929
|
+
const result = AmpCheckFrontmatterSchema.safeParse(frontmatter);
|
|
1930
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
1931
|
+
}
|
|
1932
|
+
super({
|
|
1933
|
+
...rest,
|
|
1934
|
+
fileContent: fileContent ?? stringifyFrontmatter(body, frontmatter)
|
|
1935
|
+
});
|
|
1936
|
+
this.frontmatter = frontmatter;
|
|
1937
|
+
this.body = body;
|
|
1938
|
+
}
|
|
1939
|
+
static getSettablePaths({ global = false } = {}) {
|
|
1940
|
+
return { relativeDirPath: global ? AMP_CHECKS_GLOBAL_DIR : AMP_CHECKS_PROJECT_DIR };
|
|
1941
|
+
}
|
|
1942
|
+
getFrontmatter() {
|
|
1943
|
+
return this.frontmatter;
|
|
1944
|
+
}
|
|
1945
|
+
getBody() {
|
|
1946
|
+
return this.body;
|
|
1947
|
+
}
|
|
1948
|
+
toRulesyncCheck() {
|
|
1949
|
+
const { name: _name, description, "severity-default": severityDefault, tools, ...restFields } = this.frontmatter;
|
|
1950
|
+
return new RulesyncCheck({
|
|
1951
|
+
outputRoot: ".",
|
|
1952
|
+
frontmatter: {
|
|
1953
|
+
targets: ["*"],
|
|
1954
|
+
...description !== void 0 && { description },
|
|
1955
|
+
...severityDefault !== void 0 && { severity: severityDefault },
|
|
1956
|
+
...tools !== void 0 && { tools },
|
|
1957
|
+
...restFields
|
|
1958
|
+
},
|
|
1959
|
+
body: this.body,
|
|
1960
|
+
relativeDirPath: RULESYNC_CHECKS_RELATIVE_DIR_PATH,
|
|
1961
|
+
relativeFilePath: this.getRelativeFilePath(),
|
|
1962
|
+
validate: true
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
static fromRulesyncCheck({ outputRoot = process.cwd(), rulesyncCheck, validate = true, global = false }) {
|
|
1966
|
+
const rulesyncFrontmatter = rulesyncCheck.getFrontmatter();
|
|
1967
|
+
const relativeFilePath = rulesyncCheck.getRelativeFilePath();
|
|
1968
|
+
const name = basename(relativeFilePath, ".md");
|
|
1969
|
+
const { targets: _targets, description, severity, tools, ...restFields } = rulesyncFrontmatter;
|
|
1970
|
+
const toolTargetKeys = new Set(ALL_TOOL_TARGETS);
|
|
1971
|
+
const passthroughFields = Object.fromEntries(Object.entries(restFields).filter(([key]) => !toolTargetKeys.has(key) && key !== "name"));
|
|
1972
|
+
const ampSection = this.filterToolSpecificSection(rulesyncFrontmatter.amp ?? {}, ["name"]);
|
|
1973
|
+
const rawAmpFrontmatter = {
|
|
1974
|
+
name,
|
|
1975
|
+
...description !== void 0 && { description },
|
|
1976
|
+
...severity !== void 0 && { "severity-default": severity },
|
|
1977
|
+
...tools !== void 0 && { tools },
|
|
1978
|
+
...passthroughFields,
|
|
1979
|
+
...ampSection
|
|
1980
|
+
};
|
|
1981
|
+
const result = AmpCheckFrontmatterSchema.safeParse(rawAmpFrontmatter);
|
|
1982
|
+
if (!result.success) throw new Error(`Invalid amp check frontmatter in ${relativeFilePath}: ${formatError(result.error)}`);
|
|
1983
|
+
const ampFrontmatter = result.data;
|
|
1984
|
+
const body = rulesyncCheck.getBody();
|
|
1985
|
+
const fileContent = stringifyFrontmatter(body, ampFrontmatter);
|
|
1986
|
+
const paths = this.getSettablePaths({ global });
|
|
1987
|
+
return new AmpCheck({
|
|
1988
|
+
outputRoot,
|
|
1989
|
+
frontmatter: ampFrontmatter,
|
|
1990
|
+
body,
|
|
1991
|
+
relativeDirPath: paths.relativeDirPath,
|
|
1992
|
+
relativeFilePath,
|
|
1993
|
+
fileContent,
|
|
1994
|
+
validate
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
validate() {
|
|
1998
|
+
if (!this.frontmatter) return {
|
|
1999
|
+
success: true,
|
|
2000
|
+
error: null
|
|
2001
|
+
};
|
|
2002
|
+
const result = AmpCheckFrontmatterSchema.safeParse(this.frontmatter);
|
|
2003
|
+
if (result.success) return {
|
|
2004
|
+
success: true,
|
|
2005
|
+
error: null
|
|
2006
|
+
};
|
|
2007
|
+
else return {
|
|
2008
|
+
success: false,
|
|
2009
|
+
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
2010
|
+
};
|
|
2011
|
+
}
|
|
2012
|
+
static isTargetedByRulesyncCheck(rulesyncCheck) {
|
|
2013
|
+
return this.isTargetedByRulesyncCheckDefault({
|
|
2014
|
+
rulesyncCheck,
|
|
2015
|
+
toolTarget: "amp"
|
|
2016
|
+
});
|
|
2017
|
+
}
|
|
2018
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
2019
|
+
const paths = this.getSettablePaths({ global });
|
|
2020
|
+
const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
2021
|
+
const fileContent = await readFileContent(filePath);
|
|
2022
|
+
const { frontmatter, body: content } = parseFrontmatter(fileContent, filePath);
|
|
2023
|
+
const result = AmpCheckFrontmatterSchema.safeParse(frontmatter);
|
|
2024
|
+
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
2025
|
+
return new AmpCheck({
|
|
2026
|
+
outputRoot,
|
|
2027
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2028
|
+
relativeFilePath,
|
|
2029
|
+
frontmatter: result.data,
|
|
2030
|
+
body: content.trim(),
|
|
2031
|
+
fileContent,
|
|
2032
|
+
validate
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath }) {
|
|
2036
|
+
return new AmpCheck({
|
|
2037
|
+
outputRoot,
|
|
2038
|
+
relativeDirPath,
|
|
2039
|
+
relativeFilePath,
|
|
2040
|
+
frontmatter: { name: "" },
|
|
2041
|
+
body: "",
|
|
2042
|
+
fileContent: "",
|
|
2043
|
+
validate: false
|
|
2044
|
+
});
|
|
2045
|
+
}
|
|
2046
|
+
};
|
|
2047
|
+
//#endregion
|
|
2048
|
+
//#region src/features/checks/checks-processor.ts
|
|
2049
|
+
const ChecksProcessorToolTargetSchema = z.enum(checksProcessorToolTargetTuple);
|
|
2050
|
+
/**
|
|
2051
|
+
* Factory Map mapping tool targets to their check factories.
|
|
2052
|
+
* Using Map to preserve insertion order for consistent iteration.
|
|
2053
|
+
*/
|
|
2054
|
+
const toolCheckFactories = /* @__PURE__ */ new Map([["amp", {
|
|
2055
|
+
class: AmpCheck,
|
|
2056
|
+
meta: {
|
|
2057
|
+
supportsGlobal: true,
|
|
2058
|
+
filePattern: "*.md"
|
|
2059
|
+
}
|
|
2060
|
+
}]]);
|
|
2061
|
+
const defaultGetFactory$6 = (target) => {
|
|
2062
|
+
const factory = toolCheckFactories.get(target);
|
|
2063
|
+
if (!factory) throw new Error(`Unsupported tool target: ${target}`);
|
|
2064
|
+
return factory;
|
|
2065
|
+
};
|
|
2066
|
+
const allToolTargetKeys$5 = [...toolCheckFactories.keys()];
|
|
2067
|
+
const checksProcessorToolTargets = allToolTargetKeys$5;
|
|
2068
|
+
const checksProcessorToolTargetsGlobal = allToolTargetKeys$5.filter((target) => {
|
|
2069
|
+
return toolCheckFactories.get(target)?.meta.supportsGlobal ?? false;
|
|
2070
|
+
});
|
|
2071
|
+
var ChecksProcessor = class extends FeatureProcessor {
|
|
2072
|
+
toolTarget;
|
|
2073
|
+
global;
|
|
2074
|
+
getFactory;
|
|
2075
|
+
constructor({ outputRoot = process.cwd(), inputRoot = process.cwd(), toolTarget, global = false, getFactory = defaultGetFactory$6, dryRun = false, logger }) {
|
|
2076
|
+
super({
|
|
2077
|
+
outputRoot,
|
|
2078
|
+
inputRoot,
|
|
2079
|
+
dryRun,
|
|
2080
|
+
logger
|
|
2081
|
+
});
|
|
2082
|
+
const result = ChecksProcessorToolTargetSchema.safeParse(toolTarget);
|
|
2083
|
+
if (!result.success) throw new Error(`Invalid tool target for ChecksProcessor: ${toolTarget}. ${formatError(result.error)}`);
|
|
2084
|
+
this.toolTarget = result.data;
|
|
2085
|
+
this.global = global;
|
|
2086
|
+
this.getFactory = getFactory;
|
|
2087
|
+
}
|
|
2088
|
+
async convertRulesyncFilesToToolFiles(rulesyncFiles) {
|
|
2089
|
+
const rulesyncChecks = rulesyncFiles.filter((file) => file instanceof RulesyncCheck);
|
|
2090
|
+
const factory = this.getFactory(this.toolTarget);
|
|
2091
|
+
return rulesyncChecks.filter((rulesyncCheck) => factory.class.isTargetedByRulesyncCheck(rulesyncCheck)).map((rulesyncCheck) => factory.class.fromRulesyncCheck({
|
|
2092
|
+
outputRoot: this.outputRoot,
|
|
2093
|
+
relativeDirPath: RulesyncCheck.getSettablePaths().relativeDirPath,
|
|
2094
|
+
rulesyncCheck,
|
|
2095
|
+
global: this.global
|
|
2096
|
+
}));
|
|
2097
|
+
}
|
|
2098
|
+
async convertToolFilesToRulesyncFiles(toolFiles) {
|
|
2099
|
+
return toolFiles.filter((file) => file instanceof ToolCheck).map((toolCheck) => toolCheck.toRulesyncCheck());
|
|
2100
|
+
}
|
|
2101
|
+
/**
|
|
2102
|
+
* Implementation of abstract method from Processor
|
|
2103
|
+
* Load and parse rulesync check files from .rulesync/checks/ directory
|
|
2104
|
+
*/
|
|
2105
|
+
async loadRulesyncFiles() {
|
|
2106
|
+
const checksDir = join(this.inputRoot, RulesyncCheck.getSettablePaths().relativeDirPath);
|
|
2107
|
+
if (!await directoryExists(checksDir)) {
|
|
2108
|
+
this.logger.debug(`Rulesync checks directory not found: ${checksDir}`);
|
|
2109
|
+
return [];
|
|
2110
|
+
}
|
|
2111
|
+
const mdFiles = (await listDirectoryFiles(checksDir)).filter((file) => file.endsWith(".md"));
|
|
2112
|
+
if (mdFiles.length === 0) {
|
|
2113
|
+
this.logger.debug(`No markdown files found in rulesync checks directory: ${checksDir}`);
|
|
2114
|
+
return [];
|
|
2115
|
+
}
|
|
2116
|
+
this.logger.debug(`Found ${mdFiles.length} check files in ${checksDir}`);
|
|
2117
|
+
const rulesyncChecks = [];
|
|
2118
|
+
for (const mdFile of mdFiles) {
|
|
2119
|
+
const filepath = join(checksDir, mdFile);
|
|
2120
|
+
try {
|
|
2121
|
+
const rulesyncCheck = await RulesyncCheck.fromFile({
|
|
2122
|
+
outputRoot: this.inputRoot,
|
|
2123
|
+
relativeFilePath: mdFile,
|
|
2124
|
+
validate: true
|
|
2125
|
+
});
|
|
2126
|
+
rulesyncChecks.push(rulesyncCheck);
|
|
2127
|
+
this.logger.debug(`Successfully loaded check: ${mdFile}`);
|
|
2128
|
+
} catch (error) {
|
|
2129
|
+
this.logger.warn(`Failed to load check file ${filepath}: ${formatError(error)}`);
|
|
2130
|
+
continue;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
this.logger.debug(`Successfully loaded ${rulesyncChecks.length} rulesync checks`);
|
|
2134
|
+
return rulesyncChecks;
|
|
2135
|
+
}
|
|
2136
|
+
/**
|
|
2137
|
+
* Implementation of abstract method from Processor
|
|
2138
|
+
* Load tool-specific check files and parse them into ToolCheck instances
|
|
2139
|
+
*/
|
|
2140
|
+
async loadToolFiles({ forDeletion = false } = {}) {
|
|
2141
|
+
const factory = this.getFactory(this.toolTarget);
|
|
2142
|
+
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
2143
|
+
const baseDir = join(this.outputRoot, paths.relativeDirPath);
|
|
2144
|
+
const checkFilePaths = await findFilesByGlobs(join(baseDir, factory.meta.filePattern));
|
|
2145
|
+
const toRelativeFilePath = (path) => relative(baseDir, path);
|
|
2146
|
+
if (forDeletion) return checkFilePaths.map((path) => factory.class.forDeletion({
|
|
2147
|
+
outputRoot: this.outputRoot,
|
|
2148
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2149
|
+
relativeFilePath: toRelativeFilePath(path),
|
|
2150
|
+
global: this.global
|
|
2151
|
+
})).filter((check) => check.isDeletable());
|
|
2152
|
+
const loaded = await Promise.all(checkFilePaths.map((path) => factory.class.fromFile({
|
|
2153
|
+
outputRoot: this.outputRoot,
|
|
2154
|
+
relativeDirPath: paths.relativeDirPath,
|
|
2155
|
+
relativeFilePath: toRelativeFilePath(path),
|
|
2156
|
+
global: this.global
|
|
2157
|
+
})));
|
|
2158
|
+
this.logger.debug(`Successfully loaded ${loaded.length} ${this.toolTarget} checks from ${paths.relativeDirPath}`);
|
|
2159
|
+
return loaded;
|
|
2160
|
+
}
|
|
2161
|
+
/**
|
|
2162
|
+
* Implementation of abstract method from FeatureProcessor
|
|
2163
|
+
* Return the tool targets that this processor supports
|
|
2164
|
+
*/
|
|
2165
|
+
static getToolTargets({ global = false } = {}) {
|
|
2166
|
+
if (global) return [...checksProcessorToolTargetsGlobal];
|
|
2167
|
+
return [...checksProcessorToolTargets];
|
|
2168
|
+
}
|
|
2169
|
+
static getToolTargetsSimulated() {
|
|
2170
|
+
return [];
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Get the factory for a specific tool target.
|
|
2174
|
+
* This is a static version of the internal getFactory for external use.
|
|
2175
|
+
* @param target - The tool target. Must be a valid ChecksProcessorToolTarget.
|
|
2176
|
+
* @returns The factory for the target, or undefined if not found.
|
|
2177
|
+
*/
|
|
2178
|
+
static getFactory(target) {
|
|
2179
|
+
const result = ChecksProcessorToolTargetSchema.safeParse(target);
|
|
2180
|
+
if (!result.success) return;
|
|
2181
|
+
return toolCheckFactories.get(result.data);
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2184
|
+
//#endregion
|
|
2185
|
+
//#region src/constants/agentsmd-paths.ts
|
|
2186
|
+
const AGENTSMD_DIR = ".agents";
|
|
2187
|
+
const AGENTSMD_MEMORIES_DIR_PATH = join(AGENTSMD_DIR, "memories");
|
|
2188
|
+
const AGENTSMD_COMMANDS_DIR_PATH = join(AGENTSMD_DIR, "commands");
|
|
2189
|
+
const AGENTSMD_SKILLS_DIR_PATH = join(AGENTSMD_DIR, "skills");
|
|
2190
|
+
const AGENTSMD_SUBAGENTS_DIR_PATH = join(AGENTSMD_DIR, "subagents");
|
|
2191
|
+
const AGENTSMD_RULE_FILE_NAME = "AGENTS.md";
|
|
2192
|
+
//#endregion
|
|
1776
2193
|
//#region src/features/commands/tool-command.ts
|
|
1777
2194
|
/**
|
|
1778
2195
|
* Abstract base class for AI development tool-specific command formats.
|
|
@@ -2020,13 +2437,6 @@ const AntigravityCommandFrontmatterSchema = z.looseObject({
|
|
|
2020
2437
|
...AntigravityWorkflowFrontmatterSchema.shape
|
|
2021
2438
|
});
|
|
2022
2439
|
//#endregion
|
|
2023
|
-
//#region src/types/rulesync-file.ts
|
|
2024
|
-
var RulesyncFile = class extends AiFile {
|
|
2025
|
-
static async fromFile(_params) {
|
|
2026
|
-
throw new Error("Please implement this method in the subclass.");
|
|
2027
|
-
}
|
|
2028
|
-
};
|
|
2029
|
-
//#endregion
|
|
2030
2440
|
//#region src/features/commands/rulesync-command.ts
|
|
2031
2441
|
const RulesyncCommandFrontmatterSchema = z.looseObject({
|
|
2032
2442
|
targets: z._default(RulesyncTargetsSchema, ["*"]),
|
|
@@ -3087,135 +3497,118 @@ var CursorCommand = class CursorCommand extends ToolCommand {
|
|
|
3087
3497
|
//#endregion
|
|
3088
3498
|
//#region src/constants/devin-paths.ts
|
|
3089
3499
|
const DEVIN_DIR = ".devin";
|
|
3090
|
-
const CODEIUM_WINDSURF_DIR = join(".codeium", "windsurf");
|
|
3091
|
-
const DEVIN_WORKFLOWS_DIR_PATH = join(DEVIN_DIR, "workflows");
|
|
3092
3500
|
const DEVIN_SKILLS_DIR_PATH = join(DEVIN_DIR, "skills");
|
|
3093
3501
|
const DEVIN_AGENTS_DIR_PATH = join(DEVIN_DIR, "agents");
|
|
3094
3502
|
const DEVIN_GLOBAL_CONFIG_DIR_PATH = join(".config", "devin");
|
|
3095
3503
|
const DEVIN_GLOBAL_AGENTS_DIR_PATH = join(DEVIN_GLOBAL_CONFIG_DIR_PATH, "agents");
|
|
3096
3504
|
const DEVIN_GLOBAL_SKILLS_DIR_PATH = join(DEVIN_GLOBAL_CONFIG_DIR_PATH, "skills");
|
|
3097
|
-
const CODEIUM_WINDSURF_GLOBAL_WORKFLOWS_DIR_PATH = join(CODEIUM_WINDSURF_DIR, "global_workflows");
|
|
3098
3505
|
const DEVIN_CONFIG_FILE_NAME = "config.json";
|
|
3099
3506
|
const DEVIN_HOOKS_V1_FILE_NAME = "hooks.v1.json";
|
|
3100
3507
|
const DEVIN_GLOBAL_AGENTS_FILE_NAME = "AGENTS.md";
|
|
3101
3508
|
const DEVIN_IGNORE_FILE_NAME = ".devinignore";
|
|
3102
3509
|
const DEVIN_LEGACY_IGNORE_FILE_NAME = ".codeiumignore";
|
|
3103
3510
|
//#endregion
|
|
3511
|
+
//#region src/constants/general.ts
|
|
3512
|
+
const SKILL_FILE_NAME$1 = "SKILL.md";
|
|
3513
|
+
//#endregion
|
|
3514
|
+
//#region src/features/commands/command-skill-ownership.ts
|
|
3515
|
+
/**
|
|
3516
|
+
* Slug used for the per-command `<slug>/SKILL.md` directory when a tool's
|
|
3517
|
+
* commands are emitted onto its skills surface (Devin, Hermes Agent).
|
|
3518
|
+
*/
|
|
3519
|
+
function commandSlug(relativeFilePath) {
|
|
3520
|
+
return basename(relativeFilePath, ".md").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
3521
|
+
}
|
|
3522
|
+
/**
|
|
3523
|
+
* Whether a rulesync command exists whose slug matches `dirName`.
|
|
3524
|
+
*
|
|
3525
|
+
* Used by the skills-surface `isDirOwned` hooks of tools whose commands are
|
|
3526
|
+
* emitted as `<slug>/SKILL.md` into the skills tree: a directory matching a
|
|
3527
|
+
* current command slug is owned by the commands feature, so the skills
|
|
3528
|
+
* feature must neither import it as a skill nor delete it as an orphan
|
|
3529
|
+
* skill. Once the command is removed from `.rulesync/commands/`, the
|
|
3530
|
+
* directory stops matching and the skills feature cleans it up as a regular
|
|
3531
|
+
* orphan.
|
|
3532
|
+
*/
|
|
3533
|
+
async function rulesyncCommandSlugExists({ inputRoot, dirName }) {
|
|
3534
|
+
return (await findFilesByGlobs(join(inputRoot, RULESYNC_COMMANDS_RELATIVE_DIR_PATH, "**", "*.md"))).some((filePath) => commandSlug(basename(filePath)) === dirName);
|
|
3535
|
+
}
|
|
3536
|
+
//#endregion
|
|
3104
3537
|
//#region src/features/commands/devin-command.ts
|
|
3105
|
-
|
|
3538
|
+
function commandSkillContent$1(rulesyncCommand) {
|
|
3539
|
+
const slug = commandSlug(rulesyncCommand.getRelativeFilePath());
|
|
3540
|
+
const description = rulesyncCommand.getFrontmatter().description ?? `${slug} command`;
|
|
3541
|
+
return stringifyFrontmatter(rulesyncCommand.getBody().trim(), {
|
|
3542
|
+
name: slug,
|
|
3543
|
+
description
|
|
3544
|
+
});
|
|
3545
|
+
}
|
|
3106
3546
|
/**
|
|
3107
|
-
* Represents a Devin
|
|
3108
|
-
*
|
|
3109
|
-
*
|
|
3110
|
-
*
|
|
3111
|
-
*
|
|
3547
|
+
* Represents a Devin slash command, emitted as a Devin Skill.
|
|
3548
|
+
*
|
|
3549
|
+
* Devin's extensibility docs no longer document a standalone
|
|
3550
|
+
* workflows/commands component — reusable prompts invoked as slash commands
|
|
3551
|
+
* are Skills (`/name`). Commands are therefore emitted onto the native skills
|
|
3552
|
+
* surface, one `SKILL.md` per command: `.devin/skills/<slug>/SKILL.md`
|
|
3553
|
+
* (project) and `~/.config/devin/skills/<slug>/SKILL.md` (global). The legacy
|
|
3554
|
+
* Windsurf/Cascade-era `.devin/workflows/` and
|
|
3555
|
+
* `~/.codeium/windsurf/global_workflows/` locations are no longer emitted.
|
|
3556
|
+
*
|
|
3557
|
+
* Import and deletion are intentionally no-ops for this target: the skills
|
|
3558
|
+
* feature owns the `.devin/skills/` tree, so importing it as commands would
|
|
3559
|
+
* double-import every skill (mirrors the Hermes Agent commands target).
|
|
3560
|
+
*
|
|
3561
|
+
* @see https://docs.devin.ai/cli/extensibility
|
|
3562
|
+
* @see https://docs.devin.ai/cli/extensibility/skills/overview
|
|
3112
3563
|
*/
|
|
3113
3564
|
var DevinCommand = class DevinCommand extends ToolCommand {
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
const result = DevinCommandFrontmatterSchema.safeParse(frontmatter);
|
|
3119
|
-
if (!result.success) throw new Error(`Invalid frontmatter in ${join(rest.relativeDirPath, rest.relativeFilePath)}: ${formatError(result.error)}`);
|
|
3120
|
-
}
|
|
3121
|
-
super({
|
|
3122
|
-
...rest,
|
|
3123
|
-
fileContent: stringifyFrontmatter(body, frontmatter)
|
|
3565
|
+
static isTargetedByRulesyncCommand(rulesyncCommand) {
|
|
3566
|
+
return this.isTargetedByRulesyncCommandDefault({
|
|
3567
|
+
rulesyncCommand,
|
|
3568
|
+
toolTarget: "devin"
|
|
3124
3569
|
});
|
|
3125
|
-
this.frontmatter = frontmatter;
|
|
3126
|
-
this.body = body;
|
|
3127
3570
|
}
|
|
3128
3571
|
static getSettablePaths({ global = false } = {}) {
|
|
3129
|
-
|
|
3130
|
-
return { relativeDirPath: DEVIN_WORKFLOWS_DIR_PATH };
|
|
3572
|
+
return { relativeDirPath: global ? DEVIN_GLOBAL_SKILLS_DIR_PATH : DEVIN_SKILLS_DIR_PATH };
|
|
3131
3573
|
}
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
const { description, ...restFields } = this.frontmatter;
|
|
3140
|
-
const rulesyncFrontmatter = {
|
|
3141
|
-
targets: ["*"],
|
|
3142
|
-
description,
|
|
3143
|
-
...Object.keys(restFields).length > 0 && { devin: restFields }
|
|
3144
|
-
};
|
|
3145
|
-
const fileContent = stringifyFrontmatter(this.body, rulesyncFrontmatter);
|
|
3146
|
-
return new RulesyncCommand({
|
|
3147
|
-
outputRoot: process.cwd(),
|
|
3148
|
-
frontmatter: rulesyncFrontmatter,
|
|
3149
|
-
body: this.body,
|
|
3150
|
-
relativeDirPath: RulesyncCommand.getSettablePaths().relativeDirPath,
|
|
3151
|
-
relativeFilePath: this.relativeFilePath,
|
|
3152
|
-
fileContent,
|
|
3153
|
-
validate: true
|
|
3154
|
-
});
|
|
3155
|
-
}
|
|
3156
|
-
static fromRulesyncCommand({ outputRoot = process.cwd(), rulesyncCommand, validate = true, global = false }) {
|
|
3157
|
-
const rulesyncFrontmatter = rulesyncCommand.getFrontmatter();
|
|
3158
|
-
const devinFields = rulesyncFrontmatter.devin ?? {};
|
|
3159
|
-
const devinFrontmatter = {
|
|
3160
|
-
description: rulesyncFrontmatter.description,
|
|
3161
|
-
...devinFields
|
|
3162
|
-
};
|
|
3163
|
-
const body = rulesyncCommand.getBody();
|
|
3164
|
-
const paths = this.getSettablePaths({ global });
|
|
3165
|
-
return new DevinCommand({
|
|
3166
|
-
outputRoot,
|
|
3167
|
-
frontmatter: devinFrontmatter,
|
|
3168
|
-
body,
|
|
3169
|
-
relativeDirPath: paths.relativeDirPath,
|
|
3170
|
-
relativeFilePath: rulesyncCommand.getRelativeFilePath(),
|
|
3171
|
-
validate
|
|
3574
|
+
constructor({ slug, ...params }) {
|
|
3575
|
+
super({
|
|
3576
|
+
...params,
|
|
3577
|
+
...slug !== void 0 && {
|
|
3578
|
+
relativeDirPath: join(params.relativeDirPath, slug),
|
|
3579
|
+
relativeFilePath: "SKILL.md"
|
|
3580
|
+
}
|
|
3172
3581
|
});
|
|
3173
3582
|
}
|
|
3174
3583
|
validate() {
|
|
3175
|
-
|
|
3176
|
-
success: true,
|
|
3177
|
-
error: null
|
|
3178
|
-
};
|
|
3179
|
-
const result = DevinCommandFrontmatterSchema.safeParse(this.frontmatter);
|
|
3180
|
-
if (result.success) return {
|
|
3584
|
+
return {
|
|
3181
3585
|
success: true,
|
|
3182
3586
|
error: null
|
|
3183
3587
|
};
|
|
3184
|
-
else return {
|
|
3185
|
-
success: false,
|
|
3186
|
-
error: /* @__PURE__ */ new Error(`Invalid frontmatter in ${join(this.relativeDirPath, this.relativeFilePath)}: ${formatError(result.error)}`)
|
|
3187
|
-
};
|
|
3188
3588
|
}
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3589
|
+
toRulesyncCommand() {
|
|
3590
|
+
const slug = basename(dirname(this.getRelativePathFromCwd()));
|
|
3591
|
+
const { frontmatter, body } = parseFrontmatter(this.getFileContent(), this.getFilePath());
|
|
3592
|
+
const description = typeof frontmatter.description === "string" ? frontmatter.description : void 0;
|
|
3593
|
+
return new RulesyncCommand({
|
|
3594
|
+
relativeDirPath: RULESYNC_COMMANDS_RELATIVE_DIR_PATH,
|
|
3595
|
+
relativeFilePath: `${slug}.md`,
|
|
3596
|
+
frontmatter: { description },
|
|
3597
|
+
body: body.trimStart()
|
|
3193
3598
|
});
|
|
3194
3599
|
}
|
|
3195
|
-
static
|
|
3196
|
-
const paths =
|
|
3197
|
-
const filePath = join(outputRoot, paths.relativeDirPath, relativeFilePath);
|
|
3198
|
-
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(filePath), filePath);
|
|
3199
|
-
const result = DevinCommandFrontmatterSchema.safeParse(frontmatter);
|
|
3200
|
-
if (!result.success) throw new Error(`Invalid frontmatter in ${filePath}: ${formatError(result.error)}`);
|
|
3600
|
+
static fromRulesyncCommand({ outputRoot, rulesyncCommand, global = false }) {
|
|
3601
|
+
const paths = DevinCommand.getSettablePaths({ global });
|
|
3201
3602
|
return new DevinCommand({
|
|
3202
3603
|
outputRoot,
|
|
3203
3604
|
relativeDirPath: paths.relativeDirPath,
|
|
3204
|
-
relativeFilePath,
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
validate
|
|
3605
|
+
relativeFilePath: SKILL_FILE_NAME$1,
|
|
3606
|
+
slug: commandSlug(rulesyncCommand.getRelativeFilePath()),
|
|
3607
|
+
fileContent: commandSkillContent$1(rulesyncCommand)
|
|
3208
3608
|
});
|
|
3209
3609
|
}
|
|
3210
|
-
|
|
3211
|
-
return
|
|
3212
|
-
outputRoot,
|
|
3213
|
-
relativeDirPath,
|
|
3214
|
-
relativeFilePath,
|
|
3215
|
-
frontmatter: { description: "" },
|
|
3216
|
-
body: "",
|
|
3217
|
-
validate: false
|
|
3218
|
-
});
|
|
3610
|
+
getFileContent() {
|
|
3611
|
+
return this.fileContent;
|
|
3219
3612
|
}
|
|
3220
3613
|
};
|
|
3221
3614
|
//#endregion
|
|
@@ -3543,10 +3936,7 @@ const HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_MANIFEST_PATH = join(HERMESAGENT_RUL
|
|
|
3543
3936
|
const HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_INIT_PATH = join(HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_DIR_PATH, "__init__.py");
|
|
3544
3937
|
//#endregion
|
|
3545
3938
|
//#region src/features/commands/hermesagent-command.ts
|
|
3546
|
-
const SKILL_FILE_NAME
|
|
3547
|
-
function commandSlug(relativeFilePath) {
|
|
3548
|
-
return basename(relativeFilePath, ".md").replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
3549
|
-
}
|
|
3939
|
+
const SKILL_FILE_NAME = "SKILL.md";
|
|
3550
3940
|
function commandSkillContent(rulesyncCommand) {
|
|
3551
3941
|
const slug = commandSlug(rulesyncCommand.getRelativeFilePath());
|
|
3552
3942
|
const description = rulesyncCommand.getFrontmatter().description ?? `${slug} command`;
|
|
@@ -3563,7 +3953,7 @@ var HermesagentCommand = class HermesagentCommand extends ToolCommand {
|
|
|
3563
3953
|
static getSettablePaths({ slug = "command" } = {}) {
|
|
3564
3954
|
return {
|
|
3565
3955
|
relativeDirPath: join(HERMESAGENT_SKILLS_DIR_PATH, slug),
|
|
3566
|
-
relativeFilePath: SKILL_FILE_NAME
|
|
3956
|
+
relativeFilePath: SKILL_FILE_NAME
|
|
3567
3957
|
};
|
|
3568
3958
|
}
|
|
3569
3959
|
constructor({ slug, ...params }) {
|
|
@@ -3594,7 +3984,7 @@ var HermesagentCommand = class HermesagentCommand extends ToolCommand {
|
|
|
3594
3984
|
return new HermesagentCommand({
|
|
3595
3985
|
outputRoot,
|
|
3596
3986
|
relativeDirPath: "",
|
|
3597
|
-
relativeFilePath: SKILL_FILE_NAME
|
|
3987
|
+
relativeFilePath: SKILL_FILE_NAME,
|
|
3598
3988
|
slug: commandSlug(rulesyncCommand.getRelativeFilePath()),
|
|
3599
3989
|
fileContent: commandSkillContent(rulesyncCommand)
|
|
3600
3990
|
});
|
|
@@ -4829,6 +5219,7 @@ const PI_AGENT_SKILLS_DIR_PATH = join(PI_AGENT_DIR, "skills");
|
|
|
4829
5219
|
const PI_PROMPTS_DIR_PATH = join(".pi", "prompts");
|
|
4830
5220
|
const PI_SKILLS_DIR_PATH = join(".pi", "skills");
|
|
4831
5221
|
const PI_RULE_FILE_NAME = "AGENTS.md";
|
|
5222
|
+
const PI_APPEND_SYSTEM_FILE_NAME = "APPEND_SYSTEM.md";
|
|
4832
5223
|
//#endregion
|
|
4833
5224
|
//#region src/features/commands/pi-command.ts
|
|
4834
5225
|
/**
|
|
@@ -5363,9 +5754,6 @@ const ROVODEV_AGENTS_SKILLS_DIR_PATH = join(".agents", "skills");
|
|
|
5363
5754
|
const ROVODEV_PROMPTS_FILE_NAME = "prompts.yml";
|
|
5364
5755
|
const ROVODEV_PROMPTS_DIR_PATH = join(ROVODEV_DIR, "prompts");
|
|
5365
5756
|
//#endregion
|
|
5366
|
-
//#region src/types/tool-file.ts
|
|
5367
|
-
var ToolFile = class extends AiFile {};
|
|
5368
|
-
//#endregion
|
|
5369
5757
|
//#region src/features/commands/rovodev-command.ts
|
|
5370
5758
|
/**
|
|
5371
5759
|
* Rovo Dev CLI "saved prompts": a file-based custom-command surface made of a
|
|
@@ -5854,7 +6242,8 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
5854
6242
|
supportsProject: false,
|
|
5855
6243
|
supportsGlobal: true,
|
|
5856
6244
|
isSimulated: false,
|
|
5857
|
-
supportsSubdirectory: true
|
|
6245
|
+
supportsSubdirectory: true,
|
|
6246
|
+
skipToolFileScan: true
|
|
5858
6247
|
}
|
|
5859
6248
|
}],
|
|
5860
6249
|
["junie", {
|
|
@@ -5984,7 +6373,8 @@ const toolCommandFactories = /* @__PURE__ */ new Map([
|
|
|
5984
6373
|
supportsProject: true,
|
|
5985
6374
|
supportsGlobal: true,
|
|
5986
6375
|
isSimulated: false,
|
|
5987
|
-
supportsSubdirectory: false
|
|
6376
|
+
supportsSubdirectory: false,
|
|
6377
|
+
skipToolFileScan: true
|
|
5988
6378
|
}
|
|
5989
6379
|
}]
|
|
5990
6380
|
]);
|
|
@@ -6087,6 +6477,7 @@ var CommandsProcessor = class extends FeatureProcessor {
|
|
|
6087
6477
|
*/
|
|
6088
6478
|
async loadToolFiles({ forDeletion = false } = {}) {
|
|
6089
6479
|
const factory = this.getFactory(this.toolTarget);
|
|
6480
|
+
if (factory.meta.skipToolFileScan) return [];
|
|
6090
6481
|
const paths = factory.class.getSettablePaths({ global: this.global });
|
|
6091
6482
|
const outputRootFull = join(this.outputRoot, paths.relativeDirPath);
|
|
6092
6483
|
const commandFilePaths = await findFilesByGlobs(factory.meta.supportsSubdirectory ? join(outputRootFull, "**", `*.${factory.meta.extension}`) : join(outputRootFull, `*.${factory.meta.extension}`));
|
|
@@ -6196,7 +6587,10 @@ const HookDefinitionSchema = z.looseObject({
|
|
|
6196
6587
|
type: z.optional(z.enum([
|
|
6197
6588
|
"command",
|
|
6198
6589
|
"prompt",
|
|
6199
|
-
"http"
|
|
6590
|
+
"http",
|
|
6591
|
+
"agent",
|
|
6592
|
+
"mcp_tool",
|
|
6593
|
+
"function"
|
|
6200
6594
|
])),
|
|
6201
6595
|
url: z.optional(safeString),
|
|
6202
6596
|
timeout: z.optional(z.number()),
|
|
@@ -6209,12 +6603,71 @@ const HookDefinitionSchema = z.looseObject({
|
|
|
6209
6603
|
sequential: z.optional(z.boolean()),
|
|
6210
6604
|
async: z.optional(z.boolean()),
|
|
6211
6605
|
env: z.optional(z.record(z.string(), safeString)),
|
|
6212
|
-
shell: z.optional(
|
|
6606
|
+
shell: z.optional(z.enum(["bash", "powershell"])),
|
|
6213
6607
|
statusMessage: z.optional(safeString),
|
|
6214
6608
|
headers: z.optional(z.record(z.string(), safeString)),
|
|
6215
6609
|
allowedEnvVars: z.optional(z.array(z.string())),
|
|
6216
|
-
once: z.optional(z.boolean())
|
|
6610
|
+
once: z.optional(z.boolean()),
|
|
6611
|
+
server: z.optional(safeString),
|
|
6612
|
+
tool: z.optional(safeString),
|
|
6613
|
+
input: z.optional(z.looseObject({})),
|
|
6614
|
+
model: z.optional(safeString)
|
|
6217
6615
|
});
|
|
6616
|
+
/**
|
|
6617
|
+
* All canonical hook event names.
|
|
6618
|
+
* Each tool supports a subset of these events.
|
|
6619
|
+
*/
|
|
6620
|
+
const HOOK_EVENTS = [
|
|
6621
|
+
"sessionStart",
|
|
6622
|
+
"sessionEnd",
|
|
6623
|
+
"preToolUse",
|
|
6624
|
+
"postToolUse",
|
|
6625
|
+
"preModelInvocation",
|
|
6626
|
+
"postModelInvocation",
|
|
6627
|
+
"beforeSubmitPrompt",
|
|
6628
|
+
"stop",
|
|
6629
|
+
"subagentStop",
|
|
6630
|
+
"preCompact",
|
|
6631
|
+
"postCompact",
|
|
6632
|
+
"contextOffload",
|
|
6633
|
+
"postToolUseFailure",
|
|
6634
|
+
"subagentStart",
|
|
6635
|
+
"beforeShellExecution",
|
|
6636
|
+
"afterShellExecution",
|
|
6637
|
+
"beforeMCPExecution",
|
|
6638
|
+
"afterMCPExecution",
|
|
6639
|
+
"beforeReadFile",
|
|
6640
|
+
"afterFileEdit",
|
|
6641
|
+
"beforeAgentResponse",
|
|
6642
|
+
"afterAgentResponse",
|
|
6643
|
+
"afterAgentThought",
|
|
6644
|
+
"beforeTabFileRead",
|
|
6645
|
+
"afterTabFileEdit",
|
|
6646
|
+
"permissionRequest",
|
|
6647
|
+
"notification",
|
|
6648
|
+
"setup",
|
|
6649
|
+
"afterError",
|
|
6650
|
+
"beforeToolSelection",
|
|
6651
|
+
"worktreeCreate",
|
|
6652
|
+
"worktreeRemove",
|
|
6653
|
+
"workspaceOpen",
|
|
6654
|
+
"messageDisplay",
|
|
6655
|
+
"todoCreated",
|
|
6656
|
+
"todoCompleted",
|
|
6657
|
+
"stopFailure",
|
|
6658
|
+
"instructionsLoaded",
|
|
6659
|
+
"userPromptExpansion",
|
|
6660
|
+
"postToolBatch",
|
|
6661
|
+
"permissionDenied",
|
|
6662
|
+
"taskCreated",
|
|
6663
|
+
"taskCompleted",
|
|
6664
|
+
"teammateIdle",
|
|
6665
|
+
"configChange",
|
|
6666
|
+
"cwdChanged",
|
|
6667
|
+
"fileChanged",
|
|
6668
|
+
"elicitation",
|
|
6669
|
+
"elicitationResult"
|
|
6670
|
+
];
|
|
6218
6671
|
/** Hook events supported by Cursor. */
|
|
6219
6672
|
const CURSOR_HOOK_EVENTS = [
|
|
6220
6673
|
"sessionStart",
|
|
@@ -6689,12 +7142,28 @@ const CANONICAL_TO_HERMESAGENT_EVENT_NAMES = {
|
|
|
6689
7142
|
*/
|
|
6690
7143
|
const HERMESAGENT_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_HERMESAGENT_EVENT_NAMES).map(([k, v]) => [v, k]));
|
|
6691
7144
|
const hooksRecordSchema = z.record(z.string(), z.array(HookDefinitionSchema));
|
|
7145
|
+
const HOOK_EVENT_SET = new Set(HOOK_EVENTS);
|
|
7146
|
+
/** Whether `value` is a canonical hook event name. */
|
|
7147
|
+
const isHookEvent = (value) => HOOK_EVENT_SET.has(value);
|
|
7148
|
+
/**
|
|
7149
|
+
* Top-level `hooks` record whose keys must be canonical event names, so typos
|
|
7150
|
+
* are rejected at parse time. Keys are validated with a refinement (instead of
|
|
7151
|
+
* an enum key schema) to keep the inferred type a plain string record.
|
|
7152
|
+
*
|
|
7153
|
+
* The per-tool override blocks below deliberately keep the lenient
|
|
7154
|
+
* `hooksRecordSchema`: some are documented to pass tool-native event keys
|
|
7155
|
+
* through verbatim (e.g. kiro-ide's IDE-only `PostFileSave`/`PreTaskExec`
|
|
7156
|
+
* triggers), which the canonical enum would reject.
|
|
7157
|
+
*/
|
|
7158
|
+
const canonicalHooksRecordSchema = z.record(z.string(), z.array(HookDefinitionSchema)).check(z.refine((record) => Object.keys(record).every((key) => HOOK_EVENT_SET.has(key)), { error: (issue) => {
|
|
7159
|
+
return `unknown hook event name(s): ${Object.keys(issue.input ?? {}).filter((key) => !HOOK_EVENT_SET.has(key)).join(", ")}`;
|
|
7160
|
+
} }));
|
|
6692
7161
|
/**
|
|
6693
7162
|
* Canonical hooks config (canonical event names in camelCase).
|
|
6694
7163
|
*/
|
|
6695
7164
|
const HooksConfigSchema = z.looseObject({
|
|
6696
7165
|
version: z.optional(z.number()),
|
|
6697
|
-
hooks:
|
|
7166
|
+
hooks: canonicalHooksRecordSchema,
|
|
6698
7167
|
cursor: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
6699
7168
|
claudecode: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
6700
7169
|
copilot: z.optional(z.looseObject({ hooks: z.optional(hooksRecordSchema) })),
|
|
@@ -7131,6 +7600,20 @@ const CANONICAL_TO_GROKCLI_EVENT_NAMES = {
|
|
|
7131
7600
|
*/
|
|
7132
7601
|
const GROKCLI_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CANONICAL_TO_GROKCLI_EVENT_NAMES).map(([k, v]) => [v, k]));
|
|
7133
7602
|
//#endregion
|
|
7603
|
+
//#region src/utils/object.ts
|
|
7604
|
+
/**
|
|
7605
|
+
* Return a shallow copy of `obj` keeping only the entries whose value is
|
|
7606
|
+
* neither `undefined` nor `null`.
|
|
7607
|
+
*
|
|
7608
|
+
* Used to assemble generated config objects without one conditional spread per
|
|
7609
|
+
* optional field (which would otherwise exceed the lint complexity budget).
|
|
7610
|
+
*/
|
|
7611
|
+
function compact(obj) {
|
|
7612
|
+
const result = {};
|
|
7613
|
+
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== null) result[key] = value;
|
|
7614
|
+
return result;
|
|
7615
|
+
}
|
|
7616
|
+
//#endregion
|
|
7134
7617
|
//#region src/features/hooks/tool-hooks-converter.ts
|
|
7135
7618
|
function isToolMatcherEntry(x) {
|
|
7136
7619
|
if (x === null || typeof x !== "object") return false;
|
|
@@ -7188,6 +7671,25 @@ function importBooleanPassthroughFields({ h, converterConfig }) {
|
|
|
7188
7671
|
return Object.fromEntries((converterConfig.booleanPassthroughFields ?? []).filter(({ tool }) => typeof h[tool] === "boolean").map(({ canonical, tool }) => [canonical, h[tool]]));
|
|
7189
7672
|
}
|
|
7190
7673
|
/**
|
|
7674
|
+
* Emit the payload fields specific to a hook type — `url`/`headers`/
|
|
7675
|
+
* `allowedEnvVars` for http, `server`/`tool`/`input` for mcp_tool, `model`
|
|
7676
|
+
* for prompt/agent. https://code.claude.com/docs/en/hooks
|
|
7677
|
+
*/
|
|
7678
|
+
function emitTypePayloadFields({ def, hookType, converterConfig }) {
|
|
7679
|
+
if (hookType === "http") return compact({
|
|
7680
|
+
url: def.url,
|
|
7681
|
+
headers: def.headers,
|
|
7682
|
+
allowedEnvVars: def.allowedEnvVars
|
|
7683
|
+
});
|
|
7684
|
+
if (hookType === "mcp_tool") return compact({
|
|
7685
|
+
server: def.server,
|
|
7686
|
+
tool: def.tool,
|
|
7687
|
+
input: def.input
|
|
7688
|
+
});
|
|
7689
|
+
if ((hookType === "prompt" || hookType === "agent") && converterConfig.emitsPromptModel) return compact({ model: def.model });
|
|
7690
|
+
return {};
|
|
7691
|
+
}
|
|
7692
|
+
/**
|
|
7191
7693
|
* Convert the definitions of a single matcher group into tool hook entries,
|
|
7192
7694
|
* honoring supported hook types and passthrough fields.
|
|
7193
7695
|
*/
|
|
@@ -7209,6 +7711,11 @@ function buildToolHooks({ defs, converterConfig }) {
|
|
|
7209
7711
|
...command !== void 0 && command !== null && { command },
|
|
7210
7712
|
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
7211
7713
|
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt },
|
|
7714
|
+
...emitTypePayloadFields({
|
|
7715
|
+
def,
|
|
7716
|
+
hookType,
|
|
7717
|
+
converterConfig
|
|
7718
|
+
}),
|
|
7212
7719
|
...converterConfig.passthroughFields?.includes("name") && def.name !== void 0 && def.name !== null && { name: def.name },
|
|
7213
7720
|
...converterConfig.passthroughFields?.includes("description") && def.description !== void 0 && def.description !== null && { description: def.description }
|
|
7214
7721
|
});
|
|
@@ -7275,6 +7782,46 @@ function stripCommandPrefix({ command, converterConfig }) {
|
|
|
7275
7782
|
return cmd;
|
|
7276
7783
|
}
|
|
7277
7784
|
/**
|
|
7785
|
+
* Hook types preserved verbatim on import — Claude Code's five documented
|
|
7786
|
+
* handler types. Anything else is coerced to `command` as before.
|
|
7787
|
+
* https://code.claude.com/docs/en/hooks
|
|
7788
|
+
*/
|
|
7789
|
+
const IMPORTED_HOOK_TYPES = /* @__PURE__ */ new Set([
|
|
7790
|
+
"command",
|
|
7791
|
+
"prompt",
|
|
7792
|
+
"http",
|
|
7793
|
+
"mcp_tool",
|
|
7794
|
+
"agent"
|
|
7795
|
+
]);
|
|
7796
|
+
function isImportedHookType(value) {
|
|
7797
|
+
return typeof value === "string" && IMPORTED_HOOK_TYPES.has(value);
|
|
7798
|
+
}
|
|
7799
|
+
function isStringRecord(value) {
|
|
7800
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
7801
|
+
return Object.values(value).every((v) => typeof v === "string");
|
|
7802
|
+
}
|
|
7803
|
+
function isStringArray(value) {
|
|
7804
|
+
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
7805
|
+
}
|
|
7806
|
+
/**
|
|
7807
|
+
* Import the payload fields specific to a hook type, type-checking each raw
|
|
7808
|
+
* value before it enters the canonical definition.
|
|
7809
|
+
*/
|
|
7810
|
+
function importTypePayloadFields({ h, hookType }) {
|
|
7811
|
+
if (hookType === "http") return {
|
|
7812
|
+
...typeof h.url === "string" && { url: h.url },
|
|
7813
|
+
...isStringRecord(h.headers) && { headers: h.headers },
|
|
7814
|
+
...isStringArray(h.allowedEnvVars) && { allowedEnvVars: h.allowedEnvVars }
|
|
7815
|
+
};
|
|
7816
|
+
if (hookType === "mcp_tool") return {
|
|
7817
|
+
...typeof h.server === "string" && { server: h.server },
|
|
7818
|
+
...typeof h.tool === "string" && { tool: h.tool },
|
|
7819
|
+
...h.input !== null && typeof h.input === "object" && !Array.isArray(h.input) && { input: h.input }
|
|
7820
|
+
};
|
|
7821
|
+
if (hookType === "prompt" || hookType === "agent") return typeof h.model === "string" ? { model: h.model } : {};
|
|
7822
|
+
return {};
|
|
7823
|
+
}
|
|
7824
|
+
/**
|
|
7278
7825
|
* Convert a single tool hook record into a canonical hook definition.
|
|
7279
7826
|
*/
|
|
7280
7827
|
function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
@@ -7282,7 +7829,7 @@ function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
|
7282
7829
|
command: h.command,
|
|
7283
7830
|
converterConfig
|
|
7284
7831
|
});
|
|
7285
|
-
const hookType = h.type
|
|
7832
|
+
const hookType = isImportedHookType(h.type) ? h.type : "command";
|
|
7286
7833
|
const timeout = typeof h.timeout === "number" ? h.timeout : void 0;
|
|
7287
7834
|
const prompt = typeof h.prompt === "string" ? h.prompt : void 0;
|
|
7288
7835
|
return {
|
|
@@ -7290,6 +7837,10 @@ function toolHookToCanonical({ h, rawEntry, converterConfig }) {
|
|
|
7290
7837
|
...command !== void 0 && command !== null && { command },
|
|
7291
7838
|
...timeout !== void 0 && timeout !== null && { timeout },
|
|
7292
7839
|
...prompt !== void 0 && prompt !== null && { prompt },
|
|
7840
|
+
...importTypePayloadFields({
|
|
7841
|
+
h,
|
|
7842
|
+
hookType
|
|
7843
|
+
}),
|
|
7293
7844
|
...converterConfig.passthroughFields?.includes("name") && typeof h.name === "string" && { name: h.name },
|
|
7294
7845
|
...converterConfig.passthroughFields?.includes("description") && typeof h.description === "string" && { description: h.description },
|
|
7295
7846
|
...importBooleanPassthroughFields({
|
|
@@ -7309,6 +7860,32 @@ function toolMatcherEntryToCanonical({ rawEntry, converterConfig }) {
|
|
|
7309
7860
|
converterConfig
|
|
7310
7861
|
}));
|
|
7311
7862
|
}
|
|
7863
|
+
/**
|
|
7864
|
+
* Assemble the canonical hooks config a tool importer writes to
|
|
7865
|
+
* `.rulesync/hooks.json`.
|
|
7866
|
+
*
|
|
7867
|
+
* The top-level `hooks` record only accepts canonical event names, so any
|
|
7868
|
+
* imported native event key without a canonical mapping is moved under the
|
|
7869
|
+
* importing tool's own override block (`<overrideKey>.hooks`), whose keys stay
|
|
7870
|
+
* lenient. This mirrors the generate direction — override blocks pass
|
|
7871
|
+
* tool-native keys through verbatim — so documented native triggers (e.g.
|
|
7872
|
+
* kiro-ide's `PostFileSave`) survive an import → generate round-trip instead
|
|
7873
|
+
* of failing canonical validation.
|
|
7874
|
+
*/
|
|
7875
|
+
function buildImportedHooksConfig({ hooks, overrideKey, version = 1, extraOverride }) {
|
|
7876
|
+
const canonical = {};
|
|
7877
|
+
const native = {};
|
|
7878
|
+
for (const [event, defs] of Object.entries(hooks)) if (isHookEvent(event)) canonical[event] = defs;
|
|
7879
|
+
else native[event] = defs;
|
|
7880
|
+
const override = { ...extraOverride };
|
|
7881
|
+
if (Object.keys(native).length > 0) override.hooks = native;
|
|
7882
|
+
const config = {
|
|
7883
|
+
version,
|
|
7884
|
+
hooks: canonical
|
|
7885
|
+
};
|
|
7886
|
+
if (Object.keys(override).length > 0) config[overrideKey] = override;
|
|
7887
|
+
return config;
|
|
7888
|
+
}
|
|
7312
7889
|
function toolHooksToCanonical({ hooks, converterConfig }) {
|
|
7313
7890
|
if (hooks === null || hooks === void 0 || typeof hooks !== "object") return {};
|
|
7314
7891
|
const canonical = {};
|
|
@@ -7479,7 +8056,8 @@ const ANTIGRAVITY_CONVERTER_CONFIG = {
|
|
|
7479
8056
|
"preModelInvocation",
|
|
7480
8057
|
"postModelInvocation",
|
|
7481
8058
|
"stop"
|
|
7482
|
-
])
|
|
8059
|
+
]),
|
|
8060
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command"])
|
|
7483
8061
|
};
|
|
7484
8062
|
/**
|
|
7485
8063
|
* Antigravity's `hooks.json` is keyed by a named hook whose value holds the
|
|
@@ -7586,10 +8164,11 @@ var AntigravityHooks = class extends ToolHooks {
|
|
|
7586
8164
|
hooks: flattenAntigravityHooks(parsed),
|
|
7587
8165
|
converterConfig: ANTIGRAVITY_CONVERTER_CONFIG
|
|
7588
8166
|
});
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
hooks
|
|
7592
|
-
|
|
8167
|
+
const overrideKey = this.constructor.getOverrideKey();
|
|
8168
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8169
|
+
hooks,
|
|
8170
|
+
overrideKey
|
|
8171
|
+
}), null, 2) });
|
|
7593
8172
|
}
|
|
7594
8173
|
validate() {
|
|
7595
8174
|
return {
|
|
@@ -7710,7 +8289,8 @@ const AUGMENTCODE_CONVERTER_CONFIG = {
|
|
|
7710
8289
|
"sessionEnd",
|
|
7711
8290
|
"stop",
|
|
7712
8291
|
"notification"
|
|
7713
|
-
])
|
|
8292
|
+
]),
|
|
8293
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command"])
|
|
7714
8294
|
};
|
|
7715
8295
|
/**
|
|
7716
8296
|
* AugmentCode (Auggie CLI) lifecycle hooks.
|
|
@@ -7792,10 +8372,10 @@ var AugmentcodeHooks = class AugmentcodeHooks extends ToolHooks {
|
|
|
7792
8372
|
hooks: settings.hooks,
|
|
7793
8373
|
converterConfig: AUGMENTCODE_CONVERTER_CONFIG
|
|
7794
8374
|
});
|
|
7795
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
}, null, 2) });
|
|
8375
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8376
|
+
hooks,
|
|
8377
|
+
overrideKey: "augmentcode"
|
|
8378
|
+
}), null, 2) });
|
|
7799
8379
|
}
|
|
7800
8380
|
validate() {
|
|
7801
8381
|
return {
|
|
@@ -7830,7 +8410,15 @@ const CLAUDE_CONVERTER_CONFIG = {
|
|
|
7830
8410
|
"taskCompleted",
|
|
7831
8411
|
"teammateIdle",
|
|
7832
8412
|
"cwdChanged"
|
|
7833
|
-
])
|
|
8413
|
+
]),
|
|
8414
|
+
supportedHookTypes: /* @__PURE__ */ new Set([
|
|
8415
|
+
"command",
|
|
8416
|
+
"prompt",
|
|
8417
|
+
"http",
|
|
8418
|
+
"mcp_tool",
|
|
8419
|
+
"agent"
|
|
8420
|
+
]),
|
|
8421
|
+
emitsPromptModel: true
|
|
7834
8422
|
};
|
|
7835
8423
|
var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
7836
8424
|
constructor(params) {
|
|
@@ -7895,10 +8483,10 @@ var ClaudecodeHooks = class ClaudecodeHooks extends ToolHooks {
|
|
|
7895
8483
|
hooks: settings.hooks,
|
|
7896
8484
|
converterConfig: CLAUDE_CONVERTER_CONFIG
|
|
7897
8485
|
});
|
|
7898
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
}, null, 2) });
|
|
8486
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8487
|
+
hooks,
|
|
8488
|
+
overrideKey: "claudecode"
|
|
8489
|
+
}), null, 2) });
|
|
7902
8490
|
}
|
|
7903
8491
|
validate() {
|
|
7904
8492
|
return {
|
|
@@ -8041,10 +8629,10 @@ var CodexcliHooks = class CodexcliHooks extends ToolHooks {
|
|
|
8041
8629
|
hooks: parsed.hooks,
|
|
8042
8630
|
converterConfig: CODEXCLI_CONVERTER_CONFIG
|
|
8043
8631
|
});
|
|
8044
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
}, null, 2) });
|
|
8632
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8633
|
+
hooks,
|
|
8634
|
+
overrideKey: "codexcli"
|
|
8635
|
+
}), null, 2) });
|
|
8048
8636
|
}
|
|
8049
8637
|
validate() {
|
|
8050
8638
|
return {
|
|
@@ -8212,10 +8800,10 @@ var CopilotHooks = class CopilotHooks extends ToolHooks {
|
|
|
8212
8800
|
throw new Error(`Failed to parse Copilot hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8213
8801
|
}
|
|
8214
8802
|
const hooks = copilotHooksToCanonical(parsed.hooks, options?.logger);
|
|
8215
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8216
|
-
|
|
8217
|
-
|
|
8218
|
-
}, null, 2) });
|
|
8803
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
8804
|
+
hooks,
|
|
8805
|
+
overrideKey: "copilot"
|
|
8806
|
+
}), null, 2) });
|
|
8219
8807
|
}
|
|
8220
8808
|
validate() {
|
|
8221
8809
|
return {
|
|
@@ -8234,20 +8822,6 @@ var CopilotHooks = class CopilotHooks extends ToolHooks {
|
|
|
8234
8822
|
}
|
|
8235
8823
|
};
|
|
8236
8824
|
//#endregion
|
|
8237
|
-
//#region src/utils/object.ts
|
|
8238
|
-
/**
|
|
8239
|
-
* Return a shallow copy of `obj` keeping only the entries whose value is
|
|
8240
|
-
* neither `undefined` nor `null`.
|
|
8241
|
-
*
|
|
8242
|
-
* Used to assemble generated config objects without one conditional spread per
|
|
8243
|
-
* optional field (which would otherwise exceed the lint complexity budget).
|
|
8244
|
-
*/
|
|
8245
|
-
function compact(obj) {
|
|
8246
|
-
const result = {};
|
|
8247
|
-
for (const [key, value] of Object.entries(obj)) if (value !== void 0 && value !== null) result[key] = value;
|
|
8248
|
-
return result;
|
|
8249
|
-
}
|
|
8250
|
-
//#endregion
|
|
8251
8825
|
//#region src/features/hooks/copilotcli-hooks.ts
|
|
8252
8826
|
/**
|
|
8253
8827
|
* GitHub Copilot CLI hooks.
|
|
@@ -8380,7 +8954,7 @@ function buildCopilotCliEntriesForEvent({ eventName, definitions, canonicalSchem
|
|
|
8380
8954
|
...timeoutPart,
|
|
8381
8955
|
...rest
|
|
8382
8956
|
});
|
|
8383
|
-
else entries.push({
|
|
8957
|
+
else if (hookType === "command") entries.push({
|
|
8384
8958
|
type: "command",
|
|
8385
8959
|
...matcherPart,
|
|
8386
8960
|
...compact({
|
|
@@ -8532,10 +9106,10 @@ var CopilotcliHooks = class CopilotcliHooks extends ToolHooks {
|
|
|
8532
9106
|
throw new Error(`Failed to parse Copilot CLI hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8533
9107
|
}
|
|
8534
9108
|
const hooks = copilotCliHooksToCanonical(parsed.hooks, options?.logger);
|
|
8535
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
}, null, 2) });
|
|
9109
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9110
|
+
hooks,
|
|
9111
|
+
overrideKey: "copilotcli"
|
|
9112
|
+
}), null, 2) });
|
|
8539
9113
|
}
|
|
8540
9114
|
validate() {
|
|
8541
9115
|
return {
|
|
@@ -8590,9 +9164,10 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8590
9164
|
...config.cursor?.hooks
|
|
8591
9165
|
};
|
|
8592
9166
|
const mappedHooks = {};
|
|
9167
|
+
const cursorSupportedTypes = /* @__PURE__ */ new Set(["command", "prompt"]);
|
|
8593
9168
|
for (const [eventName, defs] of Object.entries(mergedHooks)) {
|
|
8594
9169
|
const cursorEventName = CANONICAL_TO_CURSOR_EVENT_NAMES[eventName] ?? eventName;
|
|
8595
|
-
|
|
9170
|
+
const mappedDefs = defs.filter((def) => cursorSupportedTypes.has(def.type ?? "command")).map((def) => ({
|
|
8596
9171
|
...def.type !== void 0 && def.type !== null && { type: def.type },
|
|
8597
9172
|
...def.command !== void 0 && def.command !== null && { command: def.command },
|
|
8598
9173
|
...def.timeout !== void 0 && def.timeout !== null && { timeout: def.timeout },
|
|
@@ -8601,6 +9176,7 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8601
9176
|
...def.prompt !== void 0 && def.prompt !== null && { prompt: def.prompt },
|
|
8602
9177
|
...def.failClosed !== void 0 && def.failClosed !== null && { failClosed: def.failClosed }
|
|
8603
9178
|
}));
|
|
9179
|
+
if (mappedDefs.length > 0) mappedHooks[cursorEventName] = mappedDefs;
|
|
8604
9180
|
}
|
|
8605
9181
|
const cursorConfig = {
|
|
8606
9182
|
version: config.version ?? 1,
|
|
@@ -8627,10 +9203,11 @@ var CursorHooks = class CursorHooks extends ToolHooks {
|
|
|
8627
9203
|
canonicalHooks[eventName] = defs;
|
|
8628
9204
|
}
|
|
8629
9205
|
const version = parsed.version ?? 1;
|
|
8630
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
9206
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9207
|
+
hooks: canonicalHooks,
|
|
9208
|
+
overrideKey: "cursor",
|
|
9209
|
+
version
|
|
9210
|
+
}), null, 2) });
|
|
8634
9211
|
}
|
|
8635
9212
|
validate() {
|
|
8636
9213
|
return {
|
|
@@ -8685,7 +9262,7 @@ function canonicalToDeepagentsHooks(config) {
|
|
|
8685
9262
|
const deepagentsEvent = CANONICAL_TO_DEEPAGENTS_EVENT_NAMES[canonicalEvent];
|
|
8686
9263
|
if (!deepagentsEvent) continue;
|
|
8687
9264
|
for (const def of definitions) {
|
|
8688
|
-
if (def.type
|
|
9265
|
+
if ((def.type ?? "command") !== "command") continue;
|
|
8689
9266
|
if (!def.command) continue;
|
|
8690
9267
|
if (def.matcher) continue;
|
|
8691
9268
|
entries.push({
|
|
@@ -8775,10 +9352,10 @@ var DeepagentsHooks = class DeepagentsHooks extends ToolHooks {
|
|
|
8775
9352
|
throw new Error(`Failed to parse deepagents hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
8776
9353
|
}
|
|
8777
9354
|
const hooks = deepagentsToCanonicalHooks(isDeepagentsHooksFile(parsed) ? parsed.hooks : []);
|
|
8778
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
}, null, 2) });
|
|
9355
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9356
|
+
hooks,
|
|
9357
|
+
overrideKey: "deepagents"
|
|
9358
|
+
}), null, 2) });
|
|
8782
9359
|
}
|
|
8783
9360
|
validate() {
|
|
8784
9361
|
return {
|
|
@@ -8907,10 +9484,10 @@ var DevinHooks = class DevinHooks extends ToolHooks {
|
|
|
8907
9484
|
hooks: this.getRelativeFilePath() === "config.json" ? isRecord(parsed) && isRecord(parsed.hooks) ? parsed.hooks : {} : parsed,
|
|
8908
9485
|
converterConfig: DEVIN_CONVERTER_CONFIG
|
|
8909
9486
|
});
|
|
8910
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
}, null, 2) });
|
|
9487
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9488
|
+
hooks,
|
|
9489
|
+
overrideKey: "devin"
|
|
9490
|
+
}), null, 2) });
|
|
8914
9491
|
}
|
|
8915
9492
|
validate() {
|
|
8916
9493
|
return {
|
|
@@ -8934,7 +9511,8 @@ const FACTORYDROID_CONVERTER_CONFIG = {
|
|
|
8934
9511
|
supportedEvents: FACTORYDROID_HOOK_EVENTS,
|
|
8935
9512
|
canonicalToToolEventNames: CANONICAL_TO_FACTORYDROID_EVENT_NAMES,
|
|
8936
9513
|
toolToCanonicalEventNames: FACTORYDROID_TO_CANONICAL_EVENT_NAMES,
|
|
8937
|
-
projectDirVar: "$FACTORY_PROJECT_DIR"
|
|
9514
|
+
projectDirVar: "$FACTORY_PROJECT_DIR",
|
|
9515
|
+
supportedHookTypes: /* @__PURE__ */ new Set(["command", "prompt"])
|
|
8938
9516
|
};
|
|
8939
9517
|
var FactorydroidHooks = class FactorydroidHooks extends ToolHooks {
|
|
8940
9518
|
constructor(params) {
|
|
@@ -9002,10 +9580,10 @@ var FactorydroidHooks = class FactorydroidHooks extends ToolHooks {
|
|
|
9002
9580
|
hooks: settings.hooks,
|
|
9003
9581
|
converterConfig: FACTORYDROID_CONVERTER_CONFIG
|
|
9004
9582
|
});
|
|
9005
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
}, null, 2) });
|
|
9583
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9584
|
+
hooks,
|
|
9585
|
+
overrideKey: "factorydroid"
|
|
9586
|
+
}), null, 2) });
|
|
9009
9587
|
}
|
|
9010
9588
|
validate() {
|
|
9011
9589
|
return {
|
|
@@ -9096,10 +9674,10 @@ var GooseHooks = class GooseHooks extends ToolHooks {
|
|
|
9096
9674
|
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,
|
|
9097
9675
|
converterConfig: GOOSE_CONVERTER_CONFIG
|
|
9098
9676
|
});
|
|
9099
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9100
|
-
|
|
9101
|
-
|
|
9102
|
-
}, null, 2) });
|
|
9677
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9678
|
+
hooks,
|
|
9679
|
+
overrideKey: "goose"
|
|
9680
|
+
}), null, 2) });
|
|
9103
9681
|
}
|
|
9104
9682
|
validate() {
|
|
9105
9683
|
return {
|
|
@@ -9257,10 +9835,10 @@ var GrokcliHooks = class GrokcliHooks extends ToolHooks {
|
|
|
9257
9835
|
hooks: isRecord(parsed) && isRecord(parsed.hooks) ? parsed.hooks : {},
|
|
9258
9836
|
converterConfig: GROKCLI_CONVERTER_CONFIG
|
|
9259
9837
|
});
|
|
9260
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
}, null, 2) });
|
|
9838
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
9839
|
+
hooks,
|
|
9840
|
+
overrideKey: "grokcli"
|
|
9841
|
+
}), null, 2) });
|
|
9264
9842
|
}
|
|
9265
9843
|
validate() {
|
|
9266
9844
|
return {
|
|
@@ -9421,10 +9999,10 @@ var HermesagentHooks = class HermesagentHooks extends ToolHooks {
|
|
|
9421
9999
|
format: "yaml",
|
|
9422
10000
|
fileContent: this.getFileContent()
|
|
9423
10001
|
}).hooks);
|
|
9424
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
}, null, 2) });
|
|
10002
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10003
|
+
hooks,
|
|
10004
|
+
overrideKey: "hermesagent"
|
|
10005
|
+
}), null, 2) });
|
|
9428
10006
|
}
|
|
9429
10007
|
static fromRulesyncHooks({ outputRoot, rulesyncHooks, logger }) {
|
|
9430
10008
|
const config = rulesyncHooks.getJson();
|
|
@@ -9527,10 +10105,10 @@ var JunieHooks = class JunieHooks extends ToolHooks {
|
|
|
9527
10105
|
hooks: settings.hooks,
|
|
9528
10106
|
converterConfig: JUNIE_CONVERTER_CONFIG
|
|
9529
10107
|
});
|
|
9530
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
}, null, 2) });
|
|
10108
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10109
|
+
hooks,
|
|
10110
|
+
overrideKey: "junie"
|
|
10111
|
+
}), null, 2) });
|
|
9534
10112
|
}
|
|
9535
10113
|
validate() {
|
|
9536
10114
|
return {
|
|
@@ -9575,7 +10153,7 @@ function collectOpencodeStyleHandlers({ effectiveHooks, eventMap, namedEventHand
|
|
|
9575
10153
|
if (!toolEvent) continue;
|
|
9576
10154
|
const handlers = [];
|
|
9577
10155
|
for (const def of definitions) {
|
|
9578
|
-
if (def.type
|
|
10156
|
+
if ((def.type ?? "command") !== "command") continue;
|
|
9579
10157
|
if (!def.command) continue;
|
|
9580
10158
|
handlers.push({
|
|
9581
10159
|
command: def.command,
|
|
@@ -9880,10 +10458,11 @@ var KiroHooks = class KiroHooks extends ToolHooks {
|
|
|
9880
10458
|
throw new Error(`Failed to parse Kiro hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
9881
10459
|
}
|
|
9882
10460
|
const hooks = kiroHooksToCanonical(agentConfig.hooks);
|
|
9883
|
-
|
|
9884
|
-
|
|
9885
|
-
hooks
|
|
9886
|
-
|
|
10461
|
+
const overrideKey = this.constructor.getOverrideKey();
|
|
10462
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10463
|
+
hooks,
|
|
10464
|
+
overrideKey
|
|
10465
|
+
}), null, 2) });
|
|
9887
10466
|
}
|
|
9888
10467
|
validate() {
|
|
9889
10468
|
return {
|
|
@@ -10092,10 +10671,10 @@ var KiroIdeHooks = class KiroIdeHooks extends ToolHooks {
|
|
|
10092
10671
|
throw new Error(`Failed to parse Kiro IDE hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10093
10672
|
}
|
|
10094
10673
|
const hooks = kiroIdeHooksToCanonical(parsed.hooks ?? []);
|
|
10095
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10096
|
-
|
|
10097
|
-
|
|
10098
|
-
}, null, 2) });
|
|
10674
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
10675
|
+
hooks,
|
|
10676
|
+
overrideKey: "kiro-ide"
|
|
10677
|
+
}), null, 2) });
|
|
10099
10678
|
}
|
|
10100
10679
|
validate() {
|
|
10101
10680
|
return {
|
|
@@ -10219,11 +10798,18 @@ function canonicalToQwencodeHooks(config) {
|
|
|
10219
10798
|
...sharedHooks,
|
|
10220
10799
|
...config.qwencode?.hooks
|
|
10221
10800
|
};
|
|
10801
|
+
const qwencodeSupportedTypes = /* @__PURE__ */ new Set([
|
|
10802
|
+
"command",
|
|
10803
|
+
"prompt",
|
|
10804
|
+
"http",
|
|
10805
|
+
"function"
|
|
10806
|
+
]);
|
|
10222
10807
|
const qwencode = {};
|
|
10223
10808
|
for (const [eventName, definitions] of Object.entries(effectiveHooks)) {
|
|
10224
10809
|
const qwencodeEventName = CANONICAL_TO_QWENCODE_EVENT_NAMES[eventName] ?? eventName;
|
|
10225
10810
|
const byMatcher = /* @__PURE__ */ new Map();
|
|
10226
10811
|
for (const def of definitions) {
|
|
10812
|
+
if (!qwencodeSupportedTypes.has(def.type ?? "command")) continue;
|
|
10227
10813
|
const key = def.matcher ?? "";
|
|
10228
10814
|
const list = byMatcher.get(key);
|
|
10229
10815
|
if (list) list.push(def);
|
|
@@ -10283,9 +10869,10 @@ function qwencodeMatcherEntryToCanonical(entry) {
|
|
|
10283
10869
|
const sequential = entry.sequential === true;
|
|
10284
10870
|
const matcher = entry.matcher !== void 0 && entry.matcher !== null && entry.matcher !== "" ? entry.matcher : void 0;
|
|
10285
10871
|
for (const h of hooks) {
|
|
10286
|
-
const hookType = h.type === "command" || h.type === "prompt" || h.type === "http" ? h.type : "command";
|
|
10872
|
+
const hookType = h.type === "command" || h.type === "prompt" || h.type === "http" || h.type === "function" ? h.type : "command";
|
|
10287
10873
|
const isHttp = hookType === "http";
|
|
10288
10874
|
const isCommand = hookType === "command";
|
|
10875
|
+
const shell = h.shell === "bash" || h.shell === "powershell" ? h.shell : void 0;
|
|
10289
10876
|
defs.push({
|
|
10290
10877
|
type: hookType,
|
|
10291
10878
|
...compact({
|
|
@@ -10297,7 +10884,7 @@ function qwencodeMatcherEntryToCanonical(entry) {
|
|
|
10297
10884
|
statusMessage: h.statusMessage,
|
|
10298
10885
|
async: isCommand ? h.async : void 0,
|
|
10299
10886
|
env: isCommand ? h.env : void 0,
|
|
10300
|
-
shell: isCommand ?
|
|
10887
|
+
shell: isCommand ? shell : void 0,
|
|
10301
10888
|
headers: isHttp ? h.headers : void 0,
|
|
10302
10889
|
allowedEnvVars: isHttp ? h.allowedEnvVars : void 0,
|
|
10303
10890
|
once: isHttp ? h.once : void 0,
|
|
@@ -10384,15 +10971,11 @@ var QwencodeHooks = class QwencodeHooks extends ToolHooks {
|
|
|
10384
10971
|
} catch (error) {
|
|
10385
10972
|
throw new Error(`Failed to parse Qwen Code hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10386
10973
|
}
|
|
10387
|
-
const
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
} : {
|
|
10393
|
-
version: 1,
|
|
10394
|
-
hooks
|
|
10395
|
-
};
|
|
10974
|
+
const canonical = buildImportedHooksConfig({
|
|
10975
|
+
hooks: qwencodeHooksToCanonical(settings.hooks),
|
|
10976
|
+
overrideKey: "qwencode",
|
|
10977
|
+
...typeof settings.disableAllHooks === "boolean" && { extraOverride: { disableAllHooks: settings.disableAllHooks } }
|
|
10978
|
+
});
|
|
10396
10979
|
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(canonical, null, 2) });
|
|
10397
10980
|
}
|
|
10398
10981
|
validate() {
|
|
@@ -10554,10 +11137,10 @@ var ReasonixHooks = class ReasonixHooks extends ToolHooks {
|
|
|
10554
11137
|
throw new Error(`Failed to parse Reasonix hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10555
11138
|
}
|
|
10556
11139
|
const hooks = reasonixHooksToCanonical(settings.hooks);
|
|
10557
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10558
|
-
|
|
10559
|
-
|
|
10560
|
-
}, null, 2) });
|
|
11140
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
11141
|
+
hooks,
|
|
11142
|
+
overrideKey: "reasonix"
|
|
11143
|
+
}), null, 2) });
|
|
10561
11144
|
}
|
|
10562
11145
|
validate() {
|
|
10563
11146
|
return {
|
|
@@ -10780,10 +11363,10 @@ var VibeHooks = class VibeHooks extends ToolHooks {
|
|
|
10780
11363
|
throw new Error(`Failed to parse Vibe hooks content in ${join(this.getRelativeDirPath(), this.getRelativeFilePath())}: ${formatError(error)}`, { cause: error });
|
|
10781
11364
|
}
|
|
10782
11365
|
const hooks = vibeHooksToCanonical(parsed);
|
|
10783
|
-
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify({
|
|
10784
|
-
|
|
10785
|
-
|
|
10786
|
-
}, null, 2) });
|
|
11366
|
+
return this.toRulesyncHooksDefault({ fileContent: JSON.stringify(buildImportedHooksConfig({
|
|
11367
|
+
hooks,
|
|
11368
|
+
overrideKey: "vibe"
|
|
11369
|
+
}), null, 2) });
|
|
10787
11370
|
}
|
|
10788
11371
|
validate() {
|
|
10789
11372
|
try {
|
|
@@ -10870,7 +11453,13 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
10870
11453
|
supportsImport: true
|
|
10871
11454
|
},
|
|
10872
11455
|
supportedEvents: CLAUDE_HOOK_EVENTS,
|
|
10873
|
-
supportedHookTypes: [
|
|
11456
|
+
supportedHookTypes: [
|
|
11457
|
+
"command",
|
|
11458
|
+
"prompt",
|
|
11459
|
+
"http",
|
|
11460
|
+
"mcp_tool",
|
|
11461
|
+
"agent"
|
|
11462
|
+
],
|
|
10874
11463
|
supportsMatcher: true
|
|
10875
11464
|
}],
|
|
10876
11465
|
["codexcli", {
|
|
@@ -11062,7 +11651,12 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
11062
11651
|
supportsImport: true
|
|
11063
11652
|
},
|
|
11064
11653
|
supportedEvents: QWENCODE_HOOK_EVENTS,
|
|
11065
|
-
supportedHookTypes: [
|
|
11654
|
+
supportedHookTypes: [
|
|
11655
|
+
"command",
|
|
11656
|
+
"prompt",
|
|
11657
|
+
"http",
|
|
11658
|
+
"function"
|
|
11659
|
+
],
|
|
11066
11660
|
supportsMatcher: true
|
|
11067
11661
|
}],
|
|
11068
11662
|
["reasonix", {
|
|
@@ -12364,16 +12958,6 @@ var IgnoreProcessor = class extends FeatureProcessor {
|
|
|
12364
12958
|
}
|
|
12365
12959
|
};
|
|
12366
12960
|
//#endregion
|
|
12367
|
-
//#region src/constants/amp-paths.ts
|
|
12368
|
-
const AMP_DIR = ".amp";
|
|
12369
|
-
const AMP_GLOBAL_DIR = join(".config", "amp");
|
|
12370
|
-
const AMP_AGENTS_DIR = ".agents";
|
|
12371
|
-
const AMP_SKILLS_PROJECT_DIR = join(AMP_AGENTS_DIR, "skills");
|
|
12372
|
-
const AMP_SKILLS_GLOBAL_DIR = join(".config", "agents", "skills");
|
|
12373
|
-
const AMP_RULE_FILE_NAME = "AGENTS.md";
|
|
12374
|
-
const AMP_SETTINGS_FILE_NAME = "settings.json";
|
|
12375
|
-
const AMP_SETTINGS_JSONC_FILE_NAME = "settings.jsonc";
|
|
12376
|
-
//#endregion
|
|
12377
12961
|
//#region src/types/mcp.ts
|
|
12378
12962
|
const EnvVarNameSchema = z.string().check(refine((value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), "envVars entries must be valid environment variable names"));
|
|
12379
12963
|
const McpServerSchema = z.looseObject({
|
|
@@ -13465,10 +14049,19 @@ function mapOauthFromCodex(oauth) {
|
|
|
13465
14049
|
}
|
|
13466
14050
|
const CODEX_MCP_SERVER_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
13467
14051
|
function normalizeCodexMcpServerName(name) {
|
|
13468
|
-
if (PROTOTYPE_POLLUTION_KEYS.has(name)) return
|
|
13469
|
-
|
|
14052
|
+
if (!PROTOTYPE_POLLUTION_KEYS.has(name) && CODEX_MCP_SERVER_NAME_PATTERN.test(name)) return {
|
|
14053
|
+
codexName: name,
|
|
14054
|
+
usedFallback: false
|
|
14055
|
+
};
|
|
13470
14056
|
const normalizedName = name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
13471
|
-
|
|
14057
|
+
if (normalizedName && !PROTOTYPE_POLLUTION_KEYS.has(normalizedName)) return {
|
|
14058
|
+
codexName: normalizedName,
|
|
14059
|
+
usedFallback: false
|
|
14060
|
+
};
|
|
14061
|
+
return {
|
|
14062
|
+
codexName: `mcp_${createHash("sha256").update(name).digest("hex").slice(0, 8)}`,
|
|
14063
|
+
usedFallback: true
|
|
14064
|
+
};
|
|
13472
14065
|
}
|
|
13473
14066
|
function convertFromCodexFormat(codexMcp) {
|
|
13474
14067
|
const result = {};
|
|
@@ -13482,7 +14075,7 @@ function convertFromCodexFormat(codexMcp) {
|
|
|
13482
14075
|
} else if (key === "oauth" && isRecord(value)) converted[key] = mapOauthFromCodex(value);
|
|
13483
14076
|
else if (Object.hasOwn(CODEX_TO_RULESYNC_FIELD_MAP, key)) {
|
|
13484
14077
|
const mappedKey = CODEX_TO_RULESYNC_FIELD_MAP[key];
|
|
13485
|
-
if (mappedKey) if (isStringArray(value)) converted[mappedKey] = value;
|
|
14078
|
+
if (mappedKey) if (isStringArray$1(value)) converted[mappedKey] = value;
|
|
13486
14079
|
else warnWithFallback(void 0, `Ignored malformed array for ${key} in MCP server ${name}`);
|
|
13487
14080
|
} else converted[key] = value;
|
|
13488
14081
|
}
|
|
@@ -13494,12 +14087,9 @@ function convertToCodexFormat(mcpServers) {
|
|
|
13494
14087
|
const result = {};
|
|
13495
14088
|
const originalNames = /* @__PURE__ */ new Map();
|
|
13496
14089
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
13497
|
-
const codexName = normalizeCodexMcpServerName(name);
|
|
13498
|
-
if (codexName === null) {
|
|
13499
|
-
warnWithFallback(void 0, `MCP server "${name}" could not be normalized to a valid Codex MCP server name and was skipped.`);
|
|
13500
|
-
continue;
|
|
13501
|
-
}
|
|
13502
14090
|
if (!isRecord(config)) continue;
|
|
14091
|
+
const { codexName, usedFallback } = normalizeCodexMcpServerName(name);
|
|
14092
|
+
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.`);
|
|
13503
14093
|
const converted = {};
|
|
13504
14094
|
for (const [key, value] of Object.entries(config)) {
|
|
13505
14095
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
@@ -13508,12 +14098,12 @@ function convertToCodexFormat(mcpServers) {
|
|
|
13508
14098
|
} else if (key === "oauth" && isRecord(value)) converted[key] = mapOauthToCodex(value);
|
|
13509
14099
|
else if (Object.hasOwn(RULESYNC_TO_CODEX_FIELD_MAP, key)) {
|
|
13510
14100
|
const mappedKey = RULESYNC_TO_CODEX_FIELD_MAP[key];
|
|
13511
|
-
if (mappedKey) if (isStringArray(value)) converted[mappedKey] = value;
|
|
14101
|
+
if (mappedKey) if (isStringArray$1(value)) converted[mappedKey] = value;
|
|
13512
14102
|
else warnWithFallback(void 0, `[CodexCliMcp] Skipping invalid value type for mapped key '${key}': expected string array, got ${typeof value}`);
|
|
13513
14103
|
} else converted[key] = value;
|
|
13514
14104
|
}
|
|
13515
14105
|
const previousName = originalNames.get(codexName);
|
|
13516
|
-
if (previousName !== void 0) warnWithFallback(void 0, `Codex MCP server name collision: "${previousName}" and "${name}" both normalize to "${codexName}"
|
|
14106
|
+
if (previousName !== void 0) warnWithFallback(void 0, `Codex MCP server name collision: "${previousName}" and "${name}" both normalize to "${codexName}"; "${name}" (processed last) overwrites "${previousName}".`);
|
|
13517
14107
|
originalNames.set(codexName, name);
|
|
13518
14108
|
result[codexName] = converted;
|
|
13519
14109
|
}
|
|
@@ -13580,7 +14170,7 @@ var CodexcliMcp = class CodexcliMcp extends ToolMcp {
|
|
|
13580
14170
|
const rawServer = isRecord(rawMcpServers) ? rawMcpServers[serverName] : void 0;
|
|
13581
14171
|
return [serverName, {
|
|
13582
14172
|
...serverConfig,
|
|
13583
|
-
...isRecord(rawServer) && isStringArray(rawServer.envVars) ? { envVars: rawServer.envVars } : {}
|
|
14173
|
+
...isRecord(rawServer) && isStringArray$1(rawServer.envVars) ? { envVars: rawServer.envVars } : {}
|
|
13584
14174
|
}];
|
|
13585
14175
|
})));
|
|
13586
14176
|
const filteredMcpServers = this.removeEmptyEntries(converted);
|
|
@@ -14317,11 +14907,11 @@ function applyGooseStdioFields(ext, config) {
|
|
|
14317
14907
|
if (Array.isArray(command)) {
|
|
14318
14908
|
if (typeof command[0] === "string") ext.cmd = command[0];
|
|
14319
14909
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14320
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
14910
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14321
14911
|
if (rest.length > 0 || args.length > 0) ext.args = [...rest, ...args];
|
|
14322
14912
|
} else if (typeof command === "string") {
|
|
14323
14913
|
ext.cmd = command;
|
|
14324
|
-
if (isStringArray(config.args)) ext.args = config.args;
|
|
14914
|
+
if (isStringArray$1(config.args)) ext.args = config.args;
|
|
14325
14915
|
}
|
|
14326
14916
|
if (isPlainObject$1(config.env)) ext.envs = omitPrototypePollutionKeys(config.env);
|
|
14327
14917
|
}
|
|
@@ -14379,7 +14969,7 @@ function convertFromGooseFormat(extensions) {
|
|
|
14379
14969
|
else if (type === "streamable_http") server.type = "http";
|
|
14380
14970
|
else if (type === "stdio") server.type = "stdio";
|
|
14381
14971
|
if (typeof ext.cmd === "string") server.command = ext.cmd;
|
|
14382
|
-
if (isStringArray(ext.args)) server.args = ext.args;
|
|
14972
|
+
if (isStringArray$1(ext.args)) server.args = ext.args;
|
|
14383
14973
|
if (isPlainObject$1(ext.envs)) server.env = omitPrototypePollutionKeys(ext.envs);
|
|
14384
14974
|
if (typeof ext.uri === "string") server.url = ext.uri;
|
|
14385
14975
|
if (isPlainObject$1(ext.headers)) server.headers = omitPrototypePollutionKeys(ext.headers);
|
|
@@ -14399,11 +14989,11 @@ function buildGoosePluginStdioServer(config) {
|
|
|
14399
14989
|
if (Array.isArray(command)) {
|
|
14400
14990
|
if (typeof command[0] === "string") server.command = command[0];
|
|
14401
14991
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14402
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
14992
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14403
14993
|
if (rest.length > 0 || args.length > 0) server.args = [...rest, ...args];
|
|
14404
14994
|
} else if (typeof command === "string") {
|
|
14405
14995
|
server.command = command;
|
|
14406
|
-
if (isStringArray(config.args)) server.args = config.args;
|
|
14996
|
+
if (isStringArray$1(config.args)) server.args = config.args;
|
|
14407
14997
|
}
|
|
14408
14998
|
if (isPlainObject$1(config.env)) server.env = omitPrototypePollutionKeys(config.env);
|
|
14409
14999
|
if (typeof config.cwd === "string") server.cwd = config.cwd;
|
|
@@ -14716,7 +15306,7 @@ function resolveHermesTimeout(config) {
|
|
|
14716
15306
|
*/
|
|
14717
15307
|
function copyHermesAdvancedFields(source, target) {
|
|
14718
15308
|
if (typeof source.auth === "string") target.auth = source.auth;
|
|
14719
|
-
if (typeof source.client_cert === "string" || isStringArray(source.client_cert)) target.client_cert = source.client_cert;
|
|
15309
|
+
if (typeof source.client_cert === "string" || isStringArray$1(source.client_cert)) target.client_cert = source.client_cert;
|
|
14720
15310
|
if (typeof source.client_key === "string") target.client_key = source.client_key;
|
|
14721
15311
|
if (typeof source.connect_timeout === "number") target.connect_timeout = source.connect_timeout;
|
|
14722
15312
|
if (typeof source.supports_parallel_tool_calls === "boolean") target.supports_parallel_tool_calls = source.supports_parallel_tool_calls;
|
|
@@ -14735,8 +15325,8 @@ function copyHermesAdvancedFields(source, target) {
|
|
|
14735
15325
|
*/
|
|
14736
15326
|
function buildHermesToolsBlock(config) {
|
|
14737
15327
|
const tools = {};
|
|
14738
|
-
if (isStringArray(config.enabledTools)) tools.include = config.enabledTools;
|
|
14739
|
-
if (isStringArray(config.disabledTools)) tools.exclude = config.disabledTools;
|
|
15328
|
+
if (isStringArray$1(config.enabledTools)) tools.include = config.enabledTools;
|
|
15329
|
+
if (isStringArray$1(config.disabledTools)) tools.exclude = config.disabledTools;
|
|
14740
15330
|
if (typeof config.promptsEnabled === "boolean") tools.prompts = config.promptsEnabled;
|
|
14741
15331
|
if (typeof config.resourcesEnabled === "boolean") tools.resources = config.resourcesEnabled;
|
|
14742
15332
|
return tools;
|
|
@@ -14748,8 +15338,8 @@ function buildHermesToolsBlock(config) {
|
|
|
14748
15338
|
* `promptsEnabled`/`resourcesEnabled` top-level toggles.
|
|
14749
15339
|
*/
|
|
14750
15340
|
function applyHermesToolsBlock(hermesTools, server) {
|
|
14751
|
-
if (isStringArray(hermesTools.include)) server.enabledTools = hermesTools.include;
|
|
14752
|
-
if (isStringArray(hermesTools.exclude)) server.disabledTools = hermesTools.exclude;
|
|
15341
|
+
if (isStringArray$1(hermesTools.include)) server.enabledTools = hermesTools.include;
|
|
15342
|
+
if (isStringArray$1(hermesTools.exclude)) server.disabledTools = hermesTools.exclude;
|
|
14753
15343
|
if (typeof hermesTools.prompts === "boolean") server.promptsEnabled = hermesTools.prompts;
|
|
14754
15344
|
if (typeof hermesTools.resources === "boolean") server.resourcesEnabled = hermesTools.resources;
|
|
14755
15345
|
}
|
|
@@ -14773,11 +15363,11 @@ function convertServerToHermes(config) {
|
|
|
14773
15363
|
if (Array.isArray(command)) {
|
|
14774
15364
|
if (typeof command[0] === "string") out.command = command[0];
|
|
14775
15365
|
const rest = command.slice(1).filter((c) => typeof c === "string");
|
|
14776
|
-
const args = isStringArray(config.args) ? config.args : [];
|
|
15366
|
+
const args = isStringArray$1(config.args) ? config.args : [];
|
|
14777
15367
|
if (rest.length > 0 || args.length > 0) out.args = [...rest, ...args];
|
|
14778
15368
|
} else if (typeof command === "string") {
|
|
14779
15369
|
out.command = command;
|
|
14780
|
-
if (isStringArray(config.args)) out.args = config.args;
|
|
15370
|
+
if (isStringArray$1(config.args)) out.args = config.args;
|
|
14781
15371
|
}
|
|
14782
15372
|
if (isPlainObject$1(config.env)) out.env = omitPrototypePollutionKeys(config.env);
|
|
14783
15373
|
} else if (url !== void 0) {
|
|
@@ -14825,7 +15415,7 @@ function convertFromHermesFormat(mcpServers) {
|
|
|
14825
15415
|
if (PROTOTYPE_POLLUTION_KEYS.has(name) || !isRecord(config)) continue;
|
|
14826
15416
|
const server = {};
|
|
14827
15417
|
if (typeof config.command === "string") server.command = config.command;
|
|
14828
|
-
if (isStringArray(config.args)) server.args = config.args;
|
|
15418
|
+
if (isStringArray$1(config.args)) server.args = config.args;
|
|
14829
15419
|
if (isPlainObject$1(config.env)) server.env = omitPrototypePollutionKeys(config.env);
|
|
14830
15420
|
if (typeof config.url === "string") server.url = config.url;
|
|
14831
15421
|
if (isPlainObject$1(config.headers)) server.headers = omitPrototypePollutionKeys(config.headers);
|
|
@@ -17150,7 +17740,11 @@ const VibePermissionsOverrideSchema = z.looseObject({ permission: z.optional(z.r
|
|
|
17150
17740
|
*/
|
|
17151
17741
|
const CursorPermissionsOverrideSchema = z.looseObject({
|
|
17152
17742
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17153
|
-
approvalMode: z.optional(z.
|
|
17743
|
+
approvalMode: z.optional(z.enum([
|
|
17744
|
+
"allowlist",
|
|
17745
|
+
"auto-review",
|
|
17746
|
+
"unrestricted"
|
|
17747
|
+
])),
|
|
17154
17748
|
sandbox: z.optional(z.looseObject({}))
|
|
17155
17749
|
});
|
|
17156
17750
|
/**
|
|
@@ -17238,7 +17832,11 @@ const FactorydroidPermissionsOverrideSchema = z.looseObject({
|
|
|
17238
17832
|
*/
|
|
17239
17833
|
const WarpPermissionsOverrideSchema = z.looseObject({
|
|
17240
17834
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17241
|
-
agent_mode_coding_permissions: z.optional(z.
|
|
17835
|
+
agent_mode_coding_permissions: z.optional(z.enum([
|
|
17836
|
+
"always_ask_before_reading",
|
|
17837
|
+
"always_allow_reading",
|
|
17838
|
+
"allow_reading_specific_files"
|
|
17839
|
+
])),
|
|
17242
17840
|
agent_mode_coding_file_read_allowlist: z.optional(z.array(z.string())),
|
|
17243
17841
|
agent_mode_execute_readonly_commands: z.optional(z.boolean())
|
|
17244
17842
|
});
|
|
@@ -17284,7 +17882,11 @@ const JuniePermissionsOverrideSchema = z.looseObject({
|
|
|
17284
17882
|
*/
|
|
17285
17883
|
const TaktPermissionsOverrideSchema = z.looseObject({
|
|
17286
17884
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17287
|
-
step_permission_overrides: z.optional(z.record(z.string(), z.
|
|
17885
|
+
step_permission_overrides: z.optional(z.record(z.string(), z.enum([
|
|
17886
|
+
"readonly",
|
|
17887
|
+
"edit",
|
|
17888
|
+
"full"
|
|
17889
|
+
]))),
|
|
17288
17890
|
provider_options: z.optional(z.looseObject({}))
|
|
17289
17891
|
});
|
|
17290
17892
|
/**
|
|
@@ -17314,9 +17916,15 @@ const AmpPermissionsOverrideSchema = z.looseObject({
|
|
|
17314
17916
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17315
17917
|
permissions: z.optional(z.array(z.looseObject({
|
|
17316
17918
|
tool: z.string(),
|
|
17317
|
-
action: z.
|
|
17919
|
+
action: z.enum([
|
|
17920
|
+
"allow",
|
|
17921
|
+
"ask",
|
|
17922
|
+
"reject",
|
|
17923
|
+
"delegate"
|
|
17924
|
+
]),
|
|
17925
|
+
context: z.optional(z.enum(["thread", "subagent"]))
|
|
17318
17926
|
}))),
|
|
17319
|
-
mcpPermissions: z.optional(z.array(z.looseObject({}))),
|
|
17927
|
+
mcpPermissions: z.optional(z.array(z.looseObject({ action: z.enum(["allow", "reject"]) }))),
|
|
17320
17928
|
guardedFiles: z.optional(z.looseObject({ allowlist: z.optional(z.array(z.string())) })),
|
|
17321
17929
|
dangerouslyAllowAll: z.optional(z.boolean())
|
|
17322
17930
|
});
|
|
@@ -17341,7 +17949,12 @@ const AmpPermissionsOverrideSchema = z.looseObject({
|
|
|
17341
17949
|
*/
|
|
17342
17950
|
const AntigravityCliPermissionsOverrideSchema = z.looseObject({
|
|
17343
17951
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17344
|
-
toolPermission: z.optional(z.
|
|
17952
|
+
toolPermission: z.optional(z.enum([
|
|
17953
|
+
"request-review",
|
|
17954
|
+
"proceed-in-sandbox",
|
|
17955
|
+
"always-proceed",
|
|
17956
|
+
"strict"
|
|
17957
|
+
])),
|
|
17345
17958
|
enableTerminalSandbox: z.optional(z.boolean())
|
|
17346
17959
|
});
|
|
17347
17960
|
/**
|
|
@@ -17370,7 +17983,14 @@ const AugmentcodePermissionsOverrideSchema = z.looseObject({
|
|
|
17370
17983
|
permission: z.optional(ToolScopedPermissionSchema),
|
|
17371
17984
|
toolPermissions: z.optional(z.array(z.looseObject({
|
|
17372
17985
|
toolName: z.string(),
|
|
17373
|
-
|
|
17986
|
+
eventType: z.optional(z.enum(["tool-call", "tool-response"])),
|
|
17987
|
+
permission: z.looseObject({ type: z.enum([
|
|
17988
|
+
"allow",
|
|
17989
|
+
"deny",
|
|
17990
|
+
"ask-user",
|
|
17991
|
+
"webhook-policy",
|
|
17992
|
+
"script-policy"
|
|
17993
|
+
]) })
|
|
17374
17994
|
})))
|
|
17375
17995
|
});
|
|
17376
17996
|
/**
|
|
@@ -17460,12 +18080,20 @@ const CodexApprovalsReviewerSchema = z.enum([
|
|
|
17460
18080
|
* `[permissions.rulesync]` profile may extend. Codex ships three built-in
|
|
17461
18081
|
* profiles (`:read-only`, `:workspace`, `:danger-full-access`; the leading
|
|
17462
18082
|
* colon is reserved for built-ins), but `extends` rejects
|
|
17463
|
-
* `:danger-full-access` at config load time, so only
|
|
17464
|
-
*
|
|
17465
|
-
*
|
|
18083
|
+
* `:danger-full-access` at config load time, so only these two are valid
|
|
18084
|
+
* `extends` parents. The value list is exported so the Codex CLI translator
|
|
18085
|
+
* derives its import-side baseline check from the same source.
|
|
17466
18086
|
* @see https://learn.chatgpt.com/docs/permissions
|
|
17467
18087
|
*/
|
|
17468
|
-
const
|
|
18088
|
+
const CODEX_EXTENDABLE_BASELINE_PROFILES = [":read-only", ":workspace"];
|
|
18089
|
+
/**
|
|
18090
|
+
* All accepted `codexcli.base_permission_profile` values. `:danger-full-access`
|
|
18091
|
+
* cannot be an `extends` parent, so selecting it makes rulesync emit
|
|
18092
|
+
* `default_permissions = ":danger-full-access"` directly and skip the managed
|
|
18093
|
+
* `[permissions.rulesync]` profile entirely (there is no sandbox for
|
|
18094
|
+
* filesystem/network rules to refine in that mode).
|
|
18095
|
+
*/
|
|
18096
|
+
const CODEX_BASE_PERMISSION_PROFILES = [...CODEX_EXTENDABLE_BASELINE_PROFILES, ":danger-full-access"];
|
|
17469
18097
|
const CodexBasePermissionProfileSchema = z.enum(CODEX_BASE_PERMISSION_PROFILES);
|
|
17470
18098
|
/**
|
|
17471
18099
|
* Codex CLI-scoped permission override.
|
|
@@ -17476,10 +18104,14 @@ const CodexBasePermissionProfileSchema = z.enum(CODEX_BASE_PERMISSION_PROFILES);
|
|
|
17476
18104
|
* override whose fields are written verbatim as top-level `.codex/config.toml`
|
|
17477
18105
|
* keys (the override wins per key; existing sibling keys the user set directly
|
|
17478
18106
|
* are preserved):
|
|
17479
|
-
* - `base_permission_profile` — the built-in profile
|
|
17480
|
-
*
|
|
17481
|
-
*
|
|
17482
|
-
*
|
|
18107
|
+
* - `base_permission_profile` — the built-in baseline profile (`:read-only` |
|
|
18108
|
+
* `:workspace` | `:danger-full-access`). Unlike the other keys it is not a
|
|
18109
|
+
* top-level config key: the extendable baselines are emitted as the managed
|
|
18110
|
+
* `[permissions.rulesync]` profile's `extends` value, while
|
|
18111
|
+
* `:danger-full-access` (which Codex rejects as an `extends` parent) is
|
|
18112
|
+
* selected directly via `default_permissions` and skips the managed profile
|
|
18113
|
+
* entirely — canonical filesystem/network rules are ignored in that mode.
|
|
18114
|
+
* Defaults to `:workspace` when unspecified.
|
|
17483
18115
|
* - `approval_policy` — `untrusted` | `on-request` (legacy alias `on-failure`) |
|
|
17484
18116
|
* `never`, or a `{ granular = { … } }` table (kept verbatim; the granular
|
|
17485
18117
|
* schema has required fields that are brittle to model as typed keys).
|
|
@@ -17500,13 +18132,14 @@ const CodexBasePermissionProfileSchema = z.enum(CODEX_BASE_PERMISSION_PROFILES);
|
|
|
17500
18132
|
* Defaults to `auto_review` when neither the override nor the existing
|
|
17501
18133
|
* config sets it.
|
|
17502
18134
|
* - `git_write_rules` — whether the managed profile's `:workspace_roots` table
|
|
17503
|
-
* emits the default `.git` carve-
|
|
17504
|
-
* `".git/config" = "read"` kept read-only as a security guard). Codex's
|
|
18135
|
+
* emits the default `.git` carve-out (`".git/**" = "write"`). Codex's
|
|
17505
18136
|
* `:workspace` baseline makes `.git` read-only, which denies basic git
|
|
17506
18137
|
* workflows (commit/stage writes to `.git/index`, `.git/objects`, refs,
|
|
17507
|
-
* logs
|
|
17508
|
-
*
|
|
17509
|
-
*
|
|
18138
|
+
* logs; everyday commands like `git remote add` or `git push -u` write to
|
|
18139
|
+
* `.git/config`), so the carve-out is emitted by default. Defaults to
|
|
18140
|
+
* `true`; only an explicit `false` suppresses it. Like
|
|
18141
|
+
* `base_permission_profile` it is consumed by the profile builder, not
|
|
18142
|
+
* written as a top-level config key.
|
|
17510
18143
|
*
|
|
17511
18144
|
* Two surfaces are deliberately NOT authorable here so the override can never
|
|
17512
18145
|
* clobber a feature-owned key: `mcp_servers.*` per-MCP gating is owned by the
|
|
@@ -19503,15 +20136,13 @@ const RULESYNC_PROFILE_NAME = "rulesync";
|
|
|
19503
20136
|
const CODEX_WORKSPACE_ROOTS_KEY = ":workspace_roots";
|
|
19504
20137
|
const CODEX_WORKSPACE_BASELINE = ":workspace";
|
|
19505
20138
|
const CODEX_READ_ONLY_BASELINE = ":read-only";
|
|
19506
|
-
const
|
|
20139
|
+
const CODEX_DANGER_FULL_ACCESS_BASELINE = ":danger-full-access";
|
|
20140
|
+
const CODEX_EXTENDABLE_BASELINES = new Set(CODEX_EXTENDABLE_BASELINE_PROFILES);
|
|
19507
20141
|
const CODEX_DEFAULT_APPROVAL_POLICY = "on-request";
|
|
19508
20142
|
const CODEX_DEFAULT_APPROVALS_REVIEWER = "auto_review";
|
|
19509
20143
|
const CODEX_GLOB_SCAN_MAX_DEPTH = 8;
|
|
19510
20144
|
const CODEX_MINIMAL_KEY = ":minimal";
|
|
19511
|
-
const CODEX_GIT_WRITE_RULES = {
|
|
19512
|
-
".git/**": "write",
|
|
19513
|
-
".git/config": "read"
|
|
19514
|
-
};
|
|
20145
|
+
const CODEX_GIT_WRITE_RULES = { ".git/**": "write" };
|
|
19515
20146
|
const GLOBAL_WILDCARD_DOMAIN = "*";
|
|
19516
20147
|
var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
19517
20148
|
static getSettablePaths(_options = {}) {
|
|
@@ -19539,8 +20170,40 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
|
19539
20170
|
const filePath = join(outputRoot, paths.relativeDirPath, paths.relativeFilePath);
|
|
19540
20171
|
const existingContent = await readFileContentOrNull(filePath) ?? "";
|
|
19541
20172
|
const existing = toMutableTable(smolToml.parse(existingContent || smolToml.stringify({})));
|
|
20173
|
+
const canonicalConfig = rulesyncPermissions.getJson();
|
|
20174
|
+
if (canonicalConfig.codexcli?.base_permission_profile === CODEX_DANGER_FULL_ACCESS_BASELINE) {
|
|
20175
|
+
const ignoredCategories = Object.entries(canonicalConfig.permission).filter(([category, rules]) => category !== "bash" && Object.keys(rules).length > 0).map(([category]) => category);
|
|
20176
|
+
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.`);
|
|
20177
|
+
const permissionsTable = toMutableTable(existing.permissions);
|
|
20178
|
+
if (permissionsTable[RULESYNC_PROFILE_NAME] !== void 0) {
|
|
20179
|
+
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.`);
|
|
20180
|
+
delete permissionsTable[RULESYNC_PROFILE_NAME];
|
|
20181
|
+
}
|
|
20182
|
+
const overridePatch = computeCodexcliOverridePatch({
|
|
20183
|
+
existing,
|
|
20184
|
+
override: canonicalConfig.codexcli,
|
|
20185
|
+
logger
|
|
20186
|
+
});
|
|
20187
|
+
return new CodexcliPermissions({
|
|
20188
|
+
outputRoot,
|
|
20189
|
+
relativeDirPath: paths.relativeDirPath,
|
|
20190
|
+
relativeFilePath: paths.relativeFilePath,
|
|
20191
|
+
fileContent: applySharedConfigPatch({
|
|
20192
|
+
fileKey: sharedConfigFileKey(paths),
|
|
20193
|
+
feature: "permissions",
|
|
20194
|
+
existingContent,
|
|
20195
|
+
patch: {
|
|
20196
|
+
permissions: Object.keys(permissionsTable).length > 0 ? permissionsTable : void 0,
|
|
20197
|
+
default_permissions: CODEX_DANGER_FULL_ACCESS_BASELINE,
|
|
20198
|
+
...overridePatch
|
|
20199
|
+
},
|
|
20200
|
+
filePath
|
|
20201
|
+
}),
|
|
20202
|
+
validate
|
|
20203
|
+
});
|
|
20204
|
+
}
|
|
19542
20205
|
const newProfile = convertRulesyncToCodexProfile({
|
|
19543
|
-
config:
|
|
20206
|
+
config: canonicalConfig,
|
|
19544
20207
|
logger
|
|
19545
20208
|
});
|
|
19546
20209
|
const permissionsTable = toMutableTable(existing.permissions);
|
|
@@ -19601,6 +20264,7 @@ var CodexcliPermissions = class CodexcliPermissions extends ToolPermissions {
|
|
|
19601
20264
|
});
|
|
19602
20265
|
const override = extractCodexcliOverride(table);
|
|
19603
20266
|
if (typeof profile?.extends === "string" && CODEX_EXTENDABLE_BASELINES.has(profile.extends)) override.base_permission_profile = profile.extends;
|
|
20267
|
+
if (defaultProfile === CODEX_DANGER_FULL_ACCESS_BASELINE) override.base_permission_profile = CODEX_DANGER_FULL_ACCESS_BASELINE;
|
|
19604
20268
|
const result = Object.keys(override).length > 0 ? {
|
|
19605
20269
|
...config,
|
|
19606
20270
|
codexcli: override
|
|
@@ -19656,16 +20320,10 @@ function convertRulesyncToCodexProfile({ config, logger }) {
|
|
|
19656
20320
|
const filesystem = { [CODEX_MINIMAL_KEY]: "read" };
|
|
19657
20321
|
const workspaceRootFilesystem = {};
|
|
19658
20322
|
const domains = {};
|
|
20323
|
+
const filesystemCategoryRules = {};
|
|
19659
20324
|
for (const [toolName, rules] of Object.entries(config.permission)) {
|
|
19660
20325
|
if (toolName === "read" || toolName === "edit" || toolName === "write") {
|
|
19661
|
-
|
|
19662
|
-
for (const [pattern, action] of Object.entries(rules)) addFilesystemRule({
|
|
19663
|
-
filesystem,
|
|
19664
|
-
workspaceRootFilesystem,
|
|
19665
|
-
pattern,
|
|
19666
|
-
access: mapAction(action),
|
|
19667
|
-
logger
|
|
19668
|
-
});
|
|
20326
|
+
filesystemCategoryRules[toolName] = rules;
|
|
19669
20327
|
continue;
|
|
19670
20328
|
}
|
|
19671
20329
|
if (toolName === "webfetch") {
|
|
@@ -19678,6 +20336,16 @@ function convertRulesyncToCodexProfile({ config, logger }) {
|
|
|
19678
20336
|
}
|
|
19679
20337
|
logger?.warn(`Codex CLI permissions support only read/edit/write/webfetch categories. Skipping: ${toolName}`);
|
|
19680
20338
|
}
|
|
20339
|
+
for (const [pattern, access] of mergeFilesystemCategoryRules({
|
|
20340
|
+
categoryRules: filesystemCategoryRules,
|
|
20341
|
+
logger
|
|
20342
|
+
})) addFilesystemRule({
|
|
20343
|
+
filesystem,
|
|
20344
|
+
workspaceRootFilesystem,
|
|
20345
|
+
pattern,
|
|
20346
|
+
access,
|
|
20347
|
+
logger
|
|
20348
|
+
});
|
|
19681
20349
|
applyDefaultGitWriteRules({
|
|
19682
20350
|
config,
|
|
19683
20351
|
filesystem,
|
|
@@ -19958,6 +20626,67 @@ function mapReadAction(action) {
|
|
|
19958
20626
|
function mapWriteAction(action) {
|
|
19959
20627
|
return action === "allow" ? "write" : "deny";
|
|
19960
20628
|
}
|
|
20629
|
+
/**
|
|
20630
|
+
* Merge the canonical read/edit/write category rules into one Codex access
|
|
20631
|
+
* level per path pattern (Codex models a single `deny` < `read` < `write`
|
|
20632
|
+
* level, with no `ask`).
|
|
20633
|
+
*
|
|
20634
|
+
* - `edit` and `write` collapse onto Codex's write side; when both carry the
|
|
20635
|
+
* same pattern, the more restrictive action wins (`deny` > `ask` > `allow`).
|
|
20636
|
+
* - `read: allow` + write-side `allow` → `"write"`.
|
|
20637
|
+
* - `read: allow` + write-side non-allow → `"read"` (readable but not
|
|
20638
|
+
* writable — exactly what Codex's `"read"` level expresses).
|
|
20639
|
+
* - `read` non-allow → `"deny"` regardless of the write side; a contradictory
|
|
20640
|
+
* write-side `allow` (unreadable but writable is not expressible in Codex)
|
|
20641
|
+
* is warned about.
|
|
20642
|
+
* - Single-category patterns keep the existing mapReadAction/mapWriteAction
|
|
20643
|
+
* mappings.
|
|
20644
|
+
*
|
|
20645
|
+
* Iteration order is read → edit → write with first-seen pattern order, so
|
|
20646
|
+
* the emitted table is stable regardless of the authored category order.
|
|
20647
|
+
* Note the merge is one-way: `"{path}" = "read"` imports back as
|
|
20648
|
+
* `read: allow` only (the explicit write-side deny is implied by Codex's
|
|
20649
|
+
* access level and not re-materialized).
|
|
20650
|
+
*/
|
|
20651
|
+
function mergeFilesystemCategoryRules({ categoryRules, logger }) {
|
|
20652
|
+
const readRules = categoryRules.read ?? {};
|
|
20653
|
+
const writeSideRestrictiveness = {
|
|
20654
|
+
deny: 2,
|
|
20655
|
+
ask: 1,
|
|
20656
|
+
allow: 0
|
|
20657
|
+
};
|
|
20658
|
+
const writeSideRules = {};
|
|
20659
|
+
for (const category of ["edit", "write"]) for (const [pattern, action] of Object.entries(categoryRules[category] ?? {})) {
|
|
20660
|
+
const existing = writeSideRules[pattern];
|
|
20661
|
+
if (existing === void 0 || writeSideRestrictiveness[action] > writeSideRestrictiveness[existing]) writeSideRules[pattern] = action;
|
|
20662
|
+
}
|
|
20663
|
+
const patterns = [];
|
|
20664
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20665
|
+
for (const pattern of [...Object.keys(readRules), ...Object.keys(writeSideRules)]) if (!seen.has(pattern)) {
|
|
20666
|
+
seen.add(pattern);
|
|
20667
|
+
patterns.push(pattern);
|
|
20668
|
+
}
|
|
20669
|
+
const merged = [];
|
|
20670
|
+
for (const pattern of patterns) {
|
|
20671
|
+
const readAction = readRules[pattern];
|
|
20672
|
+
const writeAction = writeSideRules[pattern];
|
|
20673
|
+
if (readAction === void 0) {
|
|
20674
|
+
merged.push([pattern, mapWriteAction(writeAction)]);
|
|
20675
|
+
continue;
|
|
20676
|
+
}
|
|
20677
|
+
if (writeAction === void 0) {
|
|
20678
|
+
merged.push([pattern, mapReadAction(readAction)]);
|
|
20679
|
+
continue;
|
|
20680
|
+
}
|
|
20681
|
+
if (readAction === "allow") {
|
|
20682
|
+
merged.push([pattern, writeAction === "allow" ? "write" : "read"]);
|
|
20683
|
+
continue;
|
|
20684
|
+
}
|
|
20685
|
+
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".`);
|
|
20686
|
+
merged.push([pattern, "deny"]);
|
|
20687
|
+
}
|
|
20688
|
+
return merged;
|
|
20689
|
+
}
|
|
19961
20690
|
function buildCodexBashRulesContent(config) {
|
|
19962
20691
|
const bashRules = config.permission.bash ?? {};
|
|
19963
20692
|
const entries = Object.entries(bashRules);
|
|
@@ -20909,7 +21638,7 @@ function convertRulesyncToGoosePermissionConfig({ config, logger }) {
|
|
|
20909
21638
|
function convertGoosePermissionConfigToRulesync(userPermission) {
|
|
20910
21639
|
const permission = {};
|
|
20911
21640
|
for (const key of GOOSE_PERMISSION_LIST_KEYS) {
|
|
20912
|
-
const toolNames = isStringArray(userPermission[key]) ? userPermission[key] : [];
|
|
21641
|
+
const toolNames = isStringArray$1(userPermission[key]) ? userPermission[key] : [];
|
|
20913
21642
|
const action = GOOSE_LIST_TO_ACTION[key];
|
|
20914
21643
|
for (const toolName of toolNames) {
|
|
20915
21644
|
const category = GOOSE_TO_RULESYNC_TOOL_NAME[toolName] ?? toolName;
|
|
@@ -21149,7 +21878,7 @@ const ACTION_RANK = {
|
|
|
21149
21878
|
* (mirrors the Cursor adapter's preservation of unmanaged types).
|
|
21150
21879
|
*/
|
|
21151
21880
|
function unmanagedEntries(existingPermission, key) {
|
|
21152
|
-
return (isStringArray(existingPermission[key]) ? existingPermission[key] : []).filter((entry) => parseGrokEntry(entry) === null);
|
|
21881
|
+
return (isStringArray$1(existingPermission[key]) ? existingPermission[key] : []).filter((entry) => parseGrokEntry(entry) === null);
|
|
21153
21882
|
}
|
|
21154
21883
|
/**
|
|
21155
21884
|
* Bucket canonical rules into Grok's `[permission]` allow/deny/ask arrays of
|
|
@@ -21190,9 +21919,9 @@ function buildGrokPermissionArrays(config, existingPermission, logger) {
|
|
|
21190
21919
|
* arrays resolves to the strictest action.
|
|
21191
21920
|
*/
|
|
21192
21921
|
function parseGrokPermissionArrays(permission) {
|
|
21193
|
-
const allow = isStringArray(permission.allow) ? permission.allow : void 0;
|
|
21194
|
-
const deny = isStringArray(permission.deny) ? permission.deny : void 0;
|
|
21195
|
-
const ask = isStringArray(permission.ask) ? permission.ask : void 0;
|
|
21922
|
+
const allow = isStringArray$1(permission.allow) ? permission.allow : void 0;
|
|
21923
|
+
const deny = isStringArray$1(permission.deny) ? permission.deny : void 0;
|
|
21924
|
+
const ask = isStringArray$1(permission.ask) ? permission.ask : void 0;
|
|
21196
21925
|
if ((allow?.length ?? 0) + (deny?.length ?? 0) + (ask?.length ?? 0) === 0) return null;
|
|
21197
21926
|
const result = {};
|
|
21198
21927
|
const apply = (entries, action) => {
|
|
@@ -22973,7 +23702,7 @@ function convertRovodevToolPermissionsToRulesync(toolPermissions) {
|
|
|
22973
23702
|
permission[category][CATCH_ALL_PATTERN$1] = value;
|
|
22974
23703
|
}
|
|
22975
23704
|
}
|
|
22976
|
-
if (isStringArray(toolPermissions.allowedExternalPaths)) for (const path of toolPermissions.allowedExternalPaths) {
|
|
23705
|
+
if (isStringArray$1(toolPermissions.allowedExternalPaths)) for (const path of toolPermissions.allowedExternalPaths) {
|
|
22977
23706
|
permission.read ??= {};
|
|
22978
23707
|
permission.read[path] = "allow";
|
|
22979
23708
|
}
|
|
@@ -23533,8 +24262,8 @@ var WarpPermissions = class WarpPermissions extends ToolPermissions {
|
|
|
23533
24262
|
const agents = isRecord(settings.agents) ? settings.agents : {};
|
|
23534
24263
|
const profiles = isRecord(agents.profiles) ? agents.profiles : {};
|
|
23535
24264
|
const config = convertWarpToRulesyncPermissions({
|
|
23536
|
-
allow: isStringArray(profiles[ALLOWLIST_KEY]) ? profiles[ALLOWLIST_KEY] : [],
|
|
23537
|
-
deny: isStringArray(profiles[DENYLIST_KEY]) ? profiles[DENYLIST_KEY] : []
|
|
24265
|
+
allow: isStringArray$1(profiles[ALLOWLIST_KEY]) ? profiles[ALLOWLIST_KEY] : [],
|
|
24266
|
+
deny: isStringArray$1(profiles[DENYLIST_KEY]) ? profiles[DENYLIST_KEY] : []
|
|
23538
24267
|
});
|
|
23539
24268
|
const warpOverride = {};
|
|
23540
24269
|
for (const key of WARP_OVERRIDE_KEYS) if (profiles[key] !== void 0) warpOverride[key] = profiles[key];
|
|
@@ -24114,9 +24843,6 @@ var PermissionsProcessor = class extends FeatureProcessor {
|
|
|
24114
24843
|
}
|
|
24115
24844
|
};
|
|
24116
24845
|
//#endregion
|
|
24117
|
-
//#region src/constants/general.ts
|
|
24118
|
-
const SKILL_FILE_NAME = "SKILL.md";
|
|
24119
|
-
//#endregion
|
|
24120
24846
|
//#region src/types/ai-dir.ts
|
|
24121
24847
|
var AiDir = class {
|
|
24122
24848
|
/**
|
|
@@ -24317,10 +25043,10 @@ var ToolSkill = class extends AiDir {
|
|
|
24317
25043
|
const settablePaths = getSettablePaths({ global });
|
|
24318
25044
|
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
24319
25045
|
const skillDirPath = join(outputRoot, actualRelativeDirPath, dirName);
|
|
24320
|
-
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME);
|
|
24321
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25046
|
+
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME$1);
|
|
25047
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24322
25048
|
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24323
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25049
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24324
25050
|
return {
|
|
24325
25051
|
outputRoot,
|
|
24326
25052
|
relativeDirPath: actualRelativeDirPath,
|
|
@@ -24362,7 +25088,7 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
24362
25088
|
relativeDirPath,
|
|
24363
25089
|
dirName,
|
|
24364
25090
|
mainFile: {
|
|
24365
|
-
name: SKILL_FILE_NAME,
|
|
25091
|
+
name: SKILL_FILE_NAME$1,
|
|
24366
25092
|
body,
|
|
24367
25093
|
frontmatter: { ...frontmatter }
|
|
24368
25094
|
},
|
|
@@ -24420,12 +25146,12 @@ var SimulatedSkill = class extends ToolSkill {
|
|
|
24420
25146
|
const settablePaths = this.getSettablePaths();
|
|
24421
25147
|
const actualRelativeDirPath = relativeDirPath ?? settablePaths.relativeDirPath;
|
|
24422
25148
|
const skillDirPath = join(outputRoot, actualRelativeDirPath, dirName);
|
|
24423
|
-
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME);
|
|
24424
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25149
|
+
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME$1);
|
|
25150
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24425
25151
|
const { frontmatter, body: content } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24426
25152
|
const result = SimulatedSkillFrontmatterSchema.safeParse(frontmatter);
|
|
24427
25153
|
if (!result.success) throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
24428
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25154
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, actualRelativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24429
25155
|
return {
|
|
24430
25156
|
outputRoot,
|
|
24431
25157
|
relativeDirPath: actualRelativeDirPath,
|
|
@@ -24635,7 +25361,7 @@ var RulesyncSkill = class RulesyncSkill extends AiDir {
|
|
|
24635
25361
|
relativeDirPath,
|
|
24636
25362
|
dirName,
|
|
24637
25363
|
mainFile: {
|
|
24638
|
-
name: SKILL_FILE_NAME,
|
|
25364
|
+
name: SKILL_FILE_NAME$1,
|
|
24639
25365
|
body,
|
|
24640
25366
|
frontmatter: { ...frontmatter }
|
|
24641
25367
|
},
|
|
@@ -24670,13 +25396,13 @@ var RulesyncSkill = class RulesyncSkill extends AiDir {
|
|
|
24670
25396
|
}
|
|
24671
25397
|
static async fromDir({ outputRoot = process.cwd(), relativeDirPath = RULESYNC_SKILLS_RELATIVE_DIR_PATH, dirName, global = false }) {
|
|
24672
25398
|
const skillDirPath = join(outputRoot, relativeDirPath, dirName);
|
|
24673
|
-
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME);
|
|
24674
|
-
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME} not found in ${skillDirPath}`);
|
|
25399
|
+
const skillFilePath = join(skillDirPath, SKILL_FILE_NAME$1);
|
|
25400
|
+
if (!await fileExists(skillFilePath)) throw new Error(`${SKILL_FILE_NAME$1} not found in ${skillDirPath}`);
|
|
24675
25401
|
const { frontmatter, body: content, hasFrontmatter } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
24676
25402
|
if (!hasFrontmatter) throw new Error(`Missing frontmatter in ${skillFilePath}. Rulesync files must begin with a YAML frontmatter block delimited by '---'.`);
|
|
24677
25403
|
const result = RulesyncSkillFrontmatterSchema.safeParse(frontmatter);
|
|
24678
25404
|
if (!result.success) throw new Error(`Invalid frontmatter in ${skillFilePath}: ${formatError(result.error)}`);
|
|
24679
|
-
const otherFiles = await this.collectOtherFiles(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME);
|
|
25405
|
+
const otherFiles = await this.collectOtherFiles(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
24680
25406
|
return new RulesyncSkill({
|
|
24681
25407
|
outputRoot,
|
|
24682
25408
|
relativeDirPath,
|
|
@@ -24716,7 +25442,7 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24716
25442
|
relativeDirPath,
|
|
24717
25443
|
dirName,
|
|
24718
25444
|
mainFile: {
|
|
24719
|
-
name: SKILL_FILE_NAME,
|
|
25445
|
+
name: SKILL_FILE_NAME$1,
|
|
24720
25446
|
body,
|
|
24721
25447
|
frontmatter: { ...frontmatter }
|
|
24722
25448
|
},
|
|
@@ -24743,7 +25469,7 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24743
25469
|
validate() {
|
|
24744
25470
|
if (!this.mainFile) return {
|
|
24745
25471
|
success: false,
|
|
24746
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25472
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
24747
25473
|
};
|
|
24748
25474
|
const result = RovodevSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
24749
25475
|
if (!result.success) return {
|
|
@@ -24819,10 +25545,10 @@ var RovodevSkill = class RovodevSkill extends ToolSkill {
|
|
|
24819
25545
|
const result = RovodevSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
24820
25546
|
if (!result.success) {
|
|
24821
25547
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
24822
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25548
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
24823
25549
|
}
|
|
24824
25550
|
if (result.data.name !== loaded.dirName) {
|
|
24825
|
-
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
25551
|
+
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
24826
25552
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
24827
25553
|
}
|
|
24828
25554
|
return new RovodevSkill({
|
|
@@ -24987,7 +25713,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
24987
25713
|
relativeDirPath,
|
|
24988
25714
|
dirName,
|
|
24989
25715
|
mainFile: {
|
|
24990
|
-
name: SKILL_FILE_NAME,
|
|
25716
|
+
name: SKILL_FILE_NAME$1,
|
|
24991
25717
|
body,
|
|
24992
25718
|
frontmatter: { ...frontmatter }
|
|
24993
25719
|
},
|
|
@@ -25011,7 +25737,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
25011
25737
|
validate() {
|
|
25012
25738
|
if (!this.mainFile) return {
|
|
25013
25739
|
success: false,
|
|
25014
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25740
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25015
25741
|
};
|
|
25016
25742
|
const result = AgentsSkillsSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25017
25743
|
if (!result.success) return {
|
|
@@ -25083,7 +25809,7 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
25083
25809
|
const result = AgentsSkillsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25084
25810
|
if (!result.success) {
|
|
25085
25811
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25086
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25812
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25087
25813
|
}
|
|
25088
25814
|
return new this({
|
|
25089
25815
|
outputRoot: loaded.outputRoot,
|
|
@@ -25140,7 +25866,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25140
25866
|
relativeDirPath,
|
|
25141
25867
|
dirName,
|
|
25142
25868
|
mainFile: {
|
|
25143
|
-
name: SKILL_FILE_NAME,
|
|
25869
|
+
name: SKILL_FILE_NAME$1,
|
|
25144
25870
|
body,
|
|
25145
25871
|
frontmatter: { ...frontmatter }
|
|
25146
25872
|
},
|
|
@@ -25165,7 +25891,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25165
25891
|
validate() {
|
|
25166
25892
|
if (!this.mainFile) return {
|
|
25167
25893
|
success: false,
|
|
25168
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
25894
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25169
25895
|
};
|
|
25170
25896
|
const result = AiassistantSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25171
25897
|
if (!result.success) return {
|
|
@@ -25225,7 +25951,7 @@ var AiassistantSkill = class AiassistantSkill extends ToolSkill {
|
|
|
25225
25951
|
const result = AiassistantSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25226
25952
|
if (!result.success) {
|
|
25227
25953
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25228
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
25954
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25229
25955
|
}
|
|
25230
25956
|
return new AiassistantSkill({
|
|
25231
25957
|
outputRoot: loaded.outputRoot,
|
|
@@ -25276,7 +26002,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25276
26002
|
relativeDirPath,
|
|
25277
26003
|
dirName,
|
|
25278
26004
|
mainFile: {
|
|
25279
|
-
name: SKILL_FILE_NAME,
|
|
26005
|
+
name: SKILL_FILE_NAME$1,
|
|
25280
26006
|
body,
|
|
25281
26007
|
frontmatter: { ...frontmatter }
|
|
25282
26008
|
},
|
|
@@ -25300,7 +26026,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25300
26026
|
validate() {
|
|
25301
26027
|
if (!this.mainFile) return {
|
|
25302
26028
|
success: false,
|
|
25303
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26029
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25304
26030
|
};
|
|
25305
26031
|
const result = AmpSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25306
26032
|
if (!result.success) return {
|
|
@@ -25360,7 +26086,7 @@ var AmpSkill = class AmpSkill extends ToolSkill {
|
|
|
25360
26086
|
const result = AmpSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25361
26087
|
if (!result.success) {
|
|
25362
26088
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25363
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26089
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25364
26090
|
}
|
|
25365
26091
|
return new AmpSkill({
|
|
25366
26092
|
outputRoot: loaded.outputRoot,
|
|
@@ -25416,7 +26142,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25416
26142
|
relativeDirPath,
|
|
25417
26143
|
dirName,
|
|
25418
26144
|
mainFile: {
|
|
25419
|
-
name: SKILL_FILE_NAME,
|
|
26145
|
+
name: SKILL_FILE_NAME$1,
|
|
25420
26146
|
body,
|
|
25421
26147
|
frontmatter: { ...frontmatter }
|
|
25422
26148
|
},
|
|
@@ -25449,7 +26175,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25449
26175
|
validate() {
|
|
25450
26176
|
if (this.mainFile === void 0) return {
|
|
25451
26177
|
success: false,
|
|
25452
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26178
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25453
26179
|
};
|
|
25454
26180
|
const result = AntigravitySkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25455
26181
|
if (!result.success) return {
|
|
@@ -25509,7 +26235,7 @@ var AntigravitySharedSkill = class extends ToolSkill {
|
|
|
25509
26235
|
const result = AntigravitySkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25510
26236
|
if (!result.success) {
|
|
25511
26237
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25512
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26238
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25513
26239
|
}
|
|
25514
26240
|
return new this({
|
|
25515
26241
|
outputRoot: loaded.outputRoot,
|
|
@@ -25593,7 +26319,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25593
26319
|
relativeDirPath,
|
|
25594
26320
|
dirName,
|
|
25595
26321
|
mainFile: {
|
|
25596
|
-
name: SKILL_FILE_NAME,
|
|
26322
|
+
name: SKILL_FILE_NAME$1,
|
|
25597
26323
|
body,
|
|
25598
26324
|
frontmatter: { ...frontmatter }
|
|
25599
26325
|
},
|
|
@@ -25620,7 +26346,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25620
26346
|
validate() {
|
|
25621
26347
|
if (this.mainFile === void 0) return {
|
|
25622
26348
|
success: false,
|
|
25623
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26349
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25624
26350
|
};
|
|
25625
26351
|
const result = AugmentcodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25626
26352
|
if (!result.success) return {
|
|
@@ -25680,7 +26406,7 @@ var AugmentcodeSkill = class AugmentcodeSkill extends ToolSkill {
|
|
|
25680
26406
|
const result = AugmentcodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25681
26407
|
if (!result.success) {
|
|
25682
26408
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25683
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26409
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25684
26410
|
}
|
|
25685
26411
|
return new AugmentcodeSkill({
|
|
25686
26412
|
outputRoot: loaded.outputRoot,
|
|
@@ -25821,7 +26547,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25821
26547
|
relativeDirPath,
|
|
25822
26548
|
dirName,
|
|
25823
26549
|
mainFile: {
|
|
25824
|
-
name: SKILL_FILE_NAME,
|
|
26550
|
+
name: SKILL_FILE_NAME$1,
|
|
25825
26551
|
body,
|
|
25826
26552
|
frontmatter: { ...frontmatter }
|
|
25827
26553
|
},
|
|
@@ -25848,7 +26574,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25848
26574
|
validate() {
|
|
25849
26575
|
if (this.mainFile === void 0) return {
|
|
25850
26576
|
success: false,
|
|
25851
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26577
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
25852
26578
|
};
|
|
25853
26579
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
25854
26580
|
if (!result.success) return {
|
|
@@ -25936,7 +26662,7 @@ var ClaudecodeSkill = class ClaudecodeSkill extends ToolSkill {
|
|
|
25936
26662
|
const result = ClaudecodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
25937
26663
|
if (!result.success) {
|
|
25938
26664
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
25939
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26665
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
25940
26666
|
}
|
|
25941
26667
|
return new ClaudecodeSkill({
|
|
25942
26668
|
outputRoot: loaded.outputRoot,
|
|
@@ -25982,7 +26708,7 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
25982
26708
|
relativeDirPath,
|
|
25983
26709
|
dirName,
|
|
25984
26710
|
mainFile: {
|
|
25985
|
-
name: SKILL_FILE_NAME,
|
|
26711
|
+
name: SKILL_FILE_NAME$1,
|
|
25986
26712
|
body,
|
|
25987
26713
|
frontmatter: { ...frontmatter }
|
|
25988
26714
|
},
|
|
@@ -26006,7 +26732,7 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
26006
26732
|
validate() {
|
|
26007
26733
|
if (!this.mainFile) return {
|
|
26008
26734
|
success: false,
|
|
26009
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26735
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26010
26736
|
};
|
|
26011
26737
|
const result = ClineSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26012
26738
|
if (!result.success) return {
|
|
@@ -26070,10 +26796,10 @@ var ClineSkill = class ClineSkill extends ToolSkill {
|
|
|
26070
26796
|
const result = ClineSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26071
26797
|
if (!result.success) {
|
|
26072
26798
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26073
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
26799
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26074
26800
|
}
|
|
26075
26801
|
if (result.data.name !== loaded.dirName) {
|
|
26076
|
-
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
26802
|
+
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
26077
26803
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
26078
26804
|
}
|
|
26079
26805
|
return new ClineSkill({
|
|
@@ -26187,7 +26913,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26187
26913
|
relativeDirPath,
|
|
26188
26914
|
dirName,
|
|
26189
26915
|
mainFile: {
|
|
26190
|
-
name: SKILL_FILE_NAME,
|
|
26916
|
+
name: SKILL_FILE_NAME$1,
|
|
26191
26917
|
body,
|
|
26192
26918
|
frontmatter: { ...frontmatter }
|
|
26193
26919
|
},
|
|
@@ -26211,7 +26937,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26211
26937
|
validate() {
|
|
26212
26938
|
if (!this.mainFile) return {
|
|
26213
26939
|
success: false,
|
|
26214
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
26940
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26215
26941
|
};
|
|
26216
26942
|
const result = CodexCliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26217
26943
|
if (!result.success) return {
|
|
@@ -26289,7 +27015,7 @@ var CodexCliSkill = class CodexCliSkill extends ToolSkill {
|
|
|
26289
27015
|
const result = CodexCliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26290
27016
|
if (!result.success) {
|
|
26291
27017
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26292
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27018
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26293
27019
|
}
|
|
26294
27020
|
return new CodexCliSkill({
|
|
26295
27021
|
outputRoot: loaded.outputRoot,
|
|
@@ -26341,7 +27067,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26341
27067
|
relativeDirPath,
|
|
26342
27068
|
dirName,
|
|
26343
27069
|
mainFile: {
|
|
26344
|
-
name: SKILL_FILE_NAME,
|
|
27070
|
+
name: SKILL_FILE_NAME$1,
|
|
26345
27071
|
body,
|
|
26346
27072
|
frontmatter: { ...frontmatter }
|
|
26347
27073
|
},
|
|
@@ -26366,7 +27092,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26366
27092
|
validate() {
|
|
26367
27093
|
if (!this.mainFile) return {
|
|
26368
27094
|
success: false,
|
|
26369
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27095
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26370
27096
|
};
|
|
26371
27097
|
const result = CopilotSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26372
27098
|
if (!result.success) return {
|
|
@@ -26433,7 +27159,7 @@ var CopilotSkill = class CopilotSkill extends ToolSkill {
|
|
|
26433
27159
|
const result = CopilotSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26434
27160
|
if (!result.success) {
|
|
26435
27161
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26436
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27162
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26437
27163
|
}
|
|
26438
27164
|
return new CopilotSkill({
|
|
26439
27165
|
outputRoot: loaded.outputRoot,
|
|
@@ -26487,7 +27213,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26487
27213
|
relativeDirPath,
|
|
26488
27214
|
dirName,
|
|
26489
27215
|
mainFile: {
|
|
26490
|
-
name: SKILL_FILE_NAME,
|
|
27216
|
+
name: SKILL_FILE_NAME$1,
|
|
26491
27217
|
body,
|
|
26492
27218
|
frontmatter: { ...frontmatter }
|
|
26493
27219
|
},
|
|
@@ -26512,7 +27238,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26512
27238
|
validate() {
|
|
26513
27239
|
if (!this.mainFile) return {
|
|
26514
27240
|
success: false,
|
|
26515
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27241
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26516
27242
|
};
|
|
26517
27243
|
const result = CopilotcliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26518
27244
|
if (!result.success) return {
|
|
@@ -26581,7 +27307,7 @@ var CopilotcliSkill = class CopilotcliSkill extends ToolSkill {
|
|
|
26581
27307
|
const result = CopilotcliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26582
27308
|
if (!result.success) {
|
|
26583
27309
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26584
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27310
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26585
27311
|
}
|
|
26586
27312
|
return new CopilotcliSkill({
|
|
26587
27313
|
outputRoot: loaded.outputRoot,
|
|
@@ -26631,7 +27357,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26631
27357
|
relativeDirPath,
|
|
26632
27358
|
dirName,
|
|
26633
27359
|
mainFile: {
|
|
26634
|
-
name: SKILL_FILE_NAME,
|
|
27360
|
+
name: SKILL_FILE_NAME$1,
|
|
26635
27361
|
body,
|
|
26636
27362
|
frontmatter: { ...frontmatter }
|
|
26637
27363
|
},
|
|
@@ -26655,7 +27381,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26655
27381
|
validate() {
|
|
26656
27382
|
if (!this.mainFile) return {
|
|
26657
27383
|
success: false,
|
|
26658
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27384
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26659
27385
|
};
|
|
26660
27386
|
const result = CursorSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26661
27387
|
if (!result.success) return {
|
|
@@ -26729,7 +27455,7 @@ var CursorSkill = class CursorSkill extends ToolSkill {
|
|
|
26729
27455
|
const result = CursorSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26730
27456
|
if (!result.success) {
|
|
26731
27457
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26732
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27458
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26733
27459
|
}
|
|
26734
27460
|
return new CursorSkill({
|
|
26735
27461
|
outputRoot: loaded.outputRoot,
|
|
@@ -26776,7 +27502,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26776
27502
|
relativeDirPath,
|
|
26777
27503
|
dirName,
|
|
26778
27504
|
mainFile: {
|
|
26779
|
-
name: SKILL_FILE_NAME,
|
|
27505
|
+
name: SKILL_FILE_NAME$1,
|
|
26780
27506
|
body,
|
|
26781
27507
|
frontmatter: { ...frontmatter }
|
|
26782
27508
|
},
|
|
@@ -26800,7 +27526,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26800
27526
|
validate() {
|
|
26801
27527
|
if (!this.mainFile) return {
|
|
26802
27528
|
success: false,
|
|
26803
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27529
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26804
27530
|
};
|
|
26805
27531
|
const result = DeepagentsSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26806
27532
|
if (!result.success) return {
|
|
@@ -26876,7 +27602,7 @@ var DeepagentsSkill = class DeepagentsSkill extends ToolSkill {
|
|
|
26876
27602
|
const result = DeepagentsSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
26877
27603
|
if (!result.success) {
|
|
26878
27604
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
26879
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27605
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
26880
27606
|
}
|
|
26881
27607
|
return new DeepagentsSkill({
|
|
26882
27608
|
outputRoot: loaded.outputRoot,
|
|
@@ -26927,7 +27653,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
26927
27653
|
relativeDirPath,
|
|
26928
27654
|
dirName,
|
|
26929
27655
|
mainFile: {
|
|
26930
|
-
name: SKILL_FILE_NAME,
|
|
27656
|
+
name: SKILL_FILE_NAME$1,
|
|
26931
27657
|
body,
|
|
26932
27658
|
frontmatter: { ...frontmatter }
|
|
26933
27659
|
},
|
|
@@ -26952,7 +27678,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
26952
27678
|
validate() {
|
|
26953
27679
|
if (!this.mainFile) return {
|
|
26954
27680
|
success: false,
|
|
26955
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27681
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
26956
27682
|
};
|
|
26957
27683
|
const result = DevinSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
26958
27684
|
if (!result.success) return {
|
|
@@ -27004,6 +27730,18 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
27004
27730
|
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
27005
27731
|
return targets.includes("*") || targets.includes("devin");
|
|
27006
27732
|
}
|
|
27733
|
+
/**
|
|
27734
|
+
* Commands are emitted into this same skills tree as `<slug>/SKILL.md`
|
|
27735
|
+
* (see `DevinCommand`), so a directory matching a current rulesync command
|
|
27736
|
+
* slug is owned by the commands feature: it must not be imported as a
|
|
27737
|
+
* skill nor deleted as an orphan skill.
|
|
27738
|
+
*/
|
|
27739
|
+
static async isDirOwned({ dirName, inputRoot }) {
|
|
27740
|
+
return !await rulesyncCommandSlugExists({
|
|
27741
|
+
inputRoot,
|
|
27742
|
+
dirName
|
|
27743
|
+
});
|
|
27744
|
+
}
|
|
27007
27745
|
static async fromDir(params) {
|
|
27008
27746
|
const loaded = await this.loadSkillDirContent({
|
|
27009
27747
|
...params,
|
|
@@ -27012,7 +27750,7 @@ var DevinSkill = class DevinSkill extends ToolSkill {
|
|
|
27012
27750
|
const result = DevinSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27013
27751
|
if (!result.success) {
|
|
27014
27752
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27015
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27753
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27016
27754
|
}
|
|
27017
27755
|
return new DevinSkill({
|
|
27018
27756
|
outputRoot: loaded.outputRoot,
|
|
@@ -27064,7 +27802,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27064
27802
|
relativeDirPath,
|
|
27065
27803
|
dirName,
|
|
27066
27804
|
mainFile: {
|
|
27067
|
-
name: SKILL_FILE_NAME,
|
|
27805
|
+
name: SKILL_FILE_NAME$1,
|
|
27068
27806
|
body,
|
|
27069
27807
|
frontmatter: { ...frontmatter }
|
|
27070
27808
|
},
|
|
@@ -27088,7 +27826,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27088
27826
|
validate() {
|
|
27089
27827
|
if (this.mainFile === void 0) return {
|
|
27090
27828
|
success: false,
|
|
27091
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27829
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27092
27830
|
};
|
|
27093
27831
|
const result = FactorydroidSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27094
27832
|
if (!result.success) return {
|
|
@@ -27163,7 +27901,7 @@ var FactorydroidSkill = class FactorydroidSkill extends ToolSkill {
|
|
|
27163
27901
|
const result = FactorydroidSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27164
27902
|
if (!result.success) {
|
|
27165
27903
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27166
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
27904
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27167
27905
|
}
|
|
27168
27906
|
return new FactorydroidSkill({
|
|
27169
27907
|
outputRoot: loaded.outputRoot,
|
|
@@ -27210,7 +27948,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27210
27948
|
relativeDirPath,
|
|
27211
27949
|
dirName,
|
|
27212
27950
|
mainFile: {
|
|
27213
|
-
name: SKILL_FILE_NAME,
|
|
27951
|
+
name: SKILL_FILE_NAME$1,
|
|
27214
27952
|
body,
|
|
27215
27953
|
frontmatter: { ...frontmatter }
|
|
27216
27954
|
},
|
|
@@ -27235,7 +27973,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27235
27973
|
validate() {
|
|
27236
27974
|
if (!this.mainFile) return {
|
|
27237
27975
|
success: false,
|
|
27238
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
27976
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27239
27977
|
};
|
|
27240
27978
|
const result = GooseSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27241
27979
|
if (!result.success) return {
|
|
@@ -27295,7 +28033,7 @@ var GooseSkill = class GooseSkill extends ToolSkill {
|
|
|
27295
28033
|
const result = GooseSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27296
28034
|
if (!result.success) {
|
|
27297
28035
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27298
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28036
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27299
28037
|
}
|
|
27300
28038
|
return new GooseSkill({
|
|
27301
28039
|
outputRoot: loaded.outputRoot,
|
|
@@ -27348,7 +28086,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27348
28086
|
relativeDirPath,
|
|
27349
28087
|
dirName,
|
|
27350
28088
|
mainFile: {
|
|
27351
|
-
name: SKILL_FILE_NAME,
|
|
28089
|
+
name: SKILL_FILE_NAME$1,
|
|
27352
28090
|
body,
|
|
27353
28091
|
frontmatter: { ...frontmatter }
|
|
27354
28092
|
},
|
|
@@ -27372,7 +28110,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27372
28110
|
validate() {
|
|
27373
28111
|
if (this.mainFile === void 0) return {
|
|
27374
28112
|
success: false,
|
|
27375
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28113
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27376
28114
|
};
|
|
27377
28115
|
const result = GrokcliSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27378
28116
|
if (!result.success) return {
|
|
@@ -27432,7 +28170,7 @@ var GrokcliSkill = class GrokcliSkill extends ToolSkill {
|
|
|
27432
28170
|
const result = GrokcliSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27433
28171
|
if (!result.success) {
|
|
27434
28172
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27435
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28173
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27436
28174
|
}
|
|
27437
28175
|
return new GrokcliSkill({
|
|
27438
28176
|
outputRoot: loaded.outputRoot,
|
|
@@ -27467,6 +28205,18 @@ var HermesagentSkill = class extends AgentsSkillsSkill {
|
|
|
27467
28205
|
static getSettablePaths() {
|
|
27468
28206
|
return { relativeDirPath: HERMESAGENT_SKILLS_DIR_PATH };
|
|
27469
28207
|
}
|
|
28208
|
+
/**
|
|
28209
|
+
* Commands are emitted into this same skills tree as `<slug>/SKILL.md`
|
|
28210
|
+
* (see `HermesagentCommand`), so a directory matching a current rulesync
|
|
28211
|
+
* command slug is owned by the commands feature: it must not be imported
|
|
28212
|
+
* as a skill nor deleted as an orphan skill.
|
|
28213
|
+
*/
|
|
28214
|
+
static async isDirOwned({ dirName, inputRoot }) {
|
|
28215
|
+
return !await rulesyncCommandSlugExists({
|
|
28216
|
+
inputRoot,
|
|
28217
|
+
dirName
|
|
28218
|
+
});
|
|
28219
|
+
}
|
|
27470
28220
|
constructor(params) {
|
|
27471
28221
|
super({
|
|
27472
28222
|
...params,
|
|
@@ -27491,7 +28241,7 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27491
28241
|
relativeDirPath,
|
|
27492
28242
|
dirName,
|
|
27493
28243
|
mainFile: {
|
|
27494
|
-
name: SKILL_FILE_NAME,
|
|
28244
|
+
name: SKILL_FILE_NAME$1,
|
|
27495
28245
|
body,
|
|
27496
28246
|
frontmatter: { ...frontmatter }
|
|
27497
28247
|
},
|
|
@@ -27515,7 +28265,7 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27515
28265
|
validate() {
|
|
27516
28266
|
if (!this.mainFile) return {
|
|
27517
28267
|
success: false,
|
|
27518
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28268
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27519
28269
|
};
|
|
27520
28270
|
const result = JunieSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27521
28271
|
if (!result.success) return {
|
|
@@ -27579,10 +28329,10 @@ var JunieSkill = class JunieSkill extends ToolSkill {
|
|
|
27579
28329
|
const result = JunieSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27580
28330
|
if (!result.success) {
|
|
27581
28331
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27582
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28332
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27583
28333
|
}
|
|
27584
28334
|
if (result.data.name !== loaded.dirName) {
|
|
27585
|
-
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
28335
|
+
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
27586
28336
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
27587
28337
|
}
|
|
27588
28338
|
return new JunieSkill({
|
|
@@ -27630,7 +28380,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27630
28380
|
relativeDirPath,
|
|
27631
28381
|
dirName,
|
|
27632
28382
|
mainFile: {
|
|
27633
|
-
name: SKILL_FILE_NAME,
|
|
28383
|
+
name: SKILL_FILE_NAME$1,
|
|
27634
28384
|
body,
|
|
27635
28385
|
frontmatter: { ...frontmatter }
|
|
27636
28386
|
},
|
|
@@ -27654,7 +28404,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27654
28404
|
validate() {
|
|
27655
28405
|
if (this.mainFile === void 0) return {
|
|
27656
28406
|
success: false,
|
|
27657
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28407
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27658
28408
|
};
|
|
27659
28409
|
const result = KiloSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27660
28410
|
if (!result.success) return {
|
|
@@ -27726,7 +28476,7 @@ var KiloSkill = class KiloSkill extends ToolSkill {
|
|
|
27726
28476
|
const result = KiloSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27727
28477
|
if (!result.success) {
|
|
27728
28478
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27729
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28479
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27730
28480
|
}
|
|
27731
28481
|
return new KiloSkill({
|
|
27732
28482
|
outputRoot: loaded.outputRoot,
|
|
@@ -27772,7 +28522,7 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27772
28522
|
relativeDirPath,
|
|
27773
28523
|
dirName,
|
|
27774
28524
|
mainFile: {
|
|
27775
|
-
name: SKILL_FILE_NAME,
|
|
28525
|
+
name: SKILL_FILE_NAME$1,
|
|
27776
28526
|
body,
|
|
27777
28527
|
frontmatter: { ...frontmatter }
|
|
27778
28528
|
},
|
|
@@ -27796,7 +28546,7 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27796
28546
|
validate() {
|
|
27797
28547
|
if (!this.mainFile) return {
|
|
27798
28548
|
success: false,
|
|
27799
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28549
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27800
28550
|
};
|
|
27801
28551
|
const result = KiroSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27802
28552
|
if (!result.success) return {
|
|
@@ -27860,10 +28610,10 @@ var KiroSkill = class KiroSkill extends ToolSkill {
|
|
|
27860
28610
|
const result = KiroSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
27861
28611
|
if (!result.success) {
|
|
27862
28612
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
27863
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28613
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
27864
28614
|
}
|
|
27865
28615
|
if (result.data.name !== loaded.dirName) {
|
|
27866
|
-
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
28616
|
+
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
27867
28617
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
27868
28618
|
}
|
|
27869
28619
|
return new KiroSkill({
|
|
@@ -27946,7 +28696,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
27946
28696
|
relativeDirPath,
|
|
27947
28697
|
dirName,
|
|
27948
28698
|
mainFile: {
|
|
27949
|
-
name: SKILL_FILE_NAME,
|
|
28699
|
+
name: SKILL_FILE_NAME$1,
|
|
27950
28700
|
body,
|
|
27951
28701
|
frontmatter: { ...frontmatter }
|
|
27952
28702
|
},
|
|
@@ -27973,7 +28723,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
27973
28723
|
validate() {
|
|
27974
28724
|
if (this.mainFile === void 0) return {
|
|
27975
28725
|
success: false,
|
|
27976
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28726
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
27977
28727
|
};
|
|
27978
28728
|
const result = OpenCodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
27979
28729
|
if (!result.success) return {
|
|
@@ -28052,7 +28802,7 @@ var OpenCodeSkill = class OpenCodeSkill extends ToolSkill {
|
|
|
28052
28802
|
const result = OpenCodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28053
28803
|
if (!result.success) {
|
|
28054
28804
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28055
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28805
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28056
28806
|
}
|
|
28057
28807
|
return new OpenCodeSkill({
|
|
28058
28808
|
outputRoot: loaded.outputRoot,
|
|
@@ -28113,7 +28863,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28113
28863
|
relativeDirPath: resolvedDirPath,
|
|
28114
28864
|
dirName,
|
|
28115
28865
|
mainFile: {
|
|
28116
|
-
name: SKILL_FILE_NAME,
|
|
28866
|
+
name: SKILL_FILE_NAME$1,
|
|
28117
28867
|
body,
|
|
28118
28868
|
frontmatter: { ...frontmatter }
|
|
28119
28869
|
},
|
|
@@ -28138,7 +28888,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28138
28888
|
validate() {
|
|
28139
28889
|
if (!this.mainFile) return {
|
|
28140
28890
|
success: false,
|
|
28141
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
28891
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28142
28892
|
};
|
|
28143
28893
|
const result = PiSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28144
28894
|
if (!result.success) return {
|
|
@@ -28213,7 +28963,7 @@ var PiSkill = class PiSkill extends ToolSkill {
|
|
|
28213
28963
|
const result = PiSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28214
28964
|
if (!result.success) {
|
|
28215
28965
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28216
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
28966
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28217
28967
|
}
|
|
28218
28968
|
return new PiSkill({
|
|
28219
28969
|
outputRoot: loaded.outputRoot,
|
|
@@ -28266,7 +29016,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28266
29016
|
relativeDirPath,
|
|
28267
29017
|
dirName,
|
|
28268
29018
|
mainFile: {
|
|
28269
|
-
name: SKILL_FILE_NAME,
|
|
29019
|
+
name: SKILL_FILE_NAME$1,
|
|
28270
29020
|
body,
|
|
28271
29021
|
frontmatter: { ...frontmatter }
|
|
28272
29022
|
},
|
|
@@ -28290,7 +29040,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28290
29040
|
validate() {
|
|
28291
29041
|
if (this.mainFile === void 0) return {
|
|
28292
29042
|
success: false,
|
|
28293
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29043
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28294
29044
|
};
|
|
28295
29045
|
const result = QwencodeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28296
29046
|
if (!result.success) return {
|
|
@@ -28370,7 +29120,7 @@ var QwencodeSkill = class QwencodeSkill extends ToolSkill {
|
|
|
28370
29120
|
const result = QwencodeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28371
29121
|
if (!result.success) {
|
|
28372
29122
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28373
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29123
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28374
29124
|
}
|
|
28375
29125
|
return new QwencodeSkill({
|
|
28376
29126
|
outputRoot: loaded.outputRoot,
|
|
@@ -28420,7 +29170,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28420
29170
|
relativeDirPath,
|
|
28421
29171
|
dirName,
|
|
28422
29172
|
mainFile: {
|
|
28423
|
-
name: SKILL_FILE_NAME,
|
|
29173
|
+
name: SKILL_FILE_NAME$1,
|
|
28424
29174
|
body,
|
|
28425
29175
|
frontmatter: { ...frontmatter }
|
|
28426
29176
|
},
|
|
@@ -28444,7 +29194,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28444
29194
|
validate() {
|
|
28445
29195
|
if (this.mainFile === void 0) return {
|
|
28446
29196
|
success: false,
|
|
28447
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29197
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28448
29198
|
};
|
|
28449
29199
|
const result = ReasonixSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28450
29200
|
if (!result.success) return {
|
|
@@ -28504,7 +29254,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28504
29254
|
const result = ReasonixSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28505
29255
|
if (!result.success) {
|
|
28506
29256
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28507
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29257
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28508
29258
|
}
|
|
28509
29259
|
return new ReasonixSkill({
|
|
28510
29260
|
outputRoot: loaded.outputRoot,
|
|
@@ -28527,7 +29277,7 @@ var ReasonixSkill = class ReasonixSkill extends ToolSkill {
|
|
|
28527
29277
|
* skills-feature ownership, matching the previous behavior for such dirs.
|
|
28528
29278
|
*/
|
|
28529
29279
|
static async isDirOwned({ outputRoot, relativeDirPath, dirName }) {
|
|
28530
|
-
const skillFilePath = join(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME);
|
|
29280
|
+
const skillFilePath = join(outputRoot, relativeDirPath, dirName, SKILL_FILE_NAME$1);
|
|
28531
29281
|
try {
|
|
28532
29282
|
const { frontmatter } = parseFrontmatter(await readFileContent(skillFilePath), skillFilePath);
|
|
28533
29283
|
return frontmatter["runAs"] !== REASONIX_SUBAGENT_RUN_AS;
|
|
@@ -28577,7 +29327,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28577
29327
|
relativeDirPath,
|
|
28578
29328
|
dirName,
|
|
28579
29329
|
mainFile: {
|
|
28580
|
-
name: SKILL_FILE_NAME,
|
|
29330
|
+
name: SKILL_FILE_NAME$1,
|
|
28581
29331
|
body,
|
|
28582
29332
|
frontmatter: { ...frontmatter }
|
|
28583
29333
|
},
|
|
@@ -28601,7 +29351,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28601
29351
|
validate() {
|
|
28602
29352
|
if (!this.mainFile) return {
|
|
28603
29353
|
success: false,
|
|
28604
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29354
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28605
29355
|
};
|
|
28606
29356
|
const result = ReplitSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28607
29357
|
if (!result.success) return {
|
|
@@ -28669,7 +29419,7 @@ var ReplitSkill = class ReplitSkill extends ToolSkill {
|
|
|
28669
29419
|
const result = ReplitSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28670
29420
|
if (!result.success) {
|
|
28671
29421
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28672
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29422
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28673
29423
|
}
|
|
28674
29424
|
return new ReplitSkill({
|
|
28675
29425
|
outputRoot: loaded.outputRoot,
|
|
@@ -28716,7 +29466,7 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28716
29466
|
relativeDirPath,
|
|
28717
29467
|
dirName,
|
|
28718
29468
|
mainFile: {
|
|
28719
|
-
name: SKILL_FILE_NAME,
|
|
29469
|
+
name: SKILL_FILE_NAME$1,
|
|
28720
29470
|
body,
|
|
28721
29471
|
frontmatter: { ...frontmatter }
|
|
28722
29472
|
},
|
|
@@ -28740,7 +29490,7 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28740
29490
|
validate() {
|
|
28741
29491
|
if (!this.mainFile) return {
|
|
28742
29492
|
success: false,
|
|
28743
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29493
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
28744
29494
|
};
|
|
28745
29495
|
const result = RooSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
28746
29496
|
if (!result.success) return {
|
|
@@ -28804,10 +29554,10 @@ var RooSkill = class RooSkill extends ToolSkill {
|
|
|
28804
29554
|
const result = RooSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
28805
29555
|
if (!result.success) {
|
|
28806
29556
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
28807
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29557
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
28808
29558
|
}
|
|
28809
29559
|
if (result.data.name !== loaded.dirName) {
|
|
28810
|
-
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME);
|
|
29560
|
+
const skillFilePath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName, SKILL_FILE_NAME$1);
|
|
28811
29561
|
throw new Error(`Frontmatter name (${result.data.name}) must match directory name (${loaded.dirName}) in ${skillFilePath}`);
|
|
28812
29562
|
}
|
|
28813
29563
|
return new RooSkill({
|
|
@@ -29024,7 +29774,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29024
29774
|
relativeDirPath,
|
|
29025
29775
|
dirName,
|
|
29026
29776
|
mainFile: {
|
|
29027
|
-
name: SKILL_FILE_NAME,
|
|
29777
|
+
name: SKILL_FILE_NAME$1,
|
|
29028
29778
|
body,
|
|
29029
29779
|
frontmatter: { ...frontmatter }
|
|
29030
29780
|
},
|
|
@@ -29051,7 +29801,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29051
29801
|
validate() {
|
|
29052
29802
|
if (!this.mainFile) return {
|
|
29053
29803
|
success: false,
|
|
29054
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29804
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29055
29805
|
};
|
|
29056
29806
|
const result = VibeSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29057
29807
|
if (!result.success) return {
|
|
@@ -29115,7 +29865,7 @@ var VibeSkill = class VibeSkill extends ToolSkill {
|
|
|
29115
29865
|
const result = VibeSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29116
29866
|
if (!result.success) {
|
|
29117
29867
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29118
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
29868
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29119
29869
|
}
|
|
29120
29870
|
return new VibeSkill({
|
|
29121
29871
|
outputRoot: loaded.outputRoot,
|
|
@@ -29171,7 +29921,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29171
29921
|
relativeDirPath,
|
|
29172
29922
|
dirName,
|
|
29173
29923
|
mainFile: {
|
|
29174
|
-
name: SKILL_FILE_NAME,
|
|
29924
|
+
name: SKILL_FILE_NAME$1,
|
|
29175
29925
|
body,
|
|
29176
29926
|
frontmatter: { ...frontmatter }
|
|
29177
29927
|
},
|
|
@@ -29195,7 +29945,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29195
29945
|
validate() {
|
|
29196
29946
|
if (this.mainFile === void 0) return {
|
|
29197
29947
|
success: false,
|
|
29198
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
29948
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29199
29949
|
};
|
|
29200
29950
|
const result = WarpSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29201
29951
|
if (!result.success) return {
|
|
@@ -29255,7 +30005,7 @@ var WarpSkill = class WarpSkill extends ToolSkill {
|
|
|
29255
30005
|
const result = WarpSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29256
30006
|
if (!result.success) {
|
|
29257
30007
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29258
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
30008
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29259
30009
|
}
|
|
29260
30010
|
return new WarpSkill({
|
|
29261
30011
|
outputRoot: loaded.outputRoot,
|
|
@@ -29303,7 +30053,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29303
30053
|
relativeDirPath,
|
|
29304
30054
|
dirName,
|
|
29305
30055
|
mainFile: {
|
|
29306
|
-
name: SKILL_FILE_NAME,
|
|
30056
|
+
name: SKILL_FILE_NAME$1,
|
|
29307
30057
|
body,
|
|
29308
30058
|
frontmatter: { ...frontmatter }
|
|
29309
30059
|
},
|
|
@@ -29327,7 +30077,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29327
30077
|
validate() {
|
|
29328
30078
|
if (!this.mainFile) return {
|
|
29329
30079
|
success: false,
|
|
29330
|
-
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME} file does not exist`)
|
|
30080
|
+
error: /* @__PURE__ */ new Error(`${this.getDirPath()}: ${SKILL_FILE_NAME$1} file does not exist`)
|
|
29331
30081
|
};
|
|
29332
30082
|
const result = ZedSkillFrontmatterSchema.safeParse(this.mainFile.frontmatter);
|
|
29333
30083
|
if (!result.success) return {
|
|
@@ -29396,7 +30146,7 @@ var ZedSkill = class ZedSkill extends ToolSkill {
|
|
|
29396
30146
|
const result = ZedSkillFrontmatterSchema.safeParse(loaded.frontmatter);
|
|
29397
30147
|
if (!result.success) {
|
|
29398
30148
|
const skillDirPath = join(loaded.outputRoot, loaded.relativeDirPath, loaded.dirName);
|
|
29399
|
-
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME)}: ${formatError(result.error)}`);
|
|
30149
|
+
throw new Error(`Invalid frontmatter in ${join(skillDirPath, SKILL_FILE_NAME$1)}: ${formatError(result.error)}`);
|
|
29400
30150
|
}
|
|
29401
30151
|
return new ZedSkill({
|
|
29402
30152
|
outputRoot: loaded.outputRoot,
|
|
@@ -29836,7 +30586,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29836
30586
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29837
30587
|
outputRoot: this.outputRoot,
|
|
29838
30588
|
relativeDirPath: root,
|
|
29839
|
-
dirName
|
|
30589
|
+
dirName,
|
|
30590
|
+
inputRoot: this.inputRoot
|
|
29840
30591
|
})) continue;
|
|
29841
30592
|
seenDirNames.add(dirName);
|
|
29842
30593
|
loadEntries.push({
|
|
@@ -29867,7 +30618,8 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
29867
30618
|
if (factory.class.isDirOwned && !await factory.class.isDirOwned({
|
|
29868
30619
|
outputRoot: this.outputRoot,
|
|
29869
30620
|
relativeDirPath: root,
|
|
29870
|
-
dirName
|
|
30621
|
+
dirName,
|
|
30622
|
+
inputRoot: this.inputRoot
|
|
29871
30623
|
})) continue;
|
|
29872
30624
|
const toolSkill = factory.class.forDeletion({
|
|
29873
30625
|
outputRoot: this.outputRoot,
|
|
@@ -33268,7 +34020,7 @@ var ReasonixSubagent = class ReasonixSubagent extends ToolSubagent {
|
|
|
33268
34020
|
frontmatter: reasonixFrontmatter,
|
|
33269
34021
|
body,
|
|
33270
34022
|
relativeDirPath: paths.relativeDirPath,
|
|
33271
|
-
relativeFilePath: join(subagentName, SKILL_FILE_NAME),
|
|
34023
|
+
relativeFilePath: join(subagentName, SKILL_FILE_NAME$1),
|
|
33272
34024
|
fileContent,
|
|
33273
34025
|
validate,
|
|
33274
34026
|
global
|
|
@@ -34274,6 +35026,7 @@ const RulesyncRuleFrontmatterSchema = z.object({
|
|
|
34274
35026
|
name: z.optional(z.string()),
|
|
34275
35027
|
description: z.optional(z.string())
|
|
34276
35028
|
})),
|
|
35029
|
+
pi: z.optional(z.looseObject({ systemPrompt: z.optional(z.enum(["append"])) })),
|
|
34277
35030
|
takt: z.optional(z.looseObject({
|
|
34278
35031
|
name: z.optional(z.string()),
|
|
34279
35032
|
extends: z.optional(z.string()),
|
|
@@ -34437,6 +35190,16 @@ var ToolRule = class extends ToolFile {
|
|
|
34437
35190
|
isRoot() {
|
|
34438
35191
|
return this.root;
|
|
34439
35192
|
}
|
|
35193
|
+
/**
|
|
35194
|
+
* Whether this rule must be left out of the root rule's reference/MCP
|
|
35195
|
+
* instruction listings even though it is a non-root survivor. Used by files
|
|
35196
|
+
* the tool loads through its own mechanism (e.g. Pi's `APPEND_SYSTEM.md`,
|
|
35197
|
+
* which Pi appends to the system prompt itself — referencing it from
|
|
35198
|
+
* `AGENTS.md` would double-load the content).
|
|
35199
|
+
*/
|
|
35200
|
+
isExcludedFromRootReferences() {
|
|
35201
|
+
return false;
|
|
35202
|
+
}
|
|
34440
35203
|
getDescription() {
|
|
34441
35204
|
return this.description;
|
|
34442
35205
|
}
|
|
@@ -36783,6 +37546,15 @@ var FactorydroidRule = class FactorydroidRule extends ToolRule {
|
|
|
36783
37546
|
* is `undefined`). This mirrors the grokcli, warp, and deepagents targets.
|
|
36784
37547
|
*
|
|
36785
37548
|
* Goose uses plain markdown files (.goosehints) without frontmatter.
|
|
37549
|
+
*
|
|
37550
|
+
* Global scope emits only `~/.config/goose/.goosehints`. Goose v1.41.0 (PR
|
|
37551
|
+
* block/goose#9736) additionally loads the vendor-neutral
|
|
37552
|
+
* `~/.agents/AGENTS.md` alongside the config-dir hints, but rulesync
|
|
37553
|
+
* deliberately does not emit that shared path from the goose target: the
|
|
37554
|
+
* config-dir hints remain fully loaded (no capability loss), and the
|
|
37555
|
+
* cross-tool `~/.agents/AGENTS.md` is already written by targets that own it
|
|
37556
|
+
* (e.g. cline in global mode) — a second writer would need cross-target
|
|
37557
|
+
* shared-file coordination for zero gain (decision recorded in issue #2207).
|
|
36786
37558
|
*/
|
|
36787
37559
|
var GooseRule = class GooseRule extends ToolRule {
|
|
36788
37560
|
static getSettablePaths({ global } = {}) {
|
|
@@ -36984,14 +37756,21 @@ var HermesagentRule = class HermesagentRule extends ToolRule {
|
|
|
36984
37756
|
/**
|
|
36985
37757
|
* Rule generator for JetBrains Junie AI coding agent
|
|
36986
37758
|
*
|
|
36987
|
-
* Generates `.junie/AGENTS.md` files based on rulesync rule content.
|
|
36988
|
-
*
|
|
36989
|
-
*
|
|
36990
|
-
*
|
|
36991
|
-
*
|
|
36992
|
-
*
|
|
36993
|
-
*
|
|
36994
|
-
*
|
|
37759
|
+
* Generates `.junie/AGENTS.md` files based on rulesync rule content. Junie CLI
|
|
37760
|
+
* resolves project guidelines **first-match-wins**: `.junie/AGENTS.md` → root
|
|
37761
|
+
* `AGENTS.md` → legacy `.junie/guidelines.md` / `.junie/guidelines/`. Only the
|
|
37762
|
+
* first match is loaded, it documents no `@`-reference or file-inclusion
|
|
37763
|
+
* mechanism, and no `.junie/memories/` read path exists — so non-root rules
|
|
37764
|
+
* are folded into the single root `.junie/AGENTS.md` by the RulesProcessor
|
|
37765
|
+
* (`nonRoot` is `undefined`, mirroring the grokcli / warp / deepagents
|
|
37766
|
+
* targets; decision recorded in issue #2211). The legacy
|
|
37767
|
+
* `.junie/guidelines.md` is still accepted as an import fallback, but
|
|
37768
|
+
* generation always targets `.junie/AGENTS.md`. Junie uses plain markdown
|
|
37769
|
+
* without frontmatter requirements.
|
|
37770
|
+
*
|
|
37771
|
+
* Global (user) scope writes a single `~/.junie/AGENTS.md` file. Junie merges
|
|
37772
|
+
* these user-scope guidelines with the project guidelines (both are included
|
|
37773
|
+
* and marked clearly).
|
|
36995
37774
|
*
|
|
36996
37775
|
* @see https://junie.jetbrains.com/docs/junie-ide-plugin.html
|
|
36997
37776
|
* @see https://junie.jetbrains.com/docs/guidelines-and-memory.html
|
|
@@ -37010,15 +37789,12 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37010
37789
|
alternativeRoots: [{
|
|
37011
37790
|
relativeDirPath: buildToolPath(JUNIE_DIR, ".", excludeToolDir),
|
|
37012
37791
|
relativeFilePath: JUNIE_LEGACY_RULE_FILE_NAME
|
|
37013
|
-
}]
|
|
37014
|
-
nonRoot: { relativeDirPath: buildToolPath(JUNIE_DIR, "memories", excludeToolDir) }
|
|
37792
|
+
}]
|
|
37015
37793
|
};
|
|
37016
37794
|
}
|
|
37017
37795
|
/**
|
|
37018
37796
|
* Determines whether a given relative file path refers to a root guideline file.
|
|
37019
37797
|
* The preferred file is `AGENTS.md`; the legacy `guidelines.md` is still accepted.
|
|
37020
|
-
* Memory files live under `.junie/memories/` and are passed in as bare filenames
|
|
37021
|
-
* (e.g. `memo.md`), so a top-level `AGENTS.md`/`guidelines.md` is the root entry.
|
|
37022
37798
|
*/
|
|
37023
37799
|
static isRootRelativeFilePath(relativeFilePath) {
|
|
37024
37800
|
return relativeFilePath === "AGENTS.md" || relativeFilePath === "guidelines.md";
|
|
@@ -37037,10 +37813,7 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37037
37813
|
root: true
|
|
37038
37814
|
});
|
|
37039
37815
|
}
|
|
37040
|
-
const
|
|
37041
|
-
const settablePaths = this.getSettablePaths();
|
|
37042
|
-
if (!settablePaths.nonRoot) throw new Error("JunieRule project settable paths must include a nonRoot path");
|
|
37043
|
-
const relativeDirPath = isRoot ? settablePaths.root.relativeDirPath : settablePaths.nonRoot.relativeDirPath;
|
|
37816
|
+
const relativeDirPath = this.getSettablePaths().root.relativeDirPath;
|
|
37044
37817
|
const fileContent = await readFileContent(join(outputRoot, join(relativeDirPath, relativeFilePath)));
|
|
37045
37818
|
return new JunieRule({
|
|
37046
37819
|
outputRoot,
|
|
@@ -37048,7 +37821,7 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37048
37821
|
relativeFilePath,
|
|
37049
37822
|
fileContent,
|
|
37050
37823
|
validate,
|
|
37051
|
-
root:
|
|
37824
|
+
root: JunieRule.isRootRelativeFilePath(relativeFilePath)
|
|
37052
37825
|
});
|
|
37053
37826
|
}
|
|
37054
37827
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
@@ -37063,13 +37836,15 @@ var JunieRule = class JunieRule extends ToolRule {
|
|
|
37063
37836
|
rootPath: paths.root
|
|
37064
37837
|
}));
|
|
37065
37838
|
}
|
|
37066
|
-
|
|
37839
|
+
const { root } = this.getSettablePaths();
|
|
37840
|
+
return new JunieRule({
|
|
37067
37841
|
outputRoot,
|
|
37068
|
-
|
|
37842
|
+
relativeDirPath: root.relativeDirPath,
|
|
37843
|
+
relativeFilePath: root.relativeFilePath,
|
|
37844
|
+
fileContent: rulesyncRule.getBody(),
|
|
37069
37845
|
validate,
|
|
37070
|
-
|
|
37071
|
-
|
|
37072
|
-
}));
|
|
37846
|
+
root: rulesyncRule.getFrontmatter().root ?? false
|
|
37847
|
+
});
|
|
37073
37848
|
}
|
|
37074
37849
|
toRulesyncRule() {
|
|
37075
37850
|
return this.toRulesyncRuleDefault();
|
|
@@ -37472,31 +38247,68 @@ var OpenCodeRule = class OpenCodeRule extends ToolRule {
|
|
|
37472
38247
|
* RulesProcessor (there is no separate non-root output location — `nonRoot` is
|
|
37473
38248
|
* `undefined`). This mirrors the codexcli, grokcli, warp, and deepagents targets.
|
|
37474
38249
|
*
|
|
37475
|
-
* Pi also loads two system-prompt instruction files
|
|
38250
|
+
* Pi also loads two system-prompt instruction files. `.pi/APPEND_SYSTEM.md`
|
|
38251
|
+
* (global `~/.pi/agent/APPEND_SYSTEM.md`) *appends* to the default system prompt,
|
|
38252
|
+
* and rulesync emits it from any rule that opts in via the `pi.systemPrompt:
|
|
38253
|
+
* append` frontmatter block: those bodies are routed here instead of being folded
|
|
38254
|
+
* into `AGENTS.md`, and multiple opted-in rules concatenate in source order.
|
|
37476
38255
|
* `.pi/SYSTEM.md` (global `~/.pi/agent/SYSTEM.md`) *replaces* the default system
|
|
37477
|
-
* prompt entirely
|
|
37478
|
-
*
|
|
37479
|
-
*
|
|
37480
|
-
* for marking a rule as "replace" vs "append" the system prompt, so these
|
|
37481
|
-
* surfaces are documented in docs/reference/file-formats.md and left to be
|
|
37482
|
-
* authored by hand rather than mapped to a speculative new frontmatter flag.
|
|
38256
|
+
* prompt entirely — which silently disables Pi's built-in tool instructions — so
|
|
38257
|
+
* rulesync deliberately never emits it and leaves it to be authored by hand.
|
|
38258
|
+
* See docs/reference/file-formats.md.
|
|
37483
38259
|
*/
|
|
37484
38260
|
var PiRule = class PiRule extends ToolRule {
|
|
37485
|
-
|
|
38261
|
+
appendSystemPrompt;
|
|
38262
|
+
constructor({ fileContent, root, appendSystemPrompt = false, ...rest }) {
|
|
37486
38263
|
super({
|
|
37487
38264
|
...rest,
|
|
37488
38265
|
fileContent,
|
|
37489
38266
|
root: root ?? false
|
|
37490
38267
|
});
|
|
38268
|
+
this.appendSystemPrompt = appendSystemPrompt;
|
|
37491
38269
|
}
|
|
37492
38270
|
static getSettablePaths({ global = false, excludeToolDir } = {}) {
|
|
37493
|
-
return {
|
|
37494
|
-
|
|
37495
|
-
|
|
37496
|
-
|
|
38271
|
+
return {
|
|
38272
|
+
root: {
|
|
38273
|
+
relativeDirPath: global ? buildToolPath(".pi", "agent", excludeToolDir) : ".",
|
|
38274
|
+
relativeFilePath: PI_RULE_FILE_NAME
|
|
38275
|
+
},
|
|
38276
|
+
appendSystemPrompt: {
|
|
38277
|
+
relativeDirPath: global ? buildToolPath(".pi", "agent", excludeToolDir) : ".pi",
|
|
38278
|
+
relativeFilePath: PI_APPEND_SYSTEM_FILE_NAME
|
|
38279
|
+
}
|
|
38280
|
+
};
|
|
37497
38281
|
}
|
|
37498
|
-
|
|
37499
|
-
|
|
38282
|
+
/**
|
|
38283
|
+
* Extra fixed files this tool manages beyond the root rule. The
|
|
38284
|
+
* RulesProcessor enumerates these for import and deletion so a stale
|
|
38285
|
+
* `APPEND_SYSTEM.md` is cleaned up once no rule opts in anymore.
|
|
38286
|
+
*/
|
|
38287
|
+
static getExtraFixedFiles({ global = false } = {}) {
|
|
38288
|
+
return [this.getSettablePaths({ global }).appendSystemPrompt];
|
|
38289
|
+
}
|
|
38290
|
+
/**
|
|
38291
|
+
* Pi appends `APPEND_SYSTEM.md` to the system prompt itself, so listing it in
|
|
38292
|
+
* the root rule's reference section (toon/explicit discovery modes) would
|
|
38293
|
+
* double-load the content.
|
|
38294
|
+
*/
|
|
38295
|
+
isExcludedFromRootReferences() {
|
|
38296
|
+
return this.appendSystemPrompt;
|
|
38297
|
+
}
|
|
38298
|
+
static async fromFile({ outputRoot = process.cwd(), relativeFilePath, validate = true, global = false }) {
|
|
38299
|
+
const { root, appendSystemPrompt } = this.getSettablePaths({ global });
|
|
38300
|
+
if (relativeFilePath === "APPEND_SYSTEM.md") {
|
|
38301
|
+
const fileContent = await readFileContent(join(outputRoot, join(appendSystemPrompt.relativeDirPath, appendSystemPrompt.relativeFilePath)));
|
|
38302
|
+
return new PiRule({
|
|
38303
|
+
outputRoot,
|
|
38304
|
+
relativeDirPath: appendSystemPrompt.relativeDirPath,
|
|
38305
|
+
relativeFilePath: appendSystemPrompt.relativeFilePath,
|
|
38306
|
+
fileContent,
|
|
38307
|
+
validate,
|
|
38308
|
+
root: false,
|
|
38309
|
+
appendSystemPrompt: true
|
|
38310
|
+
});
|
|
38311
|
+
}
|
|
37500
38312
|
const fileContent = await readFileContent(join(outputRoot, join(root.relativeDirPath, root.relativeFilePath)));
|
|
37501
38313
|
return new PiRule({
|
|
37502
38314
|
outputRoot,
|
|
@@ -37508,8 +38320,18 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37508
38320
|
});
|
|
37509
38321
|
}
|
|
37510
38322
|
static fromRulesyncRule({ outputRoot = process.cwd(), rulesyncRule, validate = true, global = false }) {
|
|
37511
|
-
const { root } = this.getSettablePaths({ global });
|
|
37512
|
-
const
|
|
38323
|
+
const { root, appendSystemPrompt } = this.getSettablePaths({ global });
|
|
38324
|
+
const frontmatter = rulesyncRule.getFrontmatter();
|
|
38325
|
+
if (!frontmatter.root && frontmatter.pi?.systemPrompt === "append") return new PiRule({
|
|
38326
|
+
outputRoot,
|
|
38327
|
+
relativeDirPath: appendSystemPrompt.relativeDirPath,
|
|
38328
|
+
relativeFilePath: appendSystemPrompt.relativeFilePath,
|
|
38329
|
+
fileContent: rulesyncRule.getBody(),
|
|
38330
|
+
validate,
|
|
38331
|
+
root: false,
|
|
38332
|
+
appendSystemPrompt: true
|
|
38333
|
+
});
|
|
38334
|
+
const isRoot = frontmatter.root ?? false;
|
|
37513
38335
|
return new PiRule({
|
|
37514
38336
|
outputRoot,
|
|
37515
38337
|
relativeDirPath: root.relativeDirPath,
|
|
@@ -37520,6 +38342,17 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37520
38342
|
});
|
|
37521
38343
|
}
|
|
37522
38344
|
toRulesyncRule() {
|
|
38345
|
+
if (this.appendSystemPrompt) return new RulesyncRule({
|
|
38346
|
+
outputRoot: process.cwd(),
|
|
38347
|
+
relativeDirPath: RULESYNC_RULES_RELATIVE_DIR_PATH,
|
|
38348
|
+
relativeFilePath: PI_APPEND_SYSTEM_FILE_NAME,
|
|
38349
|
+
frontmatter: {
|
|
38350
|
+
root: false,
|
|
38351
|
+
targets: ["pi"],
|
|
38352
|
+
pi: { systemPrompt: "append" }
|
|
38353
|
+
},
|
|
38354
|
+
body: this.getFileContent()
|
|
38355
|
+
});
|
|
37523
38356
|
return this.toRulesyncRuleDefault();
|
|
37524
38357
|
}
|
|
37525
38358
|
validate() {
|
|
@@ -37530,6 +38363,15 @@ var PiRule = class PiRule extends ToolRule {
|
|
|
37530
38363
|
}
|
|
37531
38364
|
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, relativeFilePath, global = false }) {
|
|
37532
38365
|
const { root } = this.getSettablePaths({ global });
|
|
38366
|
+
if (relativeFilePath === "APPEND_SYSTEM.md") return new PiRule({
|
|
38367
|
+
outputRoot,
|
|
38368
|
+
relativeDirPath,
|
|
38369
|
+
relativeFilePath,
|
|
38370
|
+
fileContent: "",
|
|
38371
|
+
validate: false,
|
|
38372
|
+
root: false,
|
|
38373
|
+
appendSystemPrompt: true
|
|
38374
|
+
});
|
|
37533
38375
|
const isRoot = relativeFilePath === "AGENTS.md" && (relativeDirPath === "." || relativeDirPath === root.relativeDirPath);
|
|
37534
38376
|
return new PiRule({
|
|
37535
38377
|
outputRoot,
|
|
@@ -38689,7 +39531,8 @@ const toolRuleFactories = /* @__PURE__ */ new Map([
|
|
|
38689
39531
|
meta: {
|
|
38690
39532
|
extension: "md",
|
|
38691
39533
|
supportsGlobal: true,
|
|
38692
|
-
ruleDiscoveryMode: "
|
|
39534
|
+
ruleDiscoveryMode: "auto",
|
|
39535
|
+
foldsNonRootIntoRoot: true
|
|
38693
39536
|
}
|
|
38694
39537
|
}],
|
|
38695
39538
|
["kilo", {
|
|
@@ -38955,7 +39798,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
38955
39798
|
*/
|
|
38956
39799
|
async buildMcpInstructionFiles({ toolRules, meta }) {
|
|
38957
39800
|
if (!meta.mcpInstructionsRegistrar || this.global) return [];
|
|
38958
|
-
const instructionPaths = toolRules.filter((rule) => !rule.isRoot()).map((rule) => toPosixPath(join(rule.getRelativeDirPath(), rule.getRelativeFilePath())));
|
|
39801
|
+
const instructionPaths = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences()).map((rule) => toPosixPath(join(rule.getRelativeDirPath(), rule.getRelativeFilePath())));
|
|
38959
39802
|
if (instructionPaths.length === 0) return [];
|
|
38960
39803
|
return [await meta.mcpInstructionsRegistrar.fromInstructions({
|
|
38961
39804
|
outputRoot: this.outputRoot,
|
|
@@ -38987,7 +39830,7 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
38987
39830
|
const toolRelativeDirPath = skillClass.getSettablePaths({ global: this.global }).relativeDirPath;
|
|
38988
39831
|
return this.skills.filter((skill) => skillClass.isTargetedByRulesyncSkill(skill)).map((skill) => {
|
|
38989
39832
|
const frontmatter = skill.getFrontmatter();
|
|
38990
|
-
const relativePath = join(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME);
|
|
39833
|
+
const relativePath = join(toolRelativeDirPath, skill.getDirName(), SKILL_FILE_NAME$1);
|
|
38991
39834
|
return {
|
|
38992
39835
|
name: frontmatter.name,
|
|
38993
39836
|
description: frontmatter.description,
|
|
@@ -39011,11 +39854,25 @@ var RulesProcessor = class extends FeatureProcessor {
|
|
|
39011
39854
|
*/
|
|
39012
39855
|
foldNonRootRulesIntoRootRule(toolRules) {
|
|
39013
39856
|
if (toolRules.length <= 1) return;
|
|
39014
|
-
const
|
|
39015
|
-
|
|
39016
|
-
|
|
39017
|
-
|
|
39018
|
-
|
|
39857
|
+
const groups = /* @__PURE__ */ new Map();
|
|
39858
|
+
for (const rule of toolRules) {
|
|
39859
|
+
const path = join(rule.getRelativeDirPath(), rule.getRelativeFilePath());
|
|
39860
|
+
const group = groups.get(path);
|
|
39861
|
+
if (group) group.push(rule);
|
|
39862
|
+
else groups.set(path, [rule]);
|
|
39863
|
+
}
|
|
39864
|
+
const survivors = /* @__PURE__ */ new Set();
|
|
39865
|
+
for (const group of groups.values()) {
|
|
39866
|
+
const target = group.find((rule) => rule.isRoot()) ?? group[0];
|
|
39867
|
+
if (!target) continue;
|
|
39868
|
+
const mergedContent = [target, ...group.filter((rule) => rule !== target)].map((rule) => rule.getFileContent().trim()).filter((content) => content.length > 0).join("\n\n");
|
|
39869
|
+
target.setFileContent(mergedContent);
|
|
39870
|
+
survivors.add(target);
|
|
39871
|
+
}
|
|
39872
|
+
for (let i = toolRules.length - 1; i >= 0; i--) {
|
|
39873
|
+
const rule = toolRules[i];
|
|
39874
|
+
if (rule && !survivors.has(rule)) toolRules.splice(i, 1);
|
|
39875
|
+
}
|
|
39019
39876
|
}
|
|
39020
39877
|
/**
|
|
39021
39878
|
* Handle localRoot rule generation based on tool target.
|
|
@@ -39225,6 +40082,27 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39225
40082
|
const mirrorPaths = await findFilesByGlobs(mirrorGlob);
|
|
39226
40083
|
return buildDeletionRulesFromPaths(mirrorPaths);
|
|
39227
40084
|
})();
|
|
40085
|
+
const extraFixedToolRules = await (async () => {
|
|
40086
|
+
const extraFiles = factory.class.getExtraFixedFiles?.({ global: this.global });
|
|
40087
|
+
if (!extraFiles || extraFiles.length === 0) return [];
|
|
40088
|
+
const filePaths = await findFilesByGlobs(extraFiles.map((file) => join(this.outputRoot, file.relativeDirPath, file.relativeFilePath)));
|
|
40089
|
+
if (filePaths.length === 0) return [];
|
|
40090
|
+
if (forDeletion) return buildDeletionRulesFromPaths(filePaths);
|
|
40091
|
+
return await Promise.all(filePaths.map((filePath) => {
|
|
40092
|
+
const relativeDirPath = resolveRelativeDirPath(filePath);
|
|
40093
|
+
checkPathTraversal({
|
|
40094
|
+
relativePath: relativeDirPath,
|
|
40095
|
+
intendedRootDir: this.outputRoot
|
|
40096
|
+
});
|
|
40097
|
+
return factory.class.fromFile({
|
|
40098
|
+
outputRoot: this.outputRoot,
|
|
40099
|
+
relativeDirPath,
|
|
40100
|
+
relativeFilePath: basename(filePath),
|
|
40101
|
+
global: this.global
|
|
40102
|
+
});
|
|
40103
|
+
}));
|
|
40104
|
+
})();
|
|
40105
|
+
this.logger.debug(`Found ${extraFixedToolRules.length} extra fixed tool rule files`);
|
|
39228
40106
|
const nonRootToolRules = await (async () => {
|
|
39229
40107
|
if (!settablePaths.nonRoot) return [];
|
|
39230
40108
|
const nonRootOutputRoot = join(this.outputRoot, settablePaths.nonRoot.relativeDirPath);
|
|
@@ -39260,6 +40138,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39260
40138
|
...rootToolRules,
|
|
39261
40139
|
...localRootToolRules,
|
|
39262
40140
|
...rootMirrorDeletionRules,
|
|
40141
|
+
...extraFixedToolRules,
|
|
39263
40142
|
...nonRootToolRules
|
|
39264
40143
|
];
|
|
39265
40144
|
} catch (error) {
|
|
@@ -39287,7 +40166,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39287
40166
|
return toolRuleFactories.get(result.data);
|
|
39288
40167
|
}
|
|
39289
40168
|
generateToonReferencesSection(toolRules) {
|
|
39290
|
-
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
40169
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences());
|
|
39291
40170
|
if (toolRulesWithoutRoot.length === 0) return "";
|
|
39292
40171
|
const lines = [];
|
|
39293
40172
|
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.");
|
|
@@ -39303,7 +40182,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39303
40182
|
return lines.join("\n") + "\n\n";
|
|
39304
40183
|
}
|
|
39305
40184
|
generateReferencesSection(toolRules) {
|
|
39306
|
-
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot());
|
|
40185
|
+
const toolRulesWithoutRoot = toolRules.filter((rule) => !rule.isRoot() && !rule.isExcludedFromRootReferences());
|
|
39307
40186
|
if (toolRulesWithoutRoot.length === 0) return "";
|
|
39308
40187
|
const lines = [];
|
|
39309
40188
|
lines.push("Please also reference the following rules as needed:");
|
|
@@ -39324,7 +40203,7 @@ As this project's AI coding tool, you must follow the additional conventions bel
|
|
|
39324
40203
|
*/
|
|
39325
40204
|
async function convertFromTool(params) {
|
|
39326
40205
|
const ctx = params;
|
|
39327
|
-
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount] = [
|
|
40206
|
+
const [rulesCount, ignoreCount, mcpCount, commandsCount, subagentsCount, skillsCount, hooksCount, permissionsCount, checksCount] = [
|
|
39328
40207
|
await runFeatureConvert(ctx, buildRulesStrategy(ctx)),
|
|
39329
40208
|
await runFeatureConvert(ctx, buildIgnoreStrategy(ctx)),
|
|
39330
40209
|
await runFeatureConvert(ctx, buildMcpStrategy(ctx)),
|
|
@@ -39332,7 +40211,8 @@ async function convertFromTool(params) {
|
|
|
39332
40211
|
await runFeatureConvert(ctx, buildSubagentsStrategy(ctx)),
|
|
39333
40212
|
await runFeatureConvert(ctx, buildSkillsStrategy(ctx)),
|
|
39334
40213
|
await runFeatureConvert(ctx, buildHooksStrategy(ctx)),
|
|
39335
|
-
await runFeatureConvert(ctx, buildPermissionsStrategy(ctx))
|
|
40214
|
+
await runFeatureConvert(ctx, buildPermissionsStrategy(ctx)),
|
|
40215
|
+
await runFeatureConvert(ctx, buildChecksStrategy(ctx))
|
|
39336
40216
|
];
|
|
39337
40217
|
return {
|
|
39338
40218
|
rulesCount,
|
|
@@ -39342,7 +40222,8 @@ async function convertFromTool(params) {
|
|
|
39342
40222
|
subagentsCount,
|
|
39343
40223
|
skillsCount,
|
|
39344
40224
|
hooksCount,
|
|
39345
|
-
permissionsCount
|
|
40225
|
+
permissionsCount,
|
|
40226
|
+
checksCount
|
|
39346
40227
|
};
|
|
39347
40228
|
}
|
|
39348
40229
|
async function runFeatureConvert(ctx, strategy) {
|
|
@@ -39575,6 +40456,27 @@ function buildPermissionsStrategy(ctx) {
|
|
|
39575
40456
|
write: (p, files) => p.writeAiFiles(files)
|
|
39576
40457
|
};
|
|
39577
40458
|
}
|
|
40459
|
+
function buildChecksStrategy(ctx) {
|
|
40460
|
+
const { config, logger } = ctx;
|
|
40461
|
+
const global = config.getGlobal();
|
|
40462
|
+
const outputRoot = getOutputRoot(config);
|
|
40463
|
+
return {
|
|
40464
|
+
feature: "checks",
|
|
40465
|
+
itemLabel: "check file(s)",
|
|
40466
|
+
allTargets: ChecksProcessor.getToolTargets({ global }),
|
|
40467
|
+
createProcessor: ({ toolTarget, dryRun }) => new ChecksProcessor({
|
|
40468
|
+
outputRoot,
|
|
40469
|
+
toolTarget,
|
|
40470
|
+
global,
|
|
40471
|
+
dryRun,
|
|
40472
|
+
logger
|
|
40473
|
+
}),
|
|
40474
|
+
loadSource: (p) => p.loadToolFiles(),
|
|
40475
|
+
toRulesync: (p, files) => p.convertToolFilesToRulesyncFiles(files),
|
|
40476
|
+
fromRulesync: (p, files) => p.convertRulesyncFilesToToolFiles(files),
|
|
40477
|
+
write: (p, files) => p.writeAiFiles(files)
|
|
40478
|
+
};
|
|
40479
|
+
}
|
|
39578
40480
|
//#endregion
|
|
39579
40481
|
//#region src/types/processor-registry.ts
|
|
39580
40482
|
const PROCESSOR_REGISTRY = [
|
|
@@ -39625,6 +40527,12 @@ const PROCESSOR_REGISTRY = [
|
|
|
39625
40527
|
processor: PermissionsProcessor,
|
|
39626
40528
|
schema: PermissionsProcessorToolTargetSchema,
|
|
39627
40529
|
factory: toolPermissionsFactories
|
|
40530
|
+
},
|
|
40531
|
+
{
|
|
40532
|
+
feature: "checks",
|
|
40533
|
+
processor: ChecksProcessor,
|
|
40534
|
+
schema: ChecksProcessorToolTargetSchema,
|
|
40535
|
+
factory: toolCheckFactories
|
|
39628
40536
|
}
|
|
39629
40537
|
];
|
|
39630
40538
|
const getProcessorRegistryEntry = (feature) => {
|
|
@@ -39974,6 +40882,7 @@ const GENERATION_STEP_GRAPH = [
|
|
|
39974
40882
|
id: "permissions",
|
|
39975
40883
|
...sharedWriteMeta("permissions")
|
|
39976
40884
|
},
|
|
40885
|
+
{ id: "checks" },
|
|
39977
40886
|
{
|
|
39978
40887
|
id: "rules",
|
|
39979
40888
|
...sharedWriteMeta("rules"),
|
|
@@ -40059,6 +40968,10 @@ async function generate(params) {
|
|
|
40059
40968
|
config,
|
|
40060
40969
|
logger
|
|
40061
40970
|
}),
|
|
40971
|
+
checks: () => generateChecksCore({
|
|
40972
|
+
config,
|
|
40973
|
+
logger
|
|
40974
|
+
}),
|
|
40062
40975
|
rules: () => generateRulesCore({
|
|
40063
40976
|
config,
|
|
40064
40977
|
logger,
|
|
@@ -40095,6 +41008,8 @@ async function generate(params) {
|
|
|
40095
41008
|
hooksPaths: get("hooks").paths,
|
|
40096
41009
|
permissionsCount: get("permissions").count,
|
|
40097
41010
|
permissionsPaths: get("permissions").paths,
|
|
41011
|
+
checksCount: get("checks").count,
|
|
41012
|
+
checksPaths: get("checks").paths,
|
|
40098
41013
|
skills: skillsResult.skills,
|
|
40099
41014
|
hasDiff
|
|
40100
41015
|
};
|
|
@@ -40463,6 +41378,44 @@ async function generatePermissionsCore(params) {
|
|
|
40463
41378
|
hasDiff
|
|
40464
41379
|
};
|
|
40465
41380
|
}
|
|
41381
|
+
async function generateChecksCore(params) {
|
|
41382
|
+
const { config, logger } = params;
|
|
41383
|
+
let totalCount = 0;
|
|
41384
|
+
const allPaths = [];
|
|
41385
|
+
let hasDiff = false;
|
|
41386
|
+
const supportedChecksTargets = ChecksProcessor.getToolTargets({ global: config.getGlobal() });
|
|
41387
|
+
const toolTargets = intersection(config.getTargets(), supportedChecksTargets);
|
|
41388
|
+
warnUnsupportedTargets({
|
|
41389
|
+
config,
|
|
41390
|
+
supportedTargets: supportedChecksTargets,
|
|
41391
|
+
featureName: "checks",
|
|
41392
|
+
logger
|
|
41393
|
+
});
|
|
41394
|
+
for (const toolTarget of toolTargets) for (const outputRoot of config.getOutputRoots(toolTarget)) {
|
|
41395
|
+
if (!config.getFeatures(toolTarget).includes("checks")) continue;
|
|
41396
|
+
const processor = new ChecksProcessor({
|
|
41397
|
+
outputRoot,
|
|
41398
|
+
inputRoot: config.getInputRoot(),
|
|
41399
|
+
toolTarget,
|
|
41400
|
+
global: config.getGlobal(),
|
|
41401
|
+
dryRun: config.isPreviewMode(),
|
|
41402
|
+
logger
|
|
41403
|
+
});
|
|
41404
|
+
const result = await processFeatureWithRulesyncFiles({
|
|
41405
|
+
config,
|
|
41406
|
+
processor,
|
|
41407
|
+
rulesyncFiles: await processor.loadRulesyncFiles()
|
|
41408
|
+
});
|
|
41409
|
+
totalCount += result.count;
|
|
41410
|
+
allPaths.push(...result.paths);
|
|
41411
|
+
if (result.hasDiff) hasDiff = true;
|
|
41412
|
+
}
|
|
41413
|
+
return {
|
|
41414
|
+
count: totalCount,
|
|
41415
|
+
paths: allPaths,
|
|
41416
|
+
hasDiff
|
|
41417
|
+
};
|
|
41418
|
+
}
|
|
40466
41419
|
//#endregion
|
|
40467
41420
|
//#region src/lib/import.ts
|
|
40468
41421
|
/**
|
|
@@ -40520,6 +41473,11 @@ async function importFromTool(params) {
|
|
|
40520
41473
|
config,
|
|
40521
41474
|
tool,
|
|
40522
41475
|
logger
|
|
41476
|
+
}),
|
|
41477
|
+
checksCount: await importChecksCore({
|
|
41478
|
+
config,
|
|
41479
|
+
tool,
|
|
41480
|
+
logger
|
|
40523
41481
|
})
|
|
40524
41482
|
};
|
|
40525
41483
|
}
|
|
@@ -40736,7 +41694,28 @@ async function importPermissionsCore(params) {
|
|
|
40736
41694
|
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} permissions file(s)`);
|
|
40737
41695
|
return writtenCount;
|
|
40738
41696
|
}
|
|
41697
|
+
async function importChecksCore(params) {
|
|
41698
|
+
const { config, tool, logger } = params;
|
|
41699
|
+
if (!config.getFeatures(tool).includes("checks")) return 0;
|
|
41700
|
+
const global = config.getGlobal();
|
|
41701
|
+
if (!ChecksProcessor.getToolTargets({ global }).includes(tool)) return 0;
|
|
41702
|
+
const checksProcessor = new ChecksProcessor({
|
|
41703
|
+
outputRoot: config.getOutputRoots()[0] ?? ".",
|
|
41704
|
+
toolTarget: tool,
|
|
41705
|
+
global,
|
|
41706
|
+
logger
|
|
41707
|
+
});
|
|
41708
|
+
const toolFiles = await checksProcessor.loadToolFiles();
|
|
41709
|
+
if (toolFiles.length === 0) {
|
|
41710
|
+
logger.warn(`No check files found for ${tool}. Skipping import.`);
|
|
41711
|
+
return 0;
|
|
41712
|
+
}
|
|
41713
|
+
const rulesyncFiles = await checksProcessor.convertToolFilesToRulesyncFiles(toolFiles);
|
|
41714
|
+
const { count: writtenCount } = await checksProcessor.writeAiFiles(rulesyncFiles);
|
|
41715
|
+
if (config.getVerbose() && writtenCount > 0) logger.success(`Created ${writtenCount} check files`);
|
|
41716
|
+
return writtenCount;
|
|
41717
|
+
}
|
|
40739
41718
|
//#endregion
|
|
40740
|
-
export {
|
|
41719
|
+
export { isSymlink as $, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as A, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as At, findControlCharacter as B, CommandsProcessor as C, RULESYNC_MCP_FILE_NAME as Ct, CLAUDECODE_DIR as D, RULESYNC_OVERVIEW_FILE_NAME as Dt, CODEXCLI_DIR as E, RULESYNC_MCP_SCHEMA_URL as Et, RulesyncCheck as F, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Ft, checkPathTraversal as G, JsonLogger as H, RulesyncCheckFrontmatterSchema as I, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as It, ensureDir as J, createTempDirectory as K, stringifyFrontmatter as L, formatError as Lt, RulesyncCommand as M, RULESYNC_RELATIVE_DIR_PATH as Mt, RulesyncCommandFrontmatterSchema as N, RULESYNC_RULES_RELATIVE_DIR_PATH as Nt, CLAUDECODE_LOCAL_RULE_FILE_NAME as O, RULESYNC_PERMISSIONS_FILE_NAME as Ot, ChecksProcessor as P, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Pt, getHomeDirectory as Q, loadYaml as R, ALL_FEATURES as Rt, RulesyncHooks as S, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as St, CODEXCLI_BASH_RULES_FILE_NAME as T, RULESYNC_MCP_RELATIVE_FILE_PATH as Tt, CLIError as U, ConsoleLogger as V, ErrorCodes as W, findFilesByGlobs as X, fileExists as Y, getFileSize as Z, McpProcessor as _, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as _t, convertFromTool as a, toPosixPath as at, RulesyncIgnore as b, RULESYNC_HOOKS_RELATIVE_FILE_PATH as bt, RulesyncRuleFrontmatterSchema as c, ALL_TOOL_TARGETS_WITH_WILDCARD as ct, RulesyncSubagentFrontmatterSchema as d, RULESYNC_AIIGNORE_FILE_NAME as dt, listDirectoryFiles as et, SkillsProcessor as f, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as ft, RulesyncPermissions as g, RULESYNC_CONFIG_SCHEMA_URL as gt, RulesyncSkillFrontmatterSchema as h, RULESYNC_CONFIG_RELATIVE_FILE_PATH as ht, getProcessorRegistryEntry as i, removeTempDirectory as it, CLAUDECODE_SKILLS_DIR_PATH as j, RULESYNC_PERMISSIONS_SCHEMA_URL as jt, CLAUDECODE_MEMORIES_DIR_NAME as k, RULESYNC_PERMISSIONS_JSONC_FILE_NAME as kt, SubagentsProcessor as l, ToolTargetSchema as lt, RulesyncSkill as m, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as mt, checkRulesyncDirExists as n, removeDirectory as nt, RulesProcessor as o, writeFileContent as ot, getLocalSkillDirNames as p, RULESYNC_CHECKS_RELATIVE_DIR_PATH as pt, directoryExists as q, generate as r, removeFile as rt, RulesyncRule as s, ALL_TOOL_TARGETS as st, importFromTool as t, readFileContent as tt, RulesyncSubagent as u, MAX_FILE_SIZE as ut, RulesyncMcp as v, RULESYNC_HOOKS_FILE_NAME as vt, SKILL_FILE_NAME$1 as w, RULESYNC_MCP_JSONC_FILE_NAME as wt, HooksProcessor as x, RULESYNC_IGNORE_RELATIVE_FILE_PATH as xt, IgnoreProcessor as y, RULESYNC_HOOKS_JSONC_FILE_NAME as yt, ConfigResolver as z, ALL_FEATURES_WITH_WILDCARD as zt };
|
|
40741
41720
|
|
|
40742
|
-
//# sourceMappingURL=import-
|
|
41721
|
+
//# sourceMappingURL=import-CMSHVMqU.js.map
|