rulesync 43.1.1 → 43.1.2
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 +1 -1
- package/dist/cli/index.cjs +4 -4
- package/dist/cli/index.js +4 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-BiQjbRR6.cjs → import-BTqYh7nP.cjs} +79 -40
- package/dist/{import-COu_2AUF.js → import-D2uYjAdc.js} +80 -41
- package/dist/{import-COu_2AUF.js.map → import-D2uYjAdc.js.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -15889,17 +15889,24 @@ function toolSkillSearchRoots(paths) {
|
|
|
15889
15889
|
return [paths.relativeDirPath, ...paths.alternativeSkillRoots ?? []];
|
|
15890
15890
|
}
|
|
15891
15891
|
/**
|
|
15892
|
-
*
|
|
15893
|
-
*
|
|
15894
|
-
*
|
|
15895
|
-
*
|
|
15896
|
-
*
|
|
15897
|
-
*
|
|
15898
|
-
*
|
|
15899
|
-
*
|
|
15900
|
-
*
|
|
15901
|
-
|
|
15902
|
-
|
|
15892
|
+
* Skill roots that every tool scanning them imports leniently (skip-and-warn
|
|
15893
|
+
* per skill) instead of failing fast, regardless of the tool's own
|
|
15894
|
+
* `lenientImport` flag.
|
|
15895
|
+
*
|
|
15896
|
+
* - The Agent Skills interoperability roots: project `.agents/skills/`, global
|
|
15897
|
+
* `~/.agents/skills/` (same relative path, home output root), and Amp's
|
|
15898
|
+
* global equivalent `~/.config/agents/skills/`. Foreign-authored —
|
|
15899
|
+
* potentially non-conformant — skills are the most likely to live here, so
|
|
15900
|
+
* they are imported leniently per the Agent Skills client-implementation
|
|
15901
|
+
* guide, while each tool keeps fail-fast behavior for its own native root.
|
|
15902
|
+
* https://agentskills.io/client-implementation/adding-skills-support
|
|
15903
|
+
* - Amp's read-only global discovery root `~/.config/amp/skills/`, which is not
|
|
15904
|
+
* an interop root but follows the same skip-and-warn rule.
|
|
15905
|
+
*
|
|
15906
|
+
* Other import-only roots (e.g. GitLab Duo's legacy skills root, Kimi Code's
|
|
15907
|
+
* shared root) are not listed here and stay fail-fast.
|
|
15908
|
+
*/
|
|
15909
|
+
const LENIENT_IMPORT_SKILL_ROOTS = /* @__PURE__ */ new Set([
|
|
15903
15910
|
toPosixPath(AGENTSMD_SKILLS_DIR_PATH),
|
|
15904
15911
|
toPosixPath(AMP_SKILLS_GLOBAL_DIR),
|
|
15905
15912
|
toPosixPath(AMP_SKILLS_NATIVE_GLOBAL_DIR)
|
|
@@ -15924,8 +15931,8 @@ function warnOnEmptyLoadedDescription({ skillFilePath, description }) {
|
|
|
15924
15931
|
if (typeof description !== "string" || description.length > 0) return;
|
|
15925
15932
|
warnOnceWithFallback(void 0, `${stripControlCharacters(toPosixPath(skillFilePath))}: ${EMPTY_SKILL_DESCRIPTION_VIOLATION}. Rulesync imports it anyway so the content is not lost; fill it in before relying on this skill.`);
|
|
15926
15933
|
}
|
|
15927
|
-
function
|
|
15928
|
-
return
|
|
15934
|
+
function isLenientImportSkillRoot(relativeDirPath) {
|
|
15935
|
+
return LENIENT_IMPORT_SKILL_ROOTS.has(toPosixPath(relativeDirPath));
|
|
15929
15936
|
}
|
|
15930
15937
|
/** Ordered import roots: managed roots first, followed by read-only discovery roots. */
|
|
15931
15938
|
function toolSkillImportRoots(paths) {
|
|
@@ -33155,7 +33162,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
33155
33162
|
for (const root of roots) {
|
|
33156
33163
|
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
33157
33164
|
const relativeDirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
33158
|
-
const isLenientRoot = configuredRootPaths.has(relativeDirPath) || factory.meta.lenientImport === true ||
|
|
33165
|
+
const isLenientRoot = configuredRootPaths.has(relativeDirPath) || factory.meta.lenientImport === true || isLenientImportSkillRoot(relativeDirPath);
|
|
33159
33166
|
const skillsDirPath = (0, node_path.join)(rootOutputRoot, relativeDirPath);
|
|
33160
33167
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
33161
33168
|
const ownedDirNames = [];
|
|
@@ -55844,7 +55851,7 @@ function isFieldApplicable({ commandOnly, hookType }) {
|
|
|
55844
55851
|
* silence — the mirror of the import side.
|
|
55845
55852
|
*/
|
|
55846
55853
|
function emitPassthroughFields({ def, hookType, eventName, fields, isValid, warn }) {
|
|
55847
|
-
for (const { canonical, tool, commandOnly, maxLength, collapseWhitespaceForLength } of fields) {
|
|
55854
|
+
for (const { canonical, tool, commandOnly, maxLength, collapseWhitespaceForLength, onlyWithFlag } of fields) {
|
|
55848
55855
|
const value = def[canonical];
|
|
55849
55856
|
if (value === void 0) continue;
|
|
55850
55857
|
if (!isFieldApplicable({
|
|
@@ -55861,9 +55868,10 @@ function emitPassthroughFields({ def, hookType, eventName, fields, isValid, warn
|
|
|
55861
55868
|
warn?.(`Dropping "${canonical}" from a "${hookType}" hook on "${eventName}": ${quoteValueForWarning(value)} is not a value this tool can express as "${tool}".`);
|
|
55862
55869
|
continue;
|
|
55863
55870
|
}
|
|
55871
|
+
if (onlyWithFlag !== void 0 && def[onlyWithFlag] !== true) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" has no effect without "${onlyWithFlag}": true; this tool reads "${tool}" only on "${onlyWithFlag}" hooks.`);
|
|
55864
55872
|
if (maxLength !== void 0 && typeof value === "string") {
|
|
55865
55873
|
const length = collapseWhitespaceForLength ? value.replace(/\s+/g, " ").trim().length : value.length;
|
|
55866
|
-
if (length > maxLength) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" is ${length} characters long; this tool caps "${tool}" at ${maxLength} characters and will shorten it.`);
|
|
55874
|
+
if (length > maxLength) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" is ${length} characters long${collapseWhitespaceForLength ? " after collapsing whitespace" : ""}; this tool caps "${tool}" at ${maxLength} characters and will shorten it.`);
|
|
55867
55875
|
}
|
|
55868
55876
|
}
|
|
55869
55877
|
return Object.fromEntries(fields.filter(({ canonical, commandOnly }) => isFieldApplicable({
|
|
@@ -64264,14 +64272,16 @@ const QODER_SPEC = {
|
|
|
64264
64272
|
{
|
|
64265
64273
|
canonical: "rewakeMessage",
|
|
64266
64274
|
tool: "rewakeMessage",
|
|
64267
|
-
commandOnly: true
|
|
64275
|
+
commandOnly: true,
|
|
64276
|
+
onlyWithFlag: "asyncRewake"
|
|
64268
64277
|
},
|
|
64269
64278
|
{
|
|
64270
64279
|
canonical: "rewakeSummary",
|
|
64271
64280
|
tool: "rewakeSummary",
|
|
64272
64281
|
commandOnly: true,
|
|
64273
64282
|
maxLength: 300,
|
|
64274
|
-
collapseWhitespaceForLength: true
|
|
64283
|
+
collapseWhitespaceForLength: true,
|
|
64284
|
+
onlyWithFlag: "asyncRewake"
|
|
64275
64285
|
}
|
|
64276
64286
|
],
|
|
64277
64287
|
booleanPassthroughFields: [
|
|
@@ -69651,7 +69661,7 @@ var CodebuddyMcp = class CodebuddyMcp extends ToolMcp {
|
|
|
69651
69661
|
}
|
|
69652
69662
|
};
|
|
69653
69663
|
// src/features/mcp/codebuff-mcp.ts
|
|
69654
|
-
const TOOL_NAME$
|
|
69664
|
+
const TOOL_NAME$2 = "codebuff";
|
|
69655
69665
|
const MAPPED_KEYS = /* @__PURE__ */ new Set([
|
|
69656
69666
|
"type",
|
|
69657
69667
|
"transport",
|
|
@@ -69686,14 +69696,14 @@ function toCodebuffEnv({ name, env, logger }) {
|
|
|
69686
69696
|
}
|
|
69687
69697
|
if (value.startsWith("$")) {
|
|
69688
69698
|
warnAndSkipMcpServer({
|
|
69689
|
-
toolName: TOOL_NAME$
|
|
69699
|
+
toolName: TOOL_NAME$2,
|
|
69690
69700
|
serverName: name,
|
|
69691
69701
|
reason: `env ${quoteValueForWarning(key)} starting with "$" that is not a whole \${VAR} reference, which Codebuff would resolve as a variable name and fail to load the whole mcp.json`,
|
|
69692
69702
|
logger
|
|
69693
69703
|
});
|
|
69694
69704
|
return null;
|
|
69695
69705
|
}
|
|
69696
|
-
if (CANONICAL_ENV_REF.test(value)) logger?.warn(`${TOOL_NAME$
|
|
69706
|
+
if (CANONICAL_ENV_REF.test(value)) logger?.warn(`${TOOL_NAME$2} MCP: env ${quoteValueForWarning(key)} of server ${quoteValueForWarning(name)} embeds a \${VAR} reference; Codebuff only resolves a whole-value \$VAR, so it is written as literal text.`);
|
|
69697
69707
|
converted.push([key, value]);
|
|
69698
69708
|
}
|
|
69699
69709
|
return Object.fromEntries(converted);
|
|
@@ -69710,31 +69720,31 @@ function toCodebuffEnv({ name, env, logger }) {
|
|
|
69710
69720
|
*/
|
|
69711
69721
|
function toCodebuffServer({ name, server, logger }) {
|
|
69712
69722
|
if (server.disabled === true) return warnAndSkipMcpServer({
|
|
69713
|
-
toolName: TOOL_NAME$
|
|
69723
|
+
toolName: TOOL_NAME$2,
|
|
69714
69724
|
serverName: name,
|
|
69715
69725
|
reason: "disabled: true, which Codebuff has no per-server switch for",
|
|
69716
69726
|
logger
|
|
69717
69727
|
});
|
|
69718
69728
|
const transport = server.type ?? server.transport;
|
|
69719
69729
|
if (transport === "ws") return warnAndSkipMcpServer({
|
|
69720
|
-
toolName: TOOL_NAME$
|
|
69730
|
+
toolName: TOOL_NAME$2,
|
|
69721
69731
|
serverName: name,
|
|
69722
69732
|
reason: "the WebSocket transport, which Codebuff does not support",
|
|
69723
69733
|
logger
|
|
69724
69734
|
});
|
|
69725
69735
|
const dropped = Object.keys(server).filter((key) => !MAPPED_KEYS.has(key));
|
|
69726
|
-
if (dropped.length > 0) logger?.warn(`${TOOL_NAME$
|
|
69736
|
+
if (dropped.length > 0) logger?.warn(`${TOOL_NAME$2} MCP: dropping ${dropped.map((key) => quoteValueForWarning(key)).join(", ")} from server ${quoteValueForWarning(name)}; Codebuff rejects keys outside its server schema.`);
|
|
69727
69737
|
if (isRemoteMcpServer(server)) {
|
|
69728
69738
|
const url = resolveRemoteMcpUrl(server);
|
|
69729
69739
|
if (url === void 0) return warnAndSkipMcpServer({
|
|
69730
|
-
toolName: TOOL_NAME$
|
|
69740
|
+
toolName: TOOL_NAME$2,
|
|
69731
69741
|
serverName: name,
|
|
69732
69742
|
reason: "a remote transport without a url",
|
|
69733
69743
|
logger
|
|
69734
69744
|
});
|
|
69735
69745
|
const params = server.params;
|
|
69736
69746
|
const validParams = isRecord(params) && Object.values(params).every((value) => typeof value === "string");
|
|
69737
|
-
if (params !== void 0 && !validParams) logger?.warn(`${TOOL_NAME$
|
|
69747
|
+
if (params !== void 0 && !validParams) logger?.warn(`${TOOL_NAME$2} MCP: dropping params from server ${quoteValueForWarning(name)}; Codebuff accepts only a map of string values.`);
|
|
69738
69748
|
return {
|
|
69739
69749
|
type: transport === "sse" ? "sse" : "http",
|
|
69740
69750
|
url,
|
|
@@ -69744,7 +69754,7 @@ function toCodebuffServer({ name, server, logger }) {
|
|
|
69744
69754
|
}
|
|
69745
69755
|
const [command, ...args] = resolveLocalMcpCommand(server);
|
|
69746
69756
|
if (command === void 0) return warnAndSkipMcpServer({
|
|
69747
|
-
toolName: TOOL_NAME$
|
|
69757
|
+
toolName: TOOL_NAME$2,
|
|
69748
69758
|
serverName: name,
|
|
69749
69759
|
reason: "no command to spawn",
|
|
69750
69760
|
logger
|
|
@@ -72414,7 +72424,7 @@ var CursorMcp = class CursorMcp extends ToolMcp {
|
|
|
72414
72424
|
}
|
|
72415
72425
|
};
|
|
72416
72426
|
// src/features/mcp/deepagents-mcp.ts
|
|
72417
|
-
const TOOL_NAME = "deepagents";
|
|
72427
|
+
const TOOL_NAME$1 = "deepagents";
|
|
72418
72428
|
/**
|
|
72419
72429
|
* Map a canonical transport onto the three dcode accepts.
|
|
72420
72430
|
*
|
|
@@ -72455,7 +72465,7 @@ function applyDeepagentsCommand({ name, server, converted, logger }) {
|
|
|
72455
72465
|
return true;
|
|
72456
72466
|
}
|
|
72457
72467
|
warnAndSkipMcpServer({
|
|
72458
|
-
toolName: TOOL_NAME,
|
|
72468
|
+
toolName: TOOL_NAME$1,
|
|
72459
72469
|
serverName: name,
|
|
72460
72470
|
reason: "an empty command list, which leaves deepagents nothing to spawn",
|
|
72461
72471
|
logger
|
|
@@ -72483,7 +72493,7 @@ function applyDeepagentsCommand({ name, server, converted, logger }) {
|
|
|
72483
72493
|
*/
|
|
72484
72494
|
function toDeepagentsOauth({ name, oauth, converted, logger }) {
|
|
72485
72495
|
if (!isSlackOauthServer(converted)) {
|
|
72486
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth on "${name}"; deepagents reads it only on a Slack (slack.com) server with auth: "oauth" and skips any other server that sets it.`);
|
|
72496
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth on "${name}"; deepagents reads it only on a Slack (slack.com) server with auth: "oauth" and skips any other server that sets it.`);
|
|
72487
72497
|
return;
|
|
72488
72498
|
}
|
|
72489
72499
|
const source = isRecord(oauth) ? oauth : {};
|
|
@@ -72492,18 +72502,18 @@ function toDeepagentsOauth({ name, oauth, converted, logger }) {
|
|
|
72492
72502
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
72493
72503
|
const nativeKey = key === "clientId" ? "client_id" : key;
|
|
72494
72504
|
if (nativeKey !== "client_id" && nativeKey !== "client_secret") {
|
|
72495
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth.${key} on "${name}"; deepagents accepts only client_id and client_secret.`);
|
|
72505
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth.${key} on "${name}"; deepagents accepts only client_id and client_secret.`);
|
|
72496
72506
|
continue;
|
|
72497
72507
|
}
|
|
72498
72508
|
if (nativeKey !== key && isDeepagentsOauthValue(source[nativeKey])) continue;
|
|
72499
72509
|
if (!isDeepagentsOauthValue(value)) {
|
|
72500
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth.${key} on "${name}"; deepagents requires a non-empty string without control characters.`);
|
|
72510
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth.${key} on "${name}"; deepagents requires a non-empty string without control characters.`);
|
|
72501
72511
|
continue;
|
|
72502
72512
|
}
|
|
72503
72513
|
result[nativeKey] = value;
|
|
72504
72514
|
}
|
|
72505
72515
|
if (result.client_id === void 0) {
|
|
72506
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth on "${name}"; deepagents requires oauth.client_id (canonical clientId) and skips a server without it.`);
|
|
72516
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth on "${name}"; deepagents requires oauth.client_id (canonical clientId) and skips a server without it.`);
|
|
72507
72517
|
return;
|
|
72508
72518
|
}
|
|
72509
72519
|
return result;
|
|
@@ -72532,14 +72542,14 @@ function isSlackOauthServer(server) {
|
|
|
72532
72542
|
*/
|
|
72533
72543
|
function toDeepagentsServer({ name, server, logger }) {
|
|
72534
72544
|
if (server.disabled === true) return warnAndSkipMcpServer({
|
|
72535
|
-
toolName: TOOL_NAME,
|
|
72545
|
+
toolName: TOOL_NAME$1,
|
|
72536
72546
|
serverName: name,
|
|
72537
72547
|
reason: "disabled: true, which deepagents does not read from .mcp.json (the server would still run)",
|
|
72538
72548
|
logger
|
|
72539
72549
|
});
|
|
72540
72550
|
const rawTransport = server.transport ?? server.type;
|
|
72541
72551
|
if (rawTransport === "ws") return warnAndSkipMcpServer({
|
|
72542
|
-
toolName: TOOL_NAME,
|
|
72552
|
+
toolName: TOOL_NAME$1,
|
|
72543
72553
|
serverName: name,
|
|
72544
72554
|
reason: "the WebSocket transport, which deepagents does not support",
|
|
72545
72555
|
logger
|
|
@@ -72569,21 +72579,21 @@ function toDeepagentsServer({ name, server, logger }) {
|
|
|
72569
72579
|
if (deepagentsOauth !== void 0) converted.oauth = deepagentsOauth;
|
|
72570
72580
|
}
|
|
72571
72581
|
if (enabledTools !== void 0 && disabledTools !== void 0) return warnAndSkipMcpServer({
|
|
72572
|
-
toolName: TOOL_NAME,
|
|
72582
|
+
toolName: TOOL_NAME$1,
|
|
72573
72583
|
serverName: name,
|
|
72574
72584
|
reason: "both enabledTools and disabledTools, which deepagents rejects — pick one",
|
|
72575
72585
|
logger
|
|
72576
72586
|
});
|
|
72577
72587
|
if (enabledTools !== void 0) {
|
|
72578
72588
|
if (enabledTools.length === 0) return warnAndSkipMcpServer({
|
|
72579
|
-
toolName: TOOL_NAME,
|
|
72589
|
+
toolName: TOOL_NAME$1,
|
|
72580
72590
|
serverName: name,
|
|
72581
72591
|
reason: "an empty enabledTools list, which allows no tools at all and which deepagents rejects",
|
|
72582
72592
|
logger
|
|
72583
72593
|
});
|
|
72584
72594
|
converted.allowedTools = enabledTools;
|
|
72585
72595
|
} else if (disabledTools !== void 0) {
|
|
72586
|
-
if (disabledTools.length === 0) logger?.warn(`${TOOL_NAME} MCP: dropping the empty disabledTools list on "${name}"; it denies nothing, and deepagents rejects the empty form.`);
|
|
72596
|
+
if (disabledTools.length === 0) logger?.warn(`${TOOL_NAME$1} MCP: dropping the empty disabledTools list on "${name}"; it denies nothing, and deepagents rejects the empty form.`);
|
|
72587
72597
|
else converted.disabledTools = disabledTools;
|
|
72588
72598
|
}
|
|
72589
72599
|
return converted;
|
|
@@ -73235,6 +73245,32 @@ var DshMcp = class DshMcp extends ToolMcp {
|
|
|
73235
73245
|
}
|
|
73236
73246
|
};
|
|
73237
73247
|
// src/features/mcp/factorydroid-mcp.ts
|
|
73248
|
+
const TOOL_NAME = "factorydroid";
|
|
73249
|
+
/**
|
|
73250
|
+
* Drop servers whose `enabledTools` allowlist is empty.
|
|
73251
|
+
*
|
|
73252
|
+
* Canonically an empty allowlist allows no tools, but Droid applies
|
|
73253
|
+
* `enabledTools` only "when the list is non-empty"
|
|
73254
|
+
* (https://docs.factory.com/harness/mcp), so writing `[]` would load every
|
|
73255
|
+
* tool the server reports. Skipping the server is the only form that does not
|
|
73256
|
+
* hand the model more tools than the canonical config allows.
|
|
73257
|
+
*/
|
|
73258
|
+
function skipEmptyAllowlistServers({ mcpServers, logger }) {
|
|
73259
|
+
const kept = {};
|
|
73260
|
+
for (const [name, server] of Object.entries(mcpServers)) {
|
|
73261
|
+
if (server.enabledTools?.length === 0) {
|
|
73262
|
+
warnAndSkipMcpServer({
|
|
73263
|
+
toolName: TOOL_NAME,
|
|
73264
|
+
serverName: name,
|
|
73265
|
+
reason: "an empty enabledTools list, which allows no tools at all but which Factory Droid treats as no filter",
|
|
73266
|
+
logger
|
|
73267
|
+
});
|
|
73268
|
+
continue;
|
|
73269
|
+
}
|
|
73270
|
+
kept[name] = server;
|
|
73271
|
+
}
|
|
73272
|
+
return kept;
|
|
73273
|
+
}
|
|
73238
73274
|
var FactorydroidMcp = class FactorydroidMcp extends ToolMcp {
|
|
73239
73275
|
json;
|
|
73240
73276
|
constructor(params) {
|
|
@@ -73260,8 +73296,11 @@ var FactorydroidMcp = class FactorydroidMcp extends ToolMcp {
|
|
|
73260
73296
|
validate
|
|
73261
73297
|
});
|
|
73262
73298
|
}
|
|
73263
|
-
static fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true }) {
|
|
73264
|
-
const factorydroidConfig = { mcpServers:
|
|
73299
|
+
static fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, logger }) {
|
|
73300
|
+
const factorydroidConfig = { mcpServers: skipEmptyAllowlistServers({
|
|
73301
|
+
mcpServers: rulesyncMcp.getMcpServers(),
|
|
73302
|
+
logger
|
|
73303
|
+
}) };
|
|
73265
73304
|
const fileContent = JSON.stringify(factorydroidConfig, null, 2);
|
|
73266
73305
|
return new FactorydroidMcp({
|
|
73267
73306
|
outputRoot,
|
|
@@ -15867,17 +15867,24 @@ function toolSkillSearchRoots(paths) {
|
|
|
15867
15867
|
return [paths.relativeDirPath, ...paths.alternativeSkillRoots ?? []];
|
|
15868
15868
|
}
|
|
15869
15869
|
/**
|
|
15870
|
-
*
|
|
15871
|
-
*
|
|
15872
|
-
*
|
|
15873
|
-
*
|
|
15874
|
-
*
|
|
15875
|
-
*
|
|
15876
|
-
*
|
|
15877
|
-
*
|
|
15878
|
-
*
|
|
15879
|
-
|
|
15880
|
-
|
|
15870
|
+
* Skill roots that every tool scanning them imports leniently (skip-and-warn
|
|
15871
|
+
* per skill) instead of failing fast, regardless of the tool's own
|
|
15872
|
+
* `lenientImport` flag.
|
|
15873
|
+
*
|
|
15874
|
+
* - The Agent Skills interoperability roots: project `.agents/skills/`, global
|
|
15875
|
+
* `~/.agents/skills/` (same relative path, home output root), and Amp's
|
|
15876
|
+
* global equivalent `~/.config/agents/skills/`. Foreign-authored —
|
|
15877
|
+
* potentially non-conformant — skills are the most likely to live here, so
|
|
15878
|
+
* they are imported leniently per the Agent Skills client-implementation
|
|
15879
|
+
* guide, while each tool keeps fail-fast behavior for its own native root.
|
|
15880
|
+
* https://agentskills.io/client-implementation/adding-skills-support
|
|
15881
|
+
* - Amp's read-only global discovery root `~/.config/amp/skills/`, which is not
|
|
15882
|
+
* an interop root but follows the same skip-and-warn rule.
|
|
15883
|
+
*
|
|
15884
|
+
* Other import-only roots (e.g. GitLab Duo's legacy skills root, Kimi Code's
|
|
15885
|
+
* shared root) are not listed here and stay fail-fast.
|
|
15886
|
+
*/
|
|
15887
|
+
const LENIENT_IMPORT_SKILL_ROOTS = /* @__PURE__ */ new Set([
|
|
15881
15888
|
toPosixPath(AGENTSMD_SKILLS_DIR_PATH),
|
|
15882
15889
|
toPosixPath(AMP_SKILLS_GLOBAL_DIR),
|
|
15883
15890
|
toPosixPath(AMP_SKILLS_NATIVE_GLOBAL_DIR)
|
|
@@ -15902,8 +15909,8 @@ function warnOnEmptyLoadedDescription({ skillFilePath, description }) {
|
|
|
15902
15909
|
if (typeof description !== "string" || description.length > 0) return;
|
|
15903
15910
|
warnOnceWithFallback(void 0, `${stripControlCharacters(toPosixPath(skillFilePath))}: ${EMPTY_SKILL_DESCRIPTION_VIOLATION}. Rulesync imports it anyway so the content is not lost; fill it in before relying on this skill.`);
|
|
15904
15911
|
}
|
|
15905
|
-
function
|
|
15906
|
-
return
|
|
15912
|
+
function isLenientImportSkillRoot(relativeDirPath) {
|
|
15913
|
+
return LENIENT_IMPORT_SKILL_ROOTS.has(toPosixPath(relativeDirPath));
|
|
15907
15914
|
}
|
|
15908
15915
|
/** Ordered import roots: managed roots first, followed by read-only discovery roots. */
|
|
15909
15916
|
function toolSkillImportRoots(paths) {
|
|
@@ -33133,7 +33140,7 @@ var SkillsProcessor = class extends DirFeatureProcessor {
|
|
|
33133
33140
|
for (const root of roots) {
|
|
33134
33141
|
const rootOutputRoot = typeof root === "string" ? this.outputRoot : root.outputRoot;
|
|
33135
33142
|
const relativeDirPath = typeof root === "string" ? root : root.relativeDirPath;
|
|
33136
|
-
const isLenientRoot = configuredRootPaths.has(relativeDirPath) || factory.meta.lenientImport === true ||
|
|
33143
|
+
const isLenientRoot = configuredRootPaths.has(relativeDirPath) || factory.meta.lenientImport === true || isLenientImportSkillRoot(relativeDirPath);
|
|
33137
33144
|
const skillsDirPath = join(rootOutputRoot, relativeDirPath);
|
|
33138
33145
|
if (!await directoryExists(skillsDirPath)) continue;
|
|
33139
33146
|
const ownedDirNames = [];
|
|
@@ -55822,7 +55829,7 @@ function isFieldApplicable({ commandOnly, hookType }) {
|
|
|
55822
55829
|
* silence — the mirror of the import side.
|
|
55823
55830
|
*/
|
|
55824
55831
|
function emitPassthroughFields({ def, hookType, eventName, fields, isValid, warn }) {
|
|
55825
|
-
for (const { canonical, tool, commandOnly, maxLength, collapseWhitespaceForLength } of fields) {
|
|
55832
|
+
for (const { canonical, tool, commandOnly, maxLength, collapseWhitespaceForLength, onlyWithFlag } of fields) {
|
|
55826
55833
|
const value = def[canonical];
|
|
55827
55834
|
if (value === void 0) continue;
|
|
55828
55835
|
if (!isFieldApplicable({
|
|
@@ -55839,9 +55846,10 @@ function emitPassthroughFields({ def, hookType, eventName, fields, isValid, warn
|
|
|
55839
55846
|
warn?.(`Dropping "${canonical}" from a "${hookType}" hook on "${eventName}": ${quoteValueForWarning(value)} is not a value this tool can express as "${tool}".`);
|
|
55840
55847
|
continue;
|
|
55841
55848
|
}
|
|
55849
|
+
if (onlyWithFlag !== void 0 && def[onlyWithFlag] !== true) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" has no effect without "${onlyWithFlag}": true; this tool reads "${tool}" only on "${onlyWithFlag}" hooks.`);
|
|
55842
55850
|
if (maxLength !== void 0 && typeof value === "string") {
|
|
55843
55851
|
const length = collapseWhitespaceForLength ? value.replace(/\s+/g, " ").trim().length : value.length;
|
|
55844
|
-
if (length > maxLength) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" is ${length} characters long; this tool caps "${tool}" at ${maxLength} characters and will shorten it.`);
|
|
55852
|
+
if (length > maxLength) warn?.(`"${canonical}" on a "${hookType}" hook on "${eventName}" is ${length} characters long${collapseWhitespaceForLength ? " after collapsing whitespace" : ""}; this tool caps "${tool}" at ${maxLength} characters and will shorten it.`);
|
|
55845
55853
|
}
|
|
55846
55854
|
}
|
|
55847
55855
|
return Object.fromEntries(fields.filter(({ canonical, commandOnly }) => isFieldApplicable({
|
|
@@ -64242,14 +64250,16 @@ const QODER_SPEC = {
|
|
|
64242
64250
|
{
|
|
64243
64251
|
canonical: "rewakeMessage",
|
|
64244
64252
|
tool: "rewakeMessage",
|
|
64245
|
-
commandOnly: true
|
|
64253
|
+
commandOnly: true,
|
|
64254
|
+
onlyWithFlag: "asyncRewake"
|
|
64246
64255
|
},
|
|
64247
64256
|
{
|
|
64248
64257
|
canonical: "rewakeSummary",
|
|
64249
64258
|
tool: "rewakeSummary",
|
|
64250
64259
|
commandOnly: true,
|
|
64251
64260
|
maxLength: 300,
|
|
64252
|
-
collapseWhitespaceForLength: true
|
|
64261
|
+
collapseWhitespaceForLength: true,
|
|
64262
|
+
onlyWithFlag: "asyncRewake"
|
|
64253
64263
|
}
|
|
64254
64264
|
],
|
|
64255
64265
|
booleanPassthroughFields: [
|
|
@@ -69629,7 +69639,7 @@ var CodebuddyMcp = class CodebuddyMcp extends ToolMcp {
|
|
|
69629
69639
|
}
|
|
69630
69640
|
};
|
|
69631
69641
|
// src/features/mcp/codebuff-mcp.ts
|
|
69632
|
-
const TOOL_NAME$
|
|
69642
|
+
const TOOL_NAME$2 = "codebuff";
|
|
69633
69643
|
const MAPPED_KEYS = /* @__PURE__ */ new Set([
|
|
69634
69644
|
"type",
|
|
69635
69645
|
"transport",
|
|
@@ -69664,14 +69674,14 @@ function toCodebuffEnv({ name, env, logger }) {
|
|
|
69664
69674
|
}
|
|
69665
69675
|
if (value.startsWith("$")) {
|
|
69666
69676
|
warnAndSkipMcpServer({
|
|
69667
|
-
toolName: TOOL_NAME$
|
|
69677
|
+
toolName: TOOL_NAME$2,
|
|
69668
69678
|
serverName: name,
|
|
69669
69679
|
reason: `env ${quoteValueForWarning(key)} starting with "$" that is not a whole \${VAR} reference, which Codebuff would resolve as a variable name and fail to load the whole mcp.json`,
|
|
69670
69680
|
logger
|
|
69671
69681
|
});
|
|
69672
69682
|
return null;
|
|
69673
69683
|
}
|
|
69674
|
-
if (CANONICAL_ENV_REF.test(value)) logger?.warn(`${TOOL_NAME$
|
|
69684
|
+
if (CANONICAL_ENV_REF.test(value)) logger?.warn(`${TOOL_NAME$2} MCP: env ${quoteValueForWarning(key)} of server ${quoteValueForWarning(name)} embeds a \${VAR} reference; Codebuff only resolves a whole-value \$VAR, so it is written as literal text.`);
|
|
69675
69685
|
converted.push([key, value]);
|
|
69676
69686
|
}
|
|
69677
69687
|
return Object.fromEntries(converted);
|
|
@@ -69688,31 +69698,31 @@ function toCodebuffEnv({ name, env, logger }) {
|
|
|
69688
69698
|
*/
|
|
69689
69699
|
function toCodebuffServer({ name, server, logger }) {
|
|
69690
69700
|
if (server.disabled === true) return warnAndSkipMcpServer({
|
|
69691
|
-
toolName: TOOL_NAME$
|
|
69701
|
+
toolName: TOOL_NAME$2,
|
|
69692
69702
|
serverName: name,
|
|
69693
69703
|
reason: "disabled: true, which Codebuff has no per-server switch for",
|
|
69694
69704
|
logger
|
|
69695
69705
|
});
|
|
69696
69706
|
const transport = server.type ?? server.transport;
|
|
69697
69707
|
if (transport === "ws") return warnAndSkipMcpServer({
|
|
69698
|
-
toolName: TOOL_NAME$
|
|
69708
|
+
toolName: TOOL_NAME$2,
|
|
69699
69709
|
serverName: name,
|
|
69700
69710
|
reason: "the WebSocket transport, which Codebuff does not support",
|
|
69701
69711
|
logger
|
|
69702
69712
|
});
|
|
69703
69713
|
const dropped = Object.keys(server).filter((key) => !MAPPED_KEYS.has(key));
|
|
69704
|
-
if (dropped.length > 0) logger?.warn(`${TOOL_NAME$
|
|
69714
|
+
if (dropped.length > 0) logger?.warn(`${TOOL_NAME$2} MCP: dropping ${dropped.map((key) => quoteValueForWarning(key)).join(", ")} from server ${quoteValueForWarning(name)}; Codebuff rejects keys outside its server schema.`);
|
|
69705
69715
|
if (isRemoteMcpServer(server)) {
|
|
69706
69716
|
const url = resolveRemoteMcpUrl(server);
|
|
69707
69717
|
if (url === void 0) return warnAndSkipMcpServer({
|
|
69708
|
-
toolName: TOOL_NAME$
|
|
69718
|
+
toolName: TOOL_NAME$2,
|
|
69709
69719
|
serverName: name,
|
|
69710
69720
|
reason: "a remote transport without a url",
|
|
69711
69721
|
logger
|
|
69712
69722
|
});
|
|
69713
69723
|
const params = server.params;
|
|
69714
69724
|
const validParams = isRecord(params) && Object.values(params).every((value) => typeof value === "string");
|
|
69715
|
-
if (params !== void 0 && !validParams) logger?.warn(`${TOOL_NAME$
|
|
69725
|
+
if (params !== void 0 && !validParams) logger?.warn(`${TOOL_NAME$2} MCP: dropping params from server ${quoteValueForWarning(name)}; Codebuff accepts only a map of string values.`);
|
|
69716
69726
|
return {
|
|
69717
69727
|
type: transport === "sse" ? "sse" : "http",
|
|
69718
69728
|
url,
|
|
@@ -69722,7 +69732,7 @@ function toCodebuffServer({ name, server, logger }) {
|
|
|
69722
69732
|
}
|
|
69723
69733
|
const [command, ...args] = resolveLocalMcpCommand(server);
|
|
69724
69734
|
if (command === void 0) return warnAndSkipMcpServer({
|
|
69725
|
-
toolName: TOOL_NAME$
|
|
69735
|
+
toolName: TOOL_NAME$2,
|
|
69726
69736
|
serverName: name,
|
|
69727
69737
|
reason: "no command to spawn",
|
|
69728
69738
|
logger
|
|
@@ -72392,7 +72402,7 @@ var CursorMcp = class CursorMcp extends ToolMcp {
|
|
|
72392
72402
|
}
|
|
72393
72403
|
};
|
|
72394
72404
|
// src/features/mcp/deepagents-mcp.ts
|
|
72395
|
-
const TOOL_NAME = "deepagents";
|
|
72405
|
+
const TOOL_NAME$1 = "deepagents";
|
|
72396
72406
|
/**
|
|
72397
72407
|
* Map a canonical transport onto the three dcode accepts.
|
|
72398
72408
|
*
|
|
@@ -72433,7 +72443,7 @@ function applyDeepagentsCommand({ name, server, converted, logger }) {
|
|
|
72433
72443
|
return true;
|
|
72434
72444
|
}
|
|
72435
72445
|
warnAndSkipMcpServer({
|
|
72436
|
-
toolName: TOOL_NAME,
|
|
72446
|
+
toolName: TOOL_NAME$1,
|
|
72437
72447
|
serverName: name,
|
|
72438
72448
|
reason: "an empty command list, which leaves deepagents nothing to spawn",
|
|
72439
72449
|
logger
|
|
@@ -72461,7 +72471,7 @@ function applyDeepagentsCommand({ name, server, converted, logger }) {
|
|
|
72461
72471
|
*/
|
|
72462
72472
|
function toDeepagentsOauth({ name, oauth, converted, logger }) {
|
|
72463
72473
|
if (!isSlackOauthServer(converted)) {
|
|
72464
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth on "${name}"; deepagents reads it only on a Slack (slack.com) server with auth: "oauth" and skips any other server that sets it.`);
|
|
72474
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth on "${name}"; deepagents reads it only on a Slack (slack.com) server with auth: "oauth" and skips any other server that sets it.`);
|
|
72465
72475
|
return;
|
|
72466
72476
|
}
|
|
72467
72477
|
const source = isRecord(oauth) ? oauth : {};
|
|
@@ -72470,18 +72480,18 @@ function toDeepagentsOauth({ name, oauth, converted, logger }) {
|
|
|
72470
72480
|
if (PROTOTYPE_POLLUTION_KEYS.has(key)) continue;
|
|
72471
72481
|
const nativeKey = key === "clientId" ? "client_id" : key;
|
|
72472
72482
|
if (nativeKey !== "client_id" && nativeKey !== "client_secret") {
|
|
72473
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth.${key} on "${name}"; deepagents accepts only client_id and client_secret.`);
|
|
72483
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth.${key} on "${name}"; deepagents accepts only client_id and client_secret.`);
|
|
72474
72484
|
continue;
|
|
72475
72485
|
}
|
|
72476
72486
|
if (nativeKey !== key && isDeepagentsOauthValue(source[nativeKey])) continue;
|
|
72477
72487
|
if (!isDeepagentsOauthValue(value)) {
|
|
72478
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth.${key} on "${name}"; deepagents requires a non-empty string without control characters.`);
|
|
72488
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth.${key} on "${name}"; deepagents requires a non-empty string without control characters.`);
|
|
72479
72489
|
continue;
|
|
72480
72490
|
}
|
|
72481
72491
|
result[nativeKey] = value;
|
|
72482
72492
|
}
|
|
72483
72493
|
if (result.client_id === void 0) {
|
|
72484
|
-
logger?.warn(`${TOOL_NAME} MCP: dropping oauth on "${name}"; deepagents requires oauth.client_id (canonical clientId) and skips a server without it.`);
|
|
72494
|
+
logger?.warn(`${TOOL_NAME$1} MCP: dropping oauth on "${name}"; deepagents requires oauth.client_id (canonical clientId) and skips a server without it.`);
|
|
72485
72495
|
return;
|
|
72486
72496
|
}
|
|
72487
72497
|
return result;
|
|
@@ -72510,14 +72520,14 @@ function isSlackOauthServer(server) {
|
|
|
72510
72520
|
*/
|
|
72511
72521
|
function toDeepagentsServer({ name, server, logger }) {
|
|
72512
72522
|
if (server.disabled === true) return warnAndSkipMcpServer({
|
|
72513
|
-
toolName: TOOL_NAME,
|
|
72523
|
+
toolName: TOOL_NAME$1,
|
|
72514
72524
|
serverName: name,
|
|
72515
72525
|
reason: "disabled: true, which deepagents does not read from .mcp.json (the server would still run)",
|
|
72516
72526
|
logger
|
|
72517
72527
|
});
|
|
72518
72528
|
const rawTransport = server.transport ?? server.type;
|
|
72519
72529
|
if (rawTransport === "ws") return warnAndSkipMcpServer({
|
|
72520
|
-
toolName: TOOL_NAME,
|
|
72530
|
+
toolName: TOOL_NAME$1,
|
|
72521
72531
|
serverName: name,
|
|
72522
72532
|
reason: "the WebSocket transport, which deepagents does not support",
|
|
72523
72533
|
logger
|
|
@@ -72547,21 +72557,21 @@ function toDeepagentsServer({ name, server, logger }) {
|
|
|
72547
72557
|
if (deepagentsOauth !== void 0) converted.oauth = deepagentsOauth;
|
|
72548
72558
|
}
|
|
72549
72559
|
if (enabledTools !== void 0 && disabledTools !== void 0) return warnAndSkipMcpServer({
|
|
72550
|
-
toolName: TOOL_NAME,
|
|
72560
|
+
toolName: TOOL_NAME$1,
|
|
72551
72561
|
serverName: name,
|
|
72552
72562
|
reason: "both enabledTools and disabledTools, which deepagents rejects — pick one",
|
|
72553
72563
|
logger
|
|
72554
72564
|
});
|
|
72555
72565
|
if (enabledTools !== void 0) {
|
|
72556
72566
|
if (enabledTools.length === 0) return warnAndSkipMcpServer({
|
|
72557
|
-
toolName: TOOL_NAME,
|
|
72567
|
+
toolName: TOOL_NAME$1,
|
|
72558
72568
|
serverName: name,
|
|
72559
72569
|
reason: "an empty enabledTools list, which allows no tools at all and which deepagents rejects",
|
|
72560
72570
|
logger
|
|
72561
72571
|
});
|
|
72562
72572
|
converted.allowedTools = enabledTools;
|
|
72563
72573
|
} else if (disabledTools !== void 0) {
|
|
72564
|
-
if (disabledTools.length === 0) logger?.warn(`${TOOL_NAME} MCP: dropping the empty disabledTools list on "${name}"; it denies nothing, and deepagents rejects the empty form.`);
|
|
72574
|
+
if (disabledTools.length === 0) logger?.warn(`${TOOL_NAME$1} MCP: dropping the empty disabledTools list on "${name}"; it denies nothing, and deepagents rejects the empty form.`);
|
|
72565
72575
|
else converted.disabledTools = disabledTools;
|
|
72566
72576
|
}
|
|
72567
72577
|
return converted;
|
|
@@ -73213,6 +73223,32 @@ var DshMcp = class DshMcp extends ToolMcp {
|
|
|
73213
73223
|
}
|
|
73214
73224
|
};
|
|
73215
73225
|
// src/features/mcp/factorydroid-mcp.ts
|
|
73226
|
+
const TOOL_NAME = "factorydroid";
|
|
73227
|
+
/**
|
|
73228
|
+
* Drop servers whose `enabledTools` allowlist is empty.
|
|
73229
|
+
*
|
|
73230
|
+
* Canonically an empty allowlist allows no tools, but Droid applies
|
|
73231
|
+
* `enabledTools` only "when the list is non-empty"
|
|
73232
|
+
* (https://docs.factory.com/harness/mcp), so writing `[]` would load every
|
|
73233
|
+
* tool the server reports. Skipping the server is the only form that does not
|
|
73234
|
+
* hand the model more tools than the canonical config allows.
|
|
73235
|
+
*/
|
|
73236
|
+
function skipEmptyAllowlistServers({ mcpServers, logger }) {
|
|
73237
|
+
const kept = {};
|
|
73238
|
+
for (const [name, server] of Object.entries(mcpServers)) {
|
|
73239
|
+
if (server.enabledTools?.length === 0) {
|
|
73240
|
+
warnAndSkipMcpServer({
|
|
73241
|
+
toolName: TOOL_NAME,
|
|
73242
|
+
serverName: name,
|
|
73243
|
+
reason: "an empty enabledTools list, which allows no tools at all but which Factory Droid treats as no filter",
|
|
73244
|
+
logger
|
|
73245
|
+
});
|
|
73246
|
+
continue;
|
|
73247
|
+
}
|
|
73248
|
+
kept[name] = server;
|
|
73249
|
+
}
|
|
73250
|
+
return kept;
|
|
73251
|
+
}
|
|
73216
73252
|
var FactorydroidMcp = class FactorydroidMcp extends ToolMcp {
|
|
73217
73253
|
json;
|
|
73218
73254
|
constructor(params) {
|
|
@@ -73238,8 +73274,11 @@ var FactorydroidMcp = class FactorydroidMcp extends ToolMcp {
|
|
|
73238
73274
|
validate
|
|
73239
73275
|
});
|
|
73240
73276
|
}
|
|
73241
|
-
static fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true }) {
|
|
73242
|
-
const factorydroidConfig = { mcpServers:
|
|
73277
|
+
static fromRulesyncMcp({ outputRoot = process.cwd(), rulesyncMcp, validate = true, logger }) {
|
|
73278
|
+
const factorydroidConfig = { mcpServers: skipEmptyAllowlistServers({
|
|
73279
|
+
mcpServers: rulesyncMcp.getMcpServers(),
|
|
73280
|
+
logger
|
|
73281
|
+
}) };
|
|
73243
73282
|
const fileContent = JSON.stringify(factorydroidConfig, null, 2);
|
|
73244
73283
|
return new FactorydroidMcp({
|
|
73245
73284
|
outputRoot,
|
|
@@ -106436,4 +106475,4 @@ async function importChecksCore(params) {
|
|
|
106436
106475
|
}
|
|
106437
106476
|
export { RulesyncPermissions as $, formatError as $n, isSymlink as $t, CODEBUDDY_DIR as A, MAX_FILE_SIZE as An, withFallbackLoggerTarget as At, CLAUDECODE_LOCAL_RULE_FILE_NAME as B, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as Bn, assertTreeContainsNoSymlinks as Bt, QWENCODE_LOCAL_RULE_FILE_NAME as C, PACKAGING_TOOL_TARGETS as Cn, getSourceTransport as Ct, FACTORYDROID_SETTINGS_LOCAL_FILE_NAME as D, DEPRECATED_FEATURE_REPLACEMENTS as Dn, WarningCollectingLogger as Dt, FACTORYDROID_DIR as E, ALL_FEATURES_WITH_WILDCARD as En, JsonLogger as Et, groupSpellingsByCaseFoldedIdentity as F, RULESYNC_CONFIG_SCHEMA_URL as Fn, PathOutsideRootError as Ft, toInstructionBudgetFile as G, RULESYNC_PERMISSIONS_SCHEMA_URL as Gn, ensureDir as Gt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as H, RULESYNC_MCP_SCHEMA_URL as Hn, checkPathTraversal as Ht, CODEXCLI_BASH_RULES_FILE_NAME as I, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as In, applyFileMode as It, RulesyncSubagentFrontmatterSchema as J, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Jn, findFilesByGlobs as Jt, getLocalSkillDirNames as K, RULESYNC_RELATIVE_DIR_PATH as Kn, fileExists as Kt, CODEXCLI_DIR as L, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as Ln, assertDirectoryIfExists as Lt, AUGMENTCODE_DIR as M, RULESYNC_CHECKS_RELATIVE_DIR_PATH as Mn, withWarnOnceScope as Mt, AUGMENTCODE_SETTINGS_LOCAL_FILE_NAME as N, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as Nn, CLIError as Nt, COMMANDCODE_DIR as O, CURATED_RULES_FEATURE_SUBDIR as On, fallbackLogger as Ot, caseFoldIdentity as P, RULESYNC_CONFIG_RELATIVE_FILE_PATH as Pn, ErrorCodes as Pt, RulesyncRuleFrontmatterSchema as Q, RULESYNC_XDG_CONFIG_HOME_DEFAULT_DIR_NAME as Qn, isFileSystemError as Qt, CLAUDECODE_AGENT_MEMORY_LOCAL_DIR_NAME as R, RULESYNC_HOOKS_RELATIVE_FILE_PATH as Rn, assertNoSymlinkBelowRoot as Rt, QWENCODE_DIR as S, ALL_TOOL_TARGETS_WITH_WILDCARD as Sn, assertTargetsFeaturesExclusive as St, LETTACODE_SETTINGS_LOCAL_FILE_NAME as T, ALL_FEATURES as Tn, ConsoleLogger as Tt, CLAUDECODE_SKILLS_DIR_PATH as U, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as Un, createTempDirectory as Ut, CLAUDECODE_MEMORIES_DIR_NAME as V, RULESYNC_MCP_RELATIVE_FILE_PATH as Vn, assertWritablePathInsideRoot as Vt, findProjectInstructionBudgetFindings as W, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Wn, directoryExists as Wt, RulesyncSkillFrontmatterSchema as X, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as Xn, getHomeDirectory as Xt, RulesyncSkill as Y, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as Yn, getFileSizeAndExecutableBit as Yt, RulesyncRule as Z, RULESYNC_USER_CONFIG_DIR_NAME as Zn, isFileNotFoundError as Zt, SubagentsProcessor as _, toPosixPath as _n, resolveEffectiveInputRoots as _t, convertFromTool as a, readFileContent as an, stripControlCharactersKeepingLineFeeds as ar, parseJsonc as at, CommandsProcessor as b, mapWithConcurrency as bn, GITIGNORE_DESTINATION_KEY as bt, parseCommaSeparatedList as c, removeDirectoryStrict as cn, RulesyncCheck as ct, shortenToWidth as d, removeFileWithoutFollowingSymlinks as dn, loadYaml as dt, listDirectoryEntryNames as en, truncateText as er, RulesyncMcp as et, McpProcessor as f, removeTempDirectory as fn, isRecord as ft, RulesProcessor as g, splitPathSegments as gn, mergeInputRootConfigs as gt, ChecksProcessor as h, runWithDirectoryRollback as hn, ConfigResolver as ht, inspectInputRoots as i, posixRelativePathEscapesRoot as in, stripControlCharacters as ir, resolveRulesyncSourceWritePath as it, CODEBUDDY_LOCAL_RULE_FILE_NAME as j, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as jn, resetRunWarningState as jt, COMMANDCODE_SETTINGS_LOCAL_FILE_NAME as k, FEATURE_SOURCE_TREE_ENTRIES as kn, warnOnConflictingFlags as kt, ELLIPSIS_WIDTH as l, removeFile as ln, RulesyncCheckFrontmatterSchema as lt, HooksProcessor as m, resolvedRelativePath as mn, SKILL_FILE_NAME as mt, formatSourceLoadFailure as n, listSubdirectoryNames as nn, hasEnclosingMarkOutsideKeycap as nr, RulesyncHooks as nt, isPackagingToolTarget as o, readFileContentOrNull as on, stripControlCharactersKeepingLineFeedsAndTabs as or, RulesyncCommand as ot, IgnoreProcessor as p, resolvePath as pn, SHARED_USER_MANAGED_CONFIG_PATHS as pt, RulesyncSubagent as q, RULESYNC_RULES_RELATIVE_DIR_PATH as qn, fileExistsStrict as qt, generate as r, pathEscapesRoot as rn, quoteForLog as rr, getRulesyncSourceCandidates as rt, getProcessorRegistryEntry as s, removeDirectory as sn, stripHiddenCharacters as sr, RulesyncCommandFrontmatterSchema as st, importFromTool as t, listFilePathsRecursively as tn, hasDeceptiveHiddenCharacters as tr, RulesyncIgnore as tt, displayWidthOf as u, removeFileStrict as un, stringifyFrontmatter as ut, SkillsProcessor as v, writeFileBuffer as vn, CONFLICTING_TARGET_PAIRS as vt, LETTACODE_DIR as w, ToolTargetSchema as wn, findControlCharacter as wt, REASONIX_LOCAL_RULE_FILE_NAME as x, ALL_TOOL_TARGETS as xn, SourceEntrySchema as xt, CRUSH_LOCAL_RULE_FILE_NAME as y, writeFileContent as yn, ConfigFileSchema as yt, CLAUDECODE_DIR as z, RULESYNC_IGNORE_RELATIVE_FILE_PATH as zn, assertPathResolvesInsideRoot as zt };
|
|
106438
106477
|
|
|
106439
|
-
//# sourceMappingURL=import-
|
|
106478
|
+
//# sourceMappingURL=import-D2uYjAdc.js.map
|