rulesync 15.0.1 → 15.1.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/dist/cli/index.cjs +14 -4
- package/dist/cli/index.d.cts +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.js +14 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/{import-DRN7goJ_.cjs → import-CVk4I0-A.cjs} +468 -88
- package/dist/{import-BuxzyDyH.js → import-WWoS8Wv4.js} +454 -74
- package/dist/import-WWoS8Wv4.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +15 -15
- package/dist/import-BuxzyDyH.js.map +0 -1
|
@@ -2573,15 +2573,14 @@ const KIMI_CODE_TO_CANONICAL_EVENT_NAMES = Object.fromEntries(Object.entries(CAN
|
|
|
2573
2573
|
*
|
|
2574
2574
|
* Hermes validates hook events against a fixed `VALID_HOOKS` set:
|
|
2575
2575
|
* `pre_tool_call`, `post_tool_call`, `pre_llm_call`, `post_llm_call`,
|
|
2576
|
-
* `pre_verify`, `
|
|
2576
|
+
* `pre_verify`, `pre_api_request`, `post_api_request`, `api_request_error`,
|
|
2577
|
+
* `on_session_start`, `on_session_end`, `on_session_finalize`,
|
|
2577
2578
|
* `on_session_reset`, `subagent_start`, `subagent_stop`, `pre_gateway_dispatch`,
|
|
2578
2579
|
* `pre_approval_request`, `post_approval_response`, `transform_tool_result`,
|
|
2579
|
-
* `transform_terminal_output`, `transform_llm_output
|
|
2580
|
-
* clean 1:1 canonical equivalent
|
|
2581
|
-
*
|
|
2582
|
-
* `
|
|
2583
|
-
* `transform_*` result-rewriting hooks) have no canonical rulesync equivalent,
|
|
2584
|
-
* so no canonical event maps to them.
|
|
2580
|
+
* `transform_terminal_output`, `transform_llm_output`, and the three
|
|
2581
|
+
* `kanban_task_*` events. Only the events with a clean 1:1 canonical equivalent
|
|
2582
|
+
* are mapped here. All other native events round-trip through
|
|
2583
|
+
* `hermesagent.hooks`.
|
|
2585
2584
|
* @see https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/hooks.md
|
|
2586
2585
|
*/
|
|
2587
2586
|
const HERMESAGENT_HOOK_EVENTS = [
|
|
@@ -2594,6 +2593,31 @@ const HERMESAGENT_HOOK_EVENTS = [
|
|
|
2594
2593
|
"subagentStart",
|
|
2595
2594
|
"subagentStop"
|
|
2596
2595
|
];
|
|
2596
|
+
const HERMESAGENT_NATIVE_HOOK_EVENTS = [
|
|
2597
|
+
"pre_tool_call",
|
|
2598
|
+
"post_tool_call",
|
|
2599
|
+
"transform_terminal_output",
|
|
2600
|
+
"transform_tool_result",
|
|
2601
|
+
"transform_llm_output",
|
|
2602
|
+
"pre_llm_call",
|
|
2603
|
+
"post_llm_call",
|
|
2604
|
+
"pre_verify",
|
|
2605
|
+
"pre_api_request",
|
|
2606
|
+
"post_api_request",
|
|
2607
|
+
"api_request_error",
|
|
2608
|
+
"on_session_start",
|
|
2609
|
+
"on_session_end",
|
|
2610
|
+
"on_session_finalize",
|
|
2611
|
+
"on_session_reset",
|
|
2612
|
+
"subagent_start",
|
|
2613
|
+
"subagent_stop",
|
|
2614
|
+
"pre_gateway_dispatch",
|
|
2615
|
+
"pre_approval_request",
|
|
2616
|
+
"post_approval_response",
|
|
2617
|
+
"kanban_task_claimed",
|
|
2618
|
+
"kanban_task_completed",
|
|
2619
|
+
"kanban_task_blocked"
|
|
2620
|
+
];
|
|
2597
2621
|
/**
|
|
2598
2622
|
* Map canonical camelCase event names to Hermes Agent's native `VALID_HOOKS`
|
|
2599
2623
|
* snake_case keys under the `hooks:` block of `~/.hermes/config.yaml`.
|
|
@@ -4741,6 +4765,7 @@ const RulesyncSkillFrontmatterSchema = z.looseObject({
|
|
|
4741
4765
|
metadata: z.optional(z.looseObject({})),
|
|
4742
4766
|
"allowed-tools": z.optional(z.union([z.string(), z.array(z.string())]))
|
|
4743
4767
|
})),
|
|
4768
|
+
hermesagent: z.optional(z.looseObject({})),
|
|
4744
4769
|
vibe: z.optional(z.looseObject({
|
|
4745
4770
|
license: z.optional(z.string()),
|
|
4746
4771
|
compatibility: z.optional(z.union([z.string(), z.looseObject({})])),
|
|
@@ -5313,6 +5338,7 @@ const HERMESAGENT_GLOBAL_DIR = ".hermes";
|
|
|
5313
5338
|
/** MCP servers and other settings live in `config.yaml` under `~/.hermes/`. */
|
|
5314
5339
|
const HERMESAGENT_CONFIG_FILE_NAME = "config.yaml";
|
|
5315
5340
|
const HERMESAGENT_CONFIG_FILE_PATH = join(HERMESAGENT_GLOBAL_DIR, HERMESAGENT_CONFIG_FILE_NAME);
|
|
5341
|
+
const HERMESAGENT_PROJECT_PLUGINS_ENV_VAR = "HERMES_ENABLE_PROJECT_PLUGINS";
|
|
5316
5342
|
const HERMESAGENT_SKILLS_DIR_PATH = join(HERMESAGENT_GLOBAL_DIR, "skills");
|
|
5317
5343
|
const HERMESAGENT_RULESYNC_DIR_PATH = join(HERMESAGENT_GLOBAL_DIR, "rulesync");
|
|
5318
5344
|
const HERMESAGENT_RULESYNC_COMMANDS_DIR_PATH = join(HERMESAGENT_RULESYNC_DIR_PATH, "commands");
|
|
@@ -8242,7 +8268,12 @@ var AgentsSkillsSkill = class AgentsSkillsSkill extends ToolSkill {
|
|
|
8242
8268
|
};
|
|
8243
8269
|
//#endregion
|
|
8244
8270
|
//#region src/features/skills/hermesagent-skill.ts
|
|
8245
|
-
|
|
8271
|
+
const SHARED_AGENT_SKILL_FIELDS = /* @__PURE__ */ new Set([
|
|
8272
|
+
"license",
|
|
8273
|
+
"compatibility",
|
|
8274
|
+
"allowed-tools"
|
|
8275
|
+
]);
|
|
8276
|
+
var HermesagentSkill = class HermesagentSkill extends AgentsSkillsSkill {
|
|
8246
8277
|
static isTargetedByRulesyncSkill(rulesyncSkill) {
|
|
8247
8278
|
const targets = rulesyncSkill.getFrontmatter().targets;
|
|
8248
8279
|
return targets.includes("*") || targets.includes("agentsskills") || targets.includes("hermesagent");
|
|
@@ -8256,6 +8287,87 @@ var HermesagentSkill = class extends AgentsSkillsSkill {
|
|
|
8256
8287
|
relativeDirPath: HERMESAGENT_SKILLS_DIR_PATH
|
|
8257
8288
|
});
|
|
8258
8289
|
}
|
|
8290
|
+
static fromRulesyncSkill({ outputRoot = process.cwd(), rulesyncSkill, validate = true, global = false }) {
|
|
8291
|
+
const rulesyncFrontmatter = rulesyncSkill.getFrontmatter();
|
|
8292
|
+
const shared = rulesyncFrontmatter.agentsskills ?? {};
|
|
8293
|
+
const hermes = rulesyncFrontmatter.hermesagent ?? {};
|
|
8294
|
+
return new this({
|
|
8295
|
+
outputRoot,
|
|
8296
|
+
relativeDirPath: HERMESAGENT_SKILLS_DIR_PATH,
|
|
8297
|
+
dirName: rulesyncSkill.getDirName(),
|
|
8298
|
+
frontmatter: {
|
|
8299
|
+
...shared,
|
|
8300
|
+
...hermes,
|
|
8301
|
+
name: rulesyncFrontmatter.name,
|
|
8302
|
+
description: rulesyncFrontmatter.description
|
|
8303
|
+
},
|
|
8304
|
+
body: rulesyncSkill.getBody(),
|
|
8305
|
+
otherFiles: rulesyncSkill.getOtherFiles(),
|
|
8306
|
+
validate,
|
|
8307
|
+
global
|
|
8308
|
+
});
|
|
8309
|
+
}
|
|
8310
|
+
toRulesyncSkill() {
|
|
8311
|
+
const frontmatter = this.getFrontmatter();
|
|
8312
|
+
const agentsskills = {
|
|
8313
|
+
...frontmatter.license !== void 0 && { license: frontmatter.license },
|
|
8314
|
+
...frontmatter.compatibility !== void 0 && { compatibility: frontmatter.compatibility },
|
|
8315
|
+
...frontmatter["allowed-tools"] !== void 0 && { "allowed-tools": frontmatter["allowed-tools"] }
|
|
8316
|
+
};
|
|
8317
|
+
const hermesagent = {};
|
|
8318
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
8319
|
+
if (key === "name" || key === "description") continue;
|
|
8320
|
+
if (!SHARED_AGENT_SKILL_FIELDS.has(key)) hermesagent[key] = value;
|
|
8321
|
+
}
|
|
8322
|
+
const rulesyncFrontmatter = {
|
|
8323
|
+
name: frontmatter.name,
|
|
8324
|
+
description: frontmatter.description,
|
|
8325
|
+
targets: ["*"],
|
|
8326
|
+
...Object.keys(agentsskills).length > 0 && { agentsskills },
|
|
8327
|
+
...Object.keys(hermesagent).length > 0 && { hermesagent }
|
|
8328
|
+
};
|
|
8329
|
+
return new RulesyncSkill({
|
|
8330
|
+
outputRoot: this.outputRoot,
|
|
8331
|
+
relativeDirPath: RULESYNC_SKILLS_RELATIVE_DIR_PATH,
|
|
8332
|
+
dirName: this.getDirName(),
|
|
8333
|
+
frontmatter: rulesyncFrontmatter,
|
|
8334
|
+
body: this.getBody(),
|
|
8335
|
+
otherFiles: this.getOtherFiles(),
|
|
8336
|
+
validate: true,
|
|
8337
|
+
global: this.global
|
|
8338
|
+
});
|
|
8339
|
+
}
|
|
8340
|
+
static async fromDir(params) {
|
|
8341
|
+
const loaded = await this.loadSkillDirContent({
|
|
8342
|
+
...params,
|
|
8343
|
+
getSettablePaths: HermesagentSkill.getSettablePaths
|
|
8344
|
+
});
|
|
8345
|
+
return new this({
|
|
8346
|
+
outputRoot: loaded.outputRoot,
|
|
8347
|
+
relativeDirPath: loaded.relativeDirPath,
|
|
8348
|
+
dirName: loaded.dirName,
|
|
8349
|
+
frontmatter: loaded.frontmatter,
|
|
8350
|
+
body: loaded.body,
|
|
8351
|
+
otherFiles: loaded.otherFiles,
|
|
8352
|
+
validate: true,
|
|
8353
|
+
global: loaded.global
|
|
8354
|
+
});
|
|
8355
|
+
}
|
|
8356
|
+
static forDeletion({ outputRoot = process.cwd(), relativeDirPath, dirName, global = false }) {
|
|
8357
|
+
return new this({
|
|
8358
|
+
outputRoot,
|
|
8359
|
+
relativeDirPath: relativeDirPath ?? HERMESAGENT_SKILLS_DIR_PATH,
|
|
8360
|
+
dirName,
|
|
8361
|
+
frontmatter: {
|
|
8362
|
+
name: "",
|
|
8363
|
+
description: ""
|
|
8364
|
+
},
|
|
8365
|
+
body: "",
|
|
8366
|
+
otherFiles: [],
|
|
8367
|
+
validate: false,
|
|
8368
|
+
global
|
|
8369
|
+
});
|
|
8370
|
+
}
|
|
8259
8371
|
};
|
|
8260
8372
|
//#endregion
|
|
8261
8373
|
//#region src/features/commands/hermesagent-command.ts
|
|
@@ -8282,7 +8394,7 @@ import json
|
|
|
8282
8394
|
from pathlib import Path
|
|
8283
8395
|
|
|
8284
8396
|
|
|
8285
|
-
COMMANDS_DIR = Path.
|
|
8397
|
+
COMMANDS_DIR = Path(__file__).resolve().parents[2] / "rulesync" / "commands"
|
|
8286
8398
|
|
|
8287
8399
|
|
|
8288
8400
|
def _load_commands():
|
|
@@ -10735,7 +10847,7 @@ function isToolMatcherEntry(x) {
|
|
|
10735
10847
|
/**
|
|
10736
10848
|
* Filter the shared canonical hooks to the supported events and merge tool overrides on top.
|
|
10737
10849
|
*/
|
|
10738
|
-
function buildEffectiveHooks$
|
|
10850
|
+
function buildEffectiveHooks$1({ config, toolOverrideHooks, supportedEvents }) {
|
|
10739
10851
|
const supported = new Set(supportedEvents);
|
|
10740
10852
|
const sharedHooks = {};
|
|
10741
10853
|
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) sharedHooks[event] = defs;
|
|
@@ -10865,7 +10977,7 @@ function buildToolHooks({ defs, converterConfig }) {
|
|
|
10865
10977
|
* (e.g. beforeSubmitPrompt → UserPromptSubmit).
|
|
10866
10978
|
*/
|
|
10867
10979
|
function canonicalToToolHooks({ config, toolOverrideHooks, converterConfig, logger }) {
|
|
10868
|
-
const effectiveHooks = buildEffectiveHooks$
|
|
10980
|
+
const effectiveHooks = buildEffectiveHooks$1({
|
|
10869
10981
|
config,
|
|
10870
10982
|
toolOverrideHooks,
|
|
10871
10983
|
supportedEvents: converterConfig.supportedEvents
|
|
@@ -12899,20 +13011,9 @@ var GrokcliHooks = class GrokcliHooks extends ToolHooks {
|
|
|
12899
13011
|
* `matcher`.
|
|
12900
13012
|
* @see https://github.com/NousResearch/hermes-agent/blob/main/website/docs/user-guide/features/hooks.md
|
|
12901
13013
|
*/
|
|
12902
|
-
const HERMESAGENT_MATCHER_EVENTS = /* @__PURE__ */ new Set(["
|
|
12903
|
-
|
|
12904
|
-
|
|
12905
|
-
* the `hermesagent`-specific override block on top.
|
|
12906
|
-
*/
|
|
12907
|
-
function buildEffectiveHooks$1(config, toolOverrideHooks) {
|
|
12908
|
-
const supported = new Set(HERMESAGENT_HOOK_EVENTS);
|
|
12909
|
-
const shared = {};
|
|
12910
|
-
for (const [event, defs] of Object.entries(config.hooks)) if (supported.has(event)) shared[event] = defs;
|
|
12911
|
-
return {
|
|
12912
|
-
...shared,
|
|
12913
|
-
...toolOverrideHooks
|
|
12914
|
-
};
|
|
12915
|
-
}
|
|
13014
|
+
const HERMESAGENT_MATCHER_EVENTS = /* @__PURE__ */ new Set(["pre_tool_call", "post_tool_call"]);
|
|
13015
|
+
const HERMESAGENT_CANONICAL_EVENTS = new Set(HERMESAGENT_HOOK_EVENTS);
|
|
13016
|
+
const HERMESAGENT_NATIVE_EVENTS = new Set(HERMESAGENT_NATIVE_HOOK_EVENTS);
|
|
12916
13017
|
/**
|
|
12917
13018
|
* Convert the canonical hooks config into Hermes's native
|
|
12918
13019
|
* `hooks: { <event>: [{ matcher?, command, timeout? }] }` shape.
|
|
@@ -12925,24 +13026,62 @@ function buildEffectiveHooks$1(config, toolOverrideHooks) {
|
|
|
12925
13026
|
* warning, mirroring how other adapters (e.g. AugmentCode) handle
|
|
12926
13027
|
* matcher-less lifecycle events.
|
|
12927
13028
|
*/
|
|
13029
|
+
function definitionsToHermesEntries({ event, sourceEvent = event, definitions, logger }) {
|
|
13030
|
+
const supportsMatcher = HERMESAGENT_MATCHER_EVENTS.has(event);
|
|
13031
|
+
const entries = [];
|
|
13032
|
+
for (const definition of definitions) {
|
|
13033
|
+
if ((definition.type ?? "command") !== "command" || typeof definition.command !== "string" || definition.command === "") continue;
|
|
13034
|
+
const entry = { command: definition.command };
|
|
13035
|
+
if (typeof definition.matcher === "string" && definition.matcher !== "") if (supportsMatcher) entry.matcher = definition.matcher;
|
|
13036
|
+
else logger?.warn(`matcher "${definition.matcher}" on "${sourceEvent}" hook will be ignored — Hermes Agent only supports matchers on pre_tool_call/post_tool_call`);
|
|
13037
|
+
if (typeof definition.timeout === "number") entry.timeout = definition.timeout;
|
|
13038
|
+
entries.push(entry);
|
|
13039
|
+
}
|
|
13040
|
+
return entries;
|
|
13041
|
+
}
|
|
13042
|
+
function setHermesHookEntries({ result, event, sourceEvent, definitions, logger }) {
|
|
13043
|
+
if (PROTOTYPE_POLLUTION_KEYS.has(event)) return;
|
|
13044
|
+
const entries = definitionsToHermesEntries({
|
|
13045
|
+
event,
|
|
13046
|
+
sourceEvent,
|
|
13047
|
+
definitions,
|
|
13048
|
+
logger
|
|
13049
|
+
});
|
|
13050
|
+
if (entries.length > 0) result[event] = entries;
|
|
13051
|
+
}
|
|
12928
13052
|
function canonicalToHermesHooks({ config, toolOverrideHooks, logger }) {
|
|
12929
|
-
const effectiveHooks = buildEffectiveHooks$1(config, toolOverrideHooks);
|
|
12930
13053
|
const result = {};
|
|
12931
|
-
for (const [canonicalEvent,
|
|
13054
|
+
for (const [canonicalEvent, definitions] of Object.entries(config.hooks)) {
|
|
13055
|
+
if (!HERMESAGENT_CANONICAL_EVENTS.has(canonicalEvent)) continue;
|
|
12932
13056
|
const nativeEvent = CANONICAL_TO_HERMESAGENT_EVENT_NAMES[canonicalEvent];
|
|
12933
|
-
if (
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
13057
|
+
if (nativeEvent) setHermesHookEntries({
|
|
13058
|
+
result,
|
|
13059
|
+
event: nativeEvent,
|
|
13060
|
+
sourceEvent: canonicalEvent,
|
|
13061
|
+
definitions,
|
|
13062
|
+
logger
|
|
13063
|
+
});
|
|
13064
|
+
}
|
|
13065
|
+
for (const [canonicalEvent, definitions] of Object.entries(toolOverrideHooks ?? {})) {
|
|
13066
|
+
if (!HERMESAGENT_CANONICAL_EVENTS.has(canonicalEvent)) continue;
|
|
13067
|
+
const nativeEvent = CANONICAL_TO_HERMESAGENT_EVENT_NAMES[canonicalEvent];
|
|
13068
|
+
if (nativeEvent) setHermesHookEntries({
|
|
13069
|
+
result,
|
|
13070
|
+
event: nativeEvent,
|
|
13071
|
+
sourceEvent: canonicalEvent,
|
|
13072
|
+
definitions,
|
|
13073
|
+
logger
|
|
13074
|
+
});
|
|
13075
|
+
}
|
|
13076
|
+
for (const [nativeEvent, definitions] of Object.entries(toolOverrideHooks ?? {})) {
|
|
13077
|
+
if (HERMESAGENT_CANONICAL_EVENTS.has(nativeEvent)) continue;
|
|
13078
|
+
if (!HERMESAGENT_NATIVE_EVENTS.has(nativeEvent)) logger?.warn(`Hermes hook event "${nativeEvent}" is not documented by Hermes Agent v0.19.0; preserving it for forward compatibility.`);
|
|
13079
|
+
setHermesHookEntries({
|
|
13080
|
+
result,
|
|
13081
|
+
event: nativeEvent,
|
|
13082
|
+
definitions,
|
|
13083
|
+
logger
|
|
13084
|
+
});
|
|
12946
13085
|
}
|
|
12947
13086
|
return result;
|
|
12948
13087
|
}
|
|
@@ -12950,16 +13089,15 @@ function canonicalToHermesHooks({ config, toolOverrideHooks, logger }) {
|
|
|
12950
13089
|
* Reverse {@link canonicalToHermesHooks}: parse Hermes's native
|
|
12951
13090
|
* `hooks: { <event>: [...] }` map back into a canonical event → definition[]
|
|
12952
13091
|
* record. Native events with no canonical equivalent (`pre_verify`,
|
|
12953
|
-
* `transform_tool_result`, ...)
|
|
12954
|
-
*
|
|
13092
|
+
* `transform_tool_result`, ...) retain their native names so
|
|
13093
|
+
* {@link buildImportedHooksConfig} places them under `hermesagent.hooks`.
|
|
12955
13094
|
*/
|
|
12956
13095
|
function hermesHooksToCanonical(hooks) {
|
|
12957
13096
|
const canonical = {};
|
|
12958
13097
|
if (hooks === null || typeof hooks !== "object" || Array.isArray(hooks)) return canonical;
|
|
12959
13098
|
for (const [nativeEvent, entries] of Object.entries(hooks)) {
|
|
12960
13099
|
if (PROTOTYPE_POLLUTION_KEYS.has(nativeEvent) || !Array.isArray(entries)) continue;
|
|
12961
|
-
const
|
|
12962
|
-
if (!canonicalEvent) continue;
|
|
13100
|
+
const rulesyncEvent = HERMESAGENT_TO_CANONICAL_EVENT_NAMES[nativeEvent] ?? nativeEvent;
|
|
12963
13101
|
const defs = [];
|
|
12964
13102
|
for (const raw of entries) {
|
|
12965
13103
|
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) continue;
|
|
@@ -12969,11 +13107,11 @@ function hermesHooksToCanonical(hooks) {
|
|
|
12969
13107
|
type: "command",
|
|
12970
13108
|
command: entry.command
|
|
12971
13109
|
};
|
|
12972
|
-
if (typeof entry.matcher === "string" && entry.matcher !== "") def.matcher = entry.matcher;
|
|
13110
|
+
if (HERMESAGENT_MATCHER_EVENTS.has(nativeEvent) && typeof entry.matcher === "string" && entry.matcher !== "") def.matcher = entry.matcher;
|
|
12973
13111
|
if (typeof entry.timeout === "number") def.timeout = entry.timeout;
|
|
12974
13112
|
defs.push(def);
|
|
12975
13113
|
}
|
|
12976
|
-
if (defs.length > 0) canonical[
|
|
13114
|
+
if (defs.length > 0) canonical[rulesyncEvent] = defs;
|
|
12977
13115
|
}
|
|
12978
13116
|
return canonical;
|
|
12979
13117
|
}
|
|
@@ -15030,7 +15168,8 @@ const toolHooksFactories = /* @__PURE__ */ new Map([
|
|
|
15030
15168
|
},
|
|
15031
15169
|
supportedEvents: HERMESAGENT_HOOK_EVENTS,
|
|
15032
15170
|
supportedHookTypes: ["command"],
|
|
15033
|
-
supportsMatcher: true
|
|
15171
|
+
supportsMatcher: true,
|
|
15172
|
+
passthroughOverrideEvents: true
|
|
15034
15173
|
}],
|
|
15035
15174
|
["kimi-code", {
|
|
15036
15175
|
class: KimiCodeHooks,
|
|
@@ -18767,12 +18906,51 @@ function resolveHermesTimeout(config) {
|
|
|
18767
18906
|
* canonical `McpServerSchema` is a `looseObject`), so this serves export and
|
|
18768
18907
|
* import alike. See the Hermes mcp-config-reference.
|
|
18769
18908
|
*/
|
|
18909
|
+
function copyHermesOauth(source) {
|
|
18910
|
+
if (!isRecord(source)) return;
|
|
18911
|
+
const oauth = {};
|
|
18912
|
+
for (const key of [
|
|
18913
|
+
"redirect_uri",
|
|
18914
|
+
"redirect_host",
|
|
18915
|
+
"client_id",
|
|
18916
|
+
"client_secret"
|
|
18917
|
+
]) if (typeof source[key] === "string") oauth[key] = source[key];
|
|
18918
|
+
if (typeof source.redirect_port === "number") oauth.redirect_port = source.redirect_port;
|
|
18919
|
+
if (isStringArray$1(source.scopes)) oauth.scopes = source.scopes;
|
|
18920
|
+
return Object.keys(oauth).length > 0 ? oauth : void 0;
|
|
18921
|
+
}
|
|
18770
18922
|
function copyHermesAdvancedFields(source, target) {
|
|
18771
|
-
|
|
18772
|
-
if (typeof source.
|
|
18773
|
-
|
|
18774
|
-
|
|
18775
|
-
|
|
18923
|
+
let copied = false;
|
|
18924
|
+
if (typeof source.auth === "string") {
|
|
18925
|
+
target.auth = source.auth;
|
|
18926
|
+
copied = true;
|
|
18927
|
+
}
|
|
18928
|
+
if (typeof source.client_cert === "string" || isStringArray$1(source.client_cert)) {
|
|
18929
|
+
target.client_cert = source.client_cert;
|
|
18930
|
+
copied = true;
|
|
18931
|
+
}
|
|
18932
|
+
if (typeof source.client_key === "string") {
|
|
18933
|
+
target.client_key = source.client_key;
|
|
18934
|
+
copied = true;
|
|
18935
|
+
}
|
|
18936
|
+
if (typeof source.connect_timeout === "number") {
|
|
18937
|
+
target.connect_timeout = source.connect_timeout;
|
|
18938
|
+
copied = true;
|
|
18939
|
+
}
|
|
18940
|
+
if (typeof source.supports_parallel_tool_calls === "boolean") {
|
|
18941
|
+
target.supports_parallel_tool_calls = source.supports_parallel_tool_calls;
|
|
18942
|
+
copied = true;
|
|
18943
|
+
}
|
|
18944
|
+
const oauth = copyHermesOauth(source.oauth);
|
|
18945
|
+
if (oauth) {
|
|
18946
|
+
target.oauth = oauth;
|
|
18947
|
+
copied = true;
|
|
18948
|
+
}
|
|
18949
|
+
for (const key of ["idle_timeout_seconds", "max_lifetime_seconds"]) if (typeof source[key] === "number") {
|
|
18950
|
+
target[key] = source[key];
|
|
18951
|
+
copied = true;
|
|
18952
|
+
}
|
|
18953
|
+
return copied;
|
|
18776
18954
|
}
|
|
18777
18955
|
/**
|
|
18778
18956
|
* Builds Hermes's per-server `tools` block from a canonical server config. The
|
|
@@ -18874,6 +19052,7 @@ function mergeHermesMcpServers(config, mcpServers) {
|
|
|
18874
19052
|
*/
|
|
18875
19053
|
function convertFromHermesFormat(mcpServers) {
|
|
18876
19054
|
const result = {};
|
|
19055
|
+
const hermesOverrides = {};
|
|
18877
19056
|
for (const [name, config] of Object.entries(mcpServers)) {
|
|
18878
19057
|
if (PROTOTYPE_POLLUTION_KEYS.has(name) || !isRecord(config)) continue;
|
|
18879
19058
|
const server = {};
|
|
@@ -18884,11 +19063,15 @@ function convertFromHermesFormat(mcpServers) {
|
|
|
18884
19063
|
if (isPlainObject$1(config.headers)) server.headers = omitPrototypePollutionKeys(config.headers);
|
|
18885
19064
|
if (config.enabled === false) server.disabled = true;
|
|
18886
19065
|
if (typeof config.timeout === "number") server.networkTimeout = config.timeout;
|
|
18887
|
-
copyHermesAdvancedFields(config, server);
|
|
18888
19066
|
if (isRecord(config.tools)) applyHermesToolsBlock(config.tools, server);
|
|
18889
19067
|
result[name] = server;
|
|
19068
|
+
const hermesServer = { ...server };
|
|
19069
|
+
if (copyHermesAdvancedFields(config, hermesServer)) hermesOverrides[name] = hermesServer;
|
|
18890
19070
|
}
|
|
18891
|
-
return
|
|
19071
|
+
return {
|
|
19072
|
+
mcpServers: result,
|
|
19073
|
+
hermesOverrides
|
|
19074
|
+
};
|
|
18892
19075
|
}
|
|
18893
19076
|
/**
|
|
18894
19077
|
* Hermes Agent MCP servers.
|
|
@@ -18973,8 +19156,11 @@ var HermesagentMcp = class HermesagentMcp extends ToolMcp {
|
|
|
18973
19156
|
});
|
|
18974
19157
|
}
|
|
18975
19158
|
toRulesyncMcp() {
|
|
18976
|
-
const servers = convertFromHermesFormat(isRecord(this.config.mcp_servers) ? this.config.mcp_servers : {});
|
|
18977
|
-
return this.toRulesyncMcpDefault({ fileContent: JSON.stringify({
|
|
19159
|
+
const { mcpServers: servers, hermesOverrides } = convertFromHermesFormat(isRecord(this.config.mcp_servers) ? this.config.mcp_servers : {});
|
|
19160
|
+
return this.toRulesyncMcpDefault({ fileContent: JSON.stringify({
|
|
19161
|
+
mcpServers: servers,
|
|
19162
|
+
...Object.keys(hermesOverrides).length > 0 && { hermesagent: { mcpServers: hermesOverrides } }
|
|
19163
|
+
}, null, 2) });
|
|
18978
19164
|
}
|
|
18979
19165
|
validate() {
|
|
18980
19166
|
return {
|
|
@@ -20984,8 +21170,8 @@ const toolMcpFactories = /* @__PURE__ */ new Map([
|
|
|
20984
21170
|
meta: {
|
|
20985
21171
|
supportsProject: false,
|
|
20986
21172
|
supportsGlobal: true,
|
|
20987
|
-
supportsEnabledTools:
|
|
20988
|
-
supportsDisabledTools:
|
|
21173
|
+
supportsEnabledTools: true,
|
|
21174
|
+
supportsDisabledTools: true
|
|
20989
21175
|
}
|
|
20990
21176
|
}],
|
|
20991
21177
|
["kimi-code", {
|
|
@@ -24999,6 +25185,59 @@ function deriveGrokPermissionMode(config) {
|
|
|
24999
25185
|
function patternsByAction(category, action) {
|
|
25000
25186
|
return Object.entries(category ?? {}).filter(([, value]) => value === action).map(([pattern]) => pattern);
|
|
25001
25187
|
}
|
|
25188
|
+
function clonePermissionBlock(permission) {
|
|
25189
|
+
return Object.fromEntries(Object.entries(permission).map(([category, rules]) => [category, { ...rules }]));
|
|
25190
|
+
}
|
|
25191
|
+
function deleteRulesByAction(rules, action) {
|
|
25192
|
+
for (const [pattern, currentAction] of Object.entries(rules)) if (currentAction === action) delete rules[pattern];
|
|
25193
|
+
}
|
|
25194
|
+
function ensureCategory(permission, category) {
|
|
25195
|
+
return permission[category] ??= {};
|
|
25196
|
+
}
|
|
25197
|
+
function removeEmptyCategories(permission) {
|
|
25198
|
+
for (const [category, rules] of Object.entries(permission)) if (Object.keys(rules).length === 0) delete permission[category];
|
|
25199
|
+
}
|
|
25200
|
+
function reconcileCommandAllowlist({ permission, commandAllowlist }) {
|
|
25201
|
+
const nativeAllows = new Set(commandAllowlist);
|
|
25202
|
+
const existingAllowCategories = /* @__PURE__ */ new Map();
|
|
25203
|
+
for (const [category, rules] of Object.entries(permission)) for (const [pattern, action] of Object.entries(rules)) {
|
|
25204
|
+
if (action !== "allow") continue;
|
|
25205
|
+
existingAllowCategories.set(pattern, category);
|
|
25206
|
+
if (!nativeAllows.has(pattern)) delete rules[pattern];
|
|
25207
|
+
}
|
|
25208
|
+
for (const pattern of nativeAllows) {
|
|
25209
|
+
const existingCategory = existingAllowCategories.get(pattern);
|
|
25210
|
+
if (existingCategory) ensureCategory(permission, existingCategory)[pattern] = "allow";
|
|
25211
|
+
else ensureCategory(permission, "bash")[pattern] = "allow";
|
|
25212
|
+
}
|
|
25213
|
+
}
|
|
25214
|
+
function reconcileNativeDenies({ permission, category, patterns }) {
|
|
25215
|
+
const rules = ensureCategory(permission, category);
|
|
25216
|
+
deleteRulesByAction(rules, "deny");
|
|
25217
|
+
for (const pattern of patterns) rules[pattern] = "deny";
|
|
25218
|
+
}
|
|
25219
|
+
function withoutKey(record, key) {
|
|
25220
|
+
return Object.fromEntries(Object.entries(record).filter(([entryKey]) => entryKey !== key));
|
|
25221
|
+
}
|
|
25222
|
+
function buildHermesOverride(config, provenance) {
|
|
25223
|
+
const base = isRecord(provenance.hermes) ? { ...provenance.hermes } : {};
|
|
25224
|
+
const approvalsOverride = withoutKey(isRecord(config.approvals) ? config.approvals : {}, "deny");
|
|
25225
|
+
if (Object.keys(approvalsOverride).length > 0) base.approvals = approvalsOverride;
|
|
25226
|
+
else delete base.approvals;
|
|
25227
|
+
const security = isRecord(config.security) ? { ...config.security } : {};
|
|
25228
|
+
const blocklist = isRecord(security.website_blocklist) ? { ...security.website_blocklist } : void 0;
|
|
25229
|
+
if (blocklist?.enabled === true) {
|
|
25230
|
+
delete blocklist.domains;
|
|
25231
|
+
delete blocklist.enabled;
|
|
25232
|
+
}
|
|
25233
|
+
if (blocklist && Object.keys(blocklist).length > 0) security.website_blocklist = blocklist;
|
|
25234
|
+
else delete security.website_blocklist;
|
|
25235
|
+
if (Object.keys(security).length > 0) base.security = security;
|
|
25236
|
+
else delete base.security;
|
|
25237
|
+
for (const key of ["skills", "memory"]) if (isRecord(config[key])) base[key] = config[key];
|
|
25238
|
+
else delete base[key];
|
|
25239
|
+
return base;
|
|
25240
|
+
}
|
|
25002
25241
|
var HermesagentPermissions = class HermesagentPermissions extends ToolPermissions {
|
|
25003
25242
|
static getSettablePaths() {
|
|
25004
25243
|
return {
|
|
@@ -25055,12 +25294,40 @@ var HermesagentPermissions = class HermesagentPermissions extends ToolPermission
|
|
|
25055
25294
|
format: "yaml",
|
|
25056
25295
|
fileContent: this.getFileContent()
|
|
25057
25296
|
});
|
|
25058
|
-
const
|
|
25297
|
+
const permissionsRoot = isRecord(config.permissions) ? config.permissions : {};
|
|
25298
|
+
const parsedProvenance = RulesyncPermissionsFileSchema.safeParse(permissionsRoot.rulesync);
|
|
25299
|
+
const provenance = parsedProvenance.success ? parsedProvenance.data : { permission: {} };
|
|
25300
|
+
const permission = clonePermissionBlock(provenance.permission);
|
|
25301
|
+
reconcileCommandAllowlist({
|
|
25302
|
+
permission,
|
|
25303
|
+
commandAllowlist: isStringArray$1(config.command_allowlist) ? config.command_allowlist : []
|
|
25304
|
+
});
|
|
25305
|
+
const approvals = isRecord(config.approvals) ? config.approvals : {};
|
|
25306
|
+
reconcileNativeDenies({
|
|
25307
|
+
permission,
|
|
25308
|
+
category: "bash",
|
|
25309
|
+
patterns: isStringArray$1(approvals.deny) ? approvals.deny : []
|
|
25310
|
+
});
|
|
25311
|
+
const security = isRecord(config.security) ? config.security : {};
|
|
25312
|
+
const websiteBlocklist = isRecord(security.website_blocklist) ? security.website_blocklist : {};
|
|
25313
|
+
reconcileNativeDenies({
|
|
25314
|
+
permission,
|
|
25315
|
+
category: "webfetch",
|
|
25316
|
+
patterns: websiteBlocklist.enabled === true && isStringArray$1(websiteBlocklist.domains) ? websiteBlocklist.domains : []
|
|
25317
|
+
});
|
|
25318
|
+
removeEmptyCategories(permission);
|
|
25319
|
+
const { permission: _permission, hermes: _hermes, ...otherProvenance } = provenance;
|
|
25320
|
+
const hermes = buildHermesOverride(config, provenance);
|
|
25321
|
+
const imported = {
|
|
25322
|
+
...otherProvenance,
|
|
25323
|
+
permission,
|
|
25324
|
+
...Object.keys(hermes).length > 0 && { hermes }
|
|
25325
|
+
};
|
|
25059
25326
|
return new RulesyncPermissions({
|
|
25060
25327
|
outputRoot: this.outputRoot,
|
|
25061
25328
|
relativeDirPath: RULESYNC_RELATIVE_DIR_PATH,
|
|
25062
25329
|
relativeFilePath: RULESYNC_PERMISSIONS_FILE_NAME,
|
|
25063
|
-
fileContent: JSON.stringify(
|
|
25330
|
+
fileContent: JSON.stringify(imported, null, 2)
|
|
25064
25331
|
});
|
|
25065
25332
|
}
|
|
25066
25333
|
static fromRulesyncPermissions({ outputRoot, rulesyncPermissions }) {
|
|
@@ -35803,7 +36070,7 @@ import json
|
|
|
35803
36070
|
from pathlib import Path
|
|
35804
36071
|
|
|
35805
36072
|
|
|
35806
|
-
SUBAGENTS_DIR = Path.
|
|
36073
|
+
SUBAGENTS_DIR = Path(__file__).resolve().parents[2] / "rulesync" / "subagents"
|
|
35807
36074
|
|
|
35808
36075
|
|
|
35809
36076
|
def _load_subagents():
|
|
@@ -35912,12 +36179,12 @@ var HermesagentSubagent = class HermesagentSubagent extends ToolSubagent {
|
|
|
35912
36179
|
validate: false
|
|
35913
36180
|
});
|
|
35914
36181
|
}
|
|
35915
|
-
static async fromFile({ global = false, outputRoot = process.cwd(), relativeFilePath, validate = true }) {
|
|
36182
|
+
static async fromFile({ global = false, outputRoot = process.cwd(), relativeDirPath, relativeFilePath, validate = true }) {
|
|
35916
36183
|
return new HermesagentSubagent({
|
|
35917
|
-
fileContent: await readFile(join(outputRoot, relativeFilePath), "utf8"),
|
|
36184
|
+
fileContent: await readFile(join(outputRoot, relativeDirPath ?? HERMESAGENT_RULESYNC_SUBAGENTS_DIR_PATH, relativeFilePath), "utf8"),
|
|
35918
36185
|
global,
|
|
35919
36186
|
outputRoot,
|
|
35920
|
-
relativeDirPath: dirname(relativeFilePath),
|
|
36187
|
+
relativeDirPath: relativeDirPath ?? dirname(relativeFilePath),
|
|
35921
36188
|
relativeFilePath: basename(relativeFilePath),
|
|
35922
36189
|
validate
|
|
35923
36190
|
});
|
|
@@ -35926,7 +36193,7 @@ var HermesagentSubagent = class HermesagentSubagent extends ToolSubagent {
|
|
|
35926
36193
|
const targets = rulesyncSubagent.getFrontmatter().targets;
|
|
35927
36194
|
return !targets || targets.includes("*") || targets.includes("hermesagent");
|
|
35928
36195
|
}
|
|
35929
|
-
static fromRulesyncSubagents({ rulesyncSubagents, outputRoot }) {
|
|
36196
|
+
static fromRulesyncSubagents({ rulesyncSubagents, outputRoot, global = false }) {
|
|
35930
36197
|
return [
|
|
35931
36198
|
...rulesyncSubagents.map((rulesyncSubagent) => HermesagentSubagent.fromRulesyncSubagent({
|
|
35932
36199
|
relativeDirPath: HERMESAGENT_RULESYNC_SUBAGENTS_DIR_PATH,
|
|
@@ -35945,12 +36212,12 @@ var HermesagentSubagent = class HermesagentSubagent extends ToolSubagent {
|
|
|
35945
36212
|
fileContent: "",
|
|
35946
36213
|
outputRoot
|
|
35947
36214
|
}),
|
|
35948
|
-
new HermesagentSubagent({
|
|
36215
|
+
...global ? [new HermesagentSubagent({
|
|
35949
36216
|
relativeDirPath: HERMESAGENT_GLOBAL_DIR,
|
|
35950
36217
|
relativeFilePath: basename(HERMESAGENT_CONFIG_FILE_PATH),
|
|
35951
36218
|
fileContent: "",
|
|
35952
36219
|
outputRoot
|
|
35953
|
-
})
|
|
36220
|
+
})] : []
|
|
35954
36221
|
];
|
|
35955
36222
|
}
|
|
35956
36223
|
static fromRulesyncSubagent({ rulesyncSubagent, outputRoot }) {
|
|
@@ -35971,11 +36238,11 @@ var HermesagentSubagent = class HermesagentSubagent extends ToolSubagent {
|
|
|
35971
36238
|
* shared `~/.hermes/config.yaml` (enabling the `rulesync-subagents` plugin),
|
|
35972
36239
|
* so the write must be declared for the shared-file order derivation.
|
|
35973
36240
|
*/
|
|
35974
|
-
static getExtraSharedWritePaths() {
|
|
35975
|
-
return [{
|
|
36241
|
+
static getExtraSharedWritePaths({ global = false } = {}) {
|
|
36242
|
+
return global ? [{
|
|
35976
36243
|
relativeDirPath: HERMESAGENT_GLOBAL_DIR,
|
|
35977
36244
|
relativeFilePath: basename(HERMESAGENT_CONFIG_FILE_PATH)
|
|
35978
|
-
}];
|
|
36245
|
+
}] : [];
|
|
35979
36246
|
}
|
|
35980
36247
|
static getSettablePathsForRulesyncSubagent(rulesyncSubagent) {
|
|
35981
36248
|
return [join(HERMESAGENT_RULESYNC_SUBAGENTS_DIR_PATH, `${subagentSlug(rulesyncSubagent.getRelativePathFromCwd())}.json`)];
|
|
@@ -35985,13 +36252,13 @@ var HermesagentSubagent = class HermesagentSubagent extends ToolSubagent {
|
|
|
35985
36252
|
const json = JSON.parse(this.getFileContent());
|
|
35986
36253
|
return new RulesyncSubagent({
|
|
35987
36254
|
relativeDirPath: RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH,
|
|
35988
|
-
relativeFilePath:
|
|
36255
|
+
relativeFilePath: `${slug}.md`,
|
|
35989
36256
|
body: json.prompt ?? "",
|
|
35990
36257
|
frontmatter: {
|
|
35991
36258
|
name: json.name ?? slug,
|
|
35992
36259
|
description: json.description
|
|
35993
36260
|
},
|
|
35994
|
-
outputRoot: this.outputRoot
|
|
36261
|
+
outputRoot: this.global ? this.outputRoot : process.cwd()
|
|
35995
36262
|
});
|
|
35996
36263
|
}
|
|
35997
36264
|
validate() {
|
|
@@ -43641,6 +43908,74 @@ function buildChecksStrategy(ctx) {
|
|
|
43641
43908
|
};
|
|
43642
43909
|
}
|
|
43643
43910
|
//#endregion
|
|
43911
|
+
//#region src/features/shared/hermes-project-plugin-activation.ts
|
|
43912
|
+
function mergeEnabledPlugins({ existingContent, filePath, pluginNames }) {
|
|
43913
|
+
const config = parseSharedConfig({
|
|
43914
|
+
format: "yaml",
|
|
43915
|
+
fileContent: existingContent,
|
|
43916
|
+
filePath,
|
|
43917
|
+
invalidRootPolicy: "error"
|
|
43918
|
+
});
|
|
43919
|
+
const plugins = isPlainObject$1(config.plugins) ? config.plugins : {};
|
|
43920
|
+
const disabled = Array.isArray(plugins.disabled) ? plugins.disabled.filter((value) => typeof value === "string") : [];
|
|
43921
|
+
const conflicts = pluginNames.filter((pluginName) => disabled.includes(pluginName));
|
|
43922
|
+
if (conflicts.length > 0) throw new Error(`Cannot activate Hermes project plugin(s) ${conflicts.join(", ")} because ${filePath} explicitly lists them in plugins.disabled. Remove the conflicting entries or exclude those RuleSync features.`);
|
|
43923
|
+
const enabled = Array.isArray(plugins.enabled) ? plugins.enabled : [];
|
|
43924
|
+
return stringifySharedConfig({
|
|
43925
|
+
format: "yaml",
|
|
43926
|
+
document: {
|
|
43927
|
+
...config,
|
|
43928
|
+
plugins: {
|
|
43929
|
+
...plugins,
|
|
43930
|
+
enabled: Array.from(/* @__PURE__ */ new Set([...enabled, ...pluginNames]))
|
|
43931
|
+
}
|
|
43932
|
+
}
|
|
43933
|
+
});
|
|
43934
|
+
}
|
|
43935
|
+
async function writeActivationFile({ filePath, relativePath, expectedContent, dryRun, logger }) {
|
|
43936
|
+
const existingContent = await readFileContentOrNull(filePath);
|
|
43937
|
+
const normalizedExpected = addTrailingNewline(expectedContent);
|
|
43938
|
+
if (fileContentsEquivalent({
|
|
43939
|
+
filePath,
|
|
43940
|
+
expected: normalizedExpected,
|
|
43941
|
+
existing: existingContent
|
|
43942
|
+
})) return false;
|
|
43943
|
+
if (dryRun) logger.info(`[DRY RUN] Would write: ${filePath}`);
|
|
43944
|
+
else await writeFileContent(filePath, normalizedExpected);
|
|
43945
|
+
logger.debug(`Hermes project-plugin activation requires ${relativePath}`);
|
|
43946
|
+
return true;
|
|
43947
|
+
}
|
|
43948
|
+
async function activateHermesProjectPlugins({ pluginNames, dryRun, logger }) {
|
|
43949
|
+
if (pluginNames.length === 0) return {
|
|
43950
|
+
count: 0,
|
|
43951
|
+
paths: [],
|
|
43952
|
+
hasDiff: false
|
|
43953
|
+
};
|
|
43954
|
+
const configuredHermesHome = process.env.HERMES_HOME?.trim();
|
|
43955
|
+
const configRoot = configuredHermesHome ? resolve(configuredHermesHome) : getHomeDirectory();
|
|
43956
|
+
const relativeConfigPath = configuredHermesHome ? HERMESAGENT_CONFIG_FILE_NAME : HERMESAGENT_CONFIG_FILE_PATH;
|
|
43957
|
+
const configPath = join(configRoot, relativeConfigPath);
|
|
43958
|
+
const expectedConfig = mergeEnabledPlugins({
|
|
43959
|
+
existingContent: await readFileContentOrNull(configPath) ?? "",
|
|
43960
|
+
filePath: configPath,
|
|
43961
|
+
pluginNames
|
|
43962
|
+
});
|
|
43963
|
+
const paths = [];
|
|
43964
|
+
logger.warn(`Hermes project plugins require explicit trust. Run Hermes from this trusted repository with ${HERMESAGENT_PROJECT_PLUGINS_ENV_VAR}=true. RuleSync does not persist this global setting.`);
|
|
43965
|
+
if (await writeActivationFile({
|
|
43966
|
+
filePath: configPath,
|
|
43967
|
+
relativePath: relativeConfigPath,
|
|
43968
|
+
expectedContent: expectedConfig,
|
|
43969
|
+
dryRun,
|
|
43970
|
+
logger
|
|
43971
|
+
})) paths.push(relativeConfigPath);
|
|
43972
|
+
return {
|
|
43973
|
+
count: paths.length,
|
|
43974
|
+
paths,
|
|
43975
|
+
hasDiff: paths.length > 0
|
|
43976
|
+
};
|
|
43977
|
+
}
|
|
43978
|
+
//#endregion
|
|
43644
43979
|
//#region src/types/processor-registry.ts
|
|
43645
43980
|
const PROCESSOR_REGISTRY = [
|
|
43646
43981
|
{
|
|
@@ -44102,6 +44437,41 @@ async function warnSkillSubagentNameCollisions(params) {
|
|
|
44102
44437
|
for (const name of skillNames) if (subagentNames.has(name)) logger.warn(`Skill "${name}" and subagent "${name}" both target '${toolTarget}' and write the same path '${join(subagentsDirPath, name)}'; the later generation step overwrites the other's output. Rename one of them or narrow their targets.`);
|
|
44103
44438
|
}
|
|
44104
44439
|
}
|
|
44440
|
+
async function collectHermesProjectPluginNames({ config, resultsById }) {
|
|
44441
|
+
if (config.getGlobal() || !config.getTargets().includes("hermesagent")) return [];
|
|
44442
|
+
const outputRoots = config.getOutputRoots("hermesagent");
|
|
44443
|
+
const enabledFeatures = config.getFeatures("hermesagent");
|
|
44444
|
+
const descriptors = [
|
|
44445
|
+
{
|
|
44446
|
+
feature: "ignore",
|
|
44447
|
+
pluginName: "rulesync-ignore",
|
|
44448
|
+
manifestPath: HERMESAGENT_IGNORE_PLUGIN_MANIFEST_PATH
|
|
44449
|
+
},
|
|
44450
|
+
{
|
|
44451
|
+
feature: "subagents",
|
|
44452
|
+
pluginName: "rulesync-subagents",
|
|
44453
|
+
manifestPath: HERMESAGENT_RULESYNC_SUBAGENTS_PLUGIN_MANIFEST_PATH
|
|
44454
|
+
},
|
|
44455
|
+
{
|
|
44456
|
+
feature: "checks",
|
|
44457
|
+
pluginName: "rulesync-checks",
|
|
44458
|
+
manifestPath: HERMESAGENT_CHECKS_PLUGIN_MANIFEST_PATH
|
|
44459
|
+
}
|
|
44460
|
+
];
|
|
44461
|
+
const pluginNames = [];
|
|
44462
|
+
for (const descriptor of descriptors) {
|
|
44463
|
+
if (!enabledFeatures.includes(descriptor.feature)) continue;
|
|
44464
|
+
const relativeManifestPath = toPosixPath(descriptor.manifestPath);
|
|
44465
|
+
const willWriteManifest = resultsById.get(descriptor.feature)?.paths.some((generatedPath) => toPosixPath(generatedPath) === relativeManifestPath) ?? false;
|
|
44466
|
+
let manifestExists = false;
|
|
44467
|
+
for (const outputRoot of outputRoots) if (await fileExists(join(outputRoot, descriptor.manifestPath))) {
|
|
44468
|
+
manifestExists = true;
|
|
44469
|
+
break;
|
|
44470
|
+
}
|
|
44471
|
+
if (willWriteManifest || manifestExists) pluginNames.push(descriptor.pluginName);
|
|
44472
|
+
}
|
|
44473
|
+
return pluginNames;
|
|
44474
|
+
}
|
|
44105
44475
|
/**
|
|
44106
44476
|
* Generate configuration files for AI tools.
|
|
44107
44477
|
* @throws Error if generation fails
|
|
@@ -44165,13 +44535,21 @@ async function generate(params) {
|
|
|
44165
44535
|
})));
|
|
44166
44536
|
const resultsById = /* @__PURE__ */ new Map();
|
|
44167
44537
|
for (const step of orderedSteps) resultsById.set(step.id, await step.run());
|
|
44538
|
+
const activationResult = await activateHermesProjectPlugins({
|
|
44539
|
+
pluginNames: await collectHermesProjectPluginNames({
|
|
44540
|
+
config,
|
|
44541
|
+
resultsById
|
|
44542
|
+
}),
|
|
44543
|
+
dryRun: config.isPreviewMode(),
|
|
44544
|
+
logger
|
|
44545
|
+
});
|
|
44168
44546
|
if (!skillsResult) throw new Error("Skills generation step did not run.");
|
|
44169
44547
|
const get = (id) => {
|
|
44170
44548
|
const result = resultsById.get(id);
|
|
44171
44549
|
if (!result) throw new Error(`Missing generation result for step '${id}'.`);
|
|
44172
44550
|
return result;
|
|
44173
44551
|
};
|
|
44174
|
-
const hasDiff = orderedSteps.some((step) => get(step.id).hasDiff);
|
|
44552
|
+
const hasDiff = activationResult.hasDiff || orderedSteps.some((step) => get(step.id).hasDiff);
|
|
44175
44553
|
return {
|
|
44176
44554
|
rulesCount: get("rules").count,
|
|
44177
44555
|
rulesPaths: get("rules").paths,
|
|
@@ -44191,6 +44569,8 @@ async function generate(params) {
|
|
|
44191
44569
|
permissionsPaths: get("permissions").paths,
|
|
44192
44570
|
checksCount: get("checks").count,
|
|
44193
44571
|
checksPaths: get("checks").paths,
|
|
44572
|
+
activationCount: activationResult.count,
|
|
44573
|
+
activationPaths: activationResult.paths,
|
|
44194
44574
|
skills: skillsResult.skills,
|
|
44195
44575
|
hasDiff
|
|
44196
44576
|
};
|
|
@@ -44972,4 +45352,4 @@ async function importChecksCore(params) {
|
|
|
44972
45352
|
//#endregion
|
|
44973
45353
|
export { assertDirectoryIfExists as $, RULESYNC_SOURCES_LOCK_RELATIVE_FILE_PATH as $t, RulesyncMcp as A, RULESYNC_CHECKS_RELATIVE_DIR_PATH as At, stringifyFrontmatter as B, RULESYNC_LOCAL_CONFIG_RELATIVE_FILE_PATH as Bt, RulesyncSubagent as C, ALL_TOOL_TARGETS as Ct, RulesyncRule as D, MAX_FILE_SIZE as Dt, RulesyncSkillFrontmatterSchema as E, ToolTargetSchema as Et, parseJsonc as F, RULESYNC_CURATED_SKILLS_RELATIVE_DIR_PATH as Ft, SourceEntrySchema as G, RULESYNC_NPM_SOURCES_LOCK_RELATIVE_FILE_PATH as Gt, SKILL_FILE_NAME as H, RULESYNC_MCP_LEGACY_FILE_NAME as Ht, RulesyncCommand as I, RULESYNC_HOOKS_FILE_NAME as It, JsonLogger as J, RULESYNC_PERMISSIONS_RELATIVE_FILE_PATH as Jt, findControlCharacter as K, RULESYNC_PERMISSIONS_FILE_NAME as Kt, RulesyncCommandFrontmatterSchema as L, RULESYNC_HOOKS_LEGACY_FILE_NAME as Lt, RulesyncHooks as M, RULESYNC_CONFIG_RELATIVE_FILE_PATH as Mt, getRulesyncSourceCandidates as N, RULESYNC_CONFIG_SCHEMA_URL as Nt, RulesyncRuleFrontmatterSchema as O, RULESYNC_AIIGNORE_FILE_NAME as Ot, resolveRulesyncSourceWritePath as P, RULESYNC_CURATED_RULES_RELATIVE_DIR_PATH as Pt, ErrorCodes as Q, RULESYNC_SKILLS_RELATIVE_DIR_PATH as Qt, RulesyncCheck as R, RULESYNC_HOOKS_RELATIVE_FILE_PATH as Rt, getLocalSkillDirNames as S, writeFileContent as St, RulesyncSkill as T, PACKAGING_TOOL_TARGETS as Tt, ConfigResolver as U, RULESYNC_MCP_RELATIVE_FILE_PATH as Ut, loadYaml as V, RULESYNC_MCP_FILE_NAME as Vt, ConfigFileSchema as W, RULESYNC_MCP_SCHEMA_URL as Wt, warnOnConflictingFlags as X, RULESYNC_RELATIVE_DIR_PATH as Xt, fallbackLogger as Y, RULESYNC_PERMISSIONS_SCHEMA_URL as Yt, CLIError as Z, RULESYNC_RULES_RELATIVE_DIR_PATH as Zt, CLAUDECODE_LOCAL_RULE_FILE_NAME as _, removeFileStrict as _t, convertFromTool as a, ensureDir as at, CLAUDECODE_SKILLS_DIR_PATH as b, runWithDirectoryRollback as bt, SubagentsProcessor as c, getFileSize as ct, IgnoreProcessor as d, listDirectoryFiles as dt, RULESYNC_SUBAGENTS_RELATIVE_DIR_PATH as en, assertTreeContainsNoSymlinks as et, HooksProcessor as f, readFileContent as ft, CLAUDECODE_DIR as g, removeFile as gt, CODEXCLI_DIR as h, removeDirectoryStrict as ht, getProcessorRegistryEntry as i, directoryExists as it, RulesyncIgnore as j, RULESYNC_COMMANDS_RELATIVE_DIR_PATH as jt, RulesyncPermissions as k, RULESYNC_AIIGNORE_RELATIVE_FILE_PATH as kt, SkillsProcessor as l, getHomeDirectory as lt, CODEXCLI_BASH_RULES_FILE_NAME as m, removeDirectory as mt, checkRulesyncDirExists as n, ALL_FEATURES_WITH_WILDCARD as nn, checkPathTraversal as nt, isPackagingToolTarget as o, fileExists as ot, CommandsProcessor as p, readFileContentOrNull as pt, ConsoleLogger as q, RULESYNC_PERMISSIONS_LEGACY_FILE_NAME as qt, generate as r, formatError as rn, createTempDirectory as rt, RulesProcessor as s, findFilesByGlobs as st, importFromTool as t, ALL_FEATURES as tn, assertWritablePathInsideRoot as tt, McpProcessor as u, isSymlink as ut, CLAUDECODE_MEMORIES_DIR_NAME as v, removeTempDirectory as vt, RulesyncSubagentFrontmatterSchema as w, ALL_TOOL_TARGETS_WITH_WILDCARD as wt, ChecksProcessor as x, toPosixPath as xt, CLAUDECODE_SETTINGS_LOCAL_FILE_NAME as y, resolvePath as yt, RulesyncCheckFrontmatterSchema as z, RULESYNC_IGNORE_RELATIVE_FILE_PATH as zt };
|
|
44974
45354
|
|
|
44975
|
-
//# sourceMappingURL=import-
|
|
45355
|
+
//# sourceMappingURL=import-WWoS8Wv4.js.map
|