agentsmesh 0.40.0 → 0.41.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/canonical.js CHANGED
@@ -926,6 +926,7 @@ var init_target_descriptor_schema = __esm({
926
926
  emitScopedSettings: z.function().optional(),
927
927
  mergeGeneratedOutputContent: z.function().optional(),
928
928
  postProcessHookOutputs: z.function().optional(),
929
+ hookContextEvents: z.array(z.string()).optional(),
929
930
  preservesManualActivation: z.boolean().optional()
930
931
  }).passthrough();
931
932
  targetDescriptorSchemaBase.superRefine((value, ctx) => {
@@ -1242,10 +1243,16 @@ var init_guards = __esm({
1242
1243
  "src/utils/types/guards.ts"() {
1243
1244
  }
1244
1245
  });
1245
- var RECALL_HOOK_COMMAND;
1246
+ var init_cli_invocation = __esm({
1247
+ "src/lessons/cli-invocation.ts"() {
1248
+ }
1249
+ });
1250
+ var RECALL_SUBCOMMAND, RECALL_HOOK_COMMAND;
1246
1251
  var init_recall_hook_scaffold = __esm({
1247
1252
  "src/lessons/recall-hook-scaffold.ts"() {
1248
- RECALL_HOOK_COMMAND = "agentsmesh lessons hook";
1253
+ init_cli_invocation();
1254
+ RECALL_SUBCOMMAND = "lessons hook";
1255
+ RECALL_HOOK_COMMAND = `agentsmesh ${RECALL_SUBCOMMAND}`;
1249
1256
  }
1250
1257
  });
1251
1258
 
@@ -2177,6 +2184,15 @@ var init_constants = __esm({
2177
2184
  }
2178
2185
  });
2179
2186
 
2187
+ // src/targets/catalog/ignore-output.ts
2188
+ function ignoreOutput(path) {
2189
+ return (canonical) => canonical.ignore.length === 0 ? [] : [{ path, content: canonical.ignore.join("\n") }];
2190
+ }
2191
+ var init_ignore_output = __esm({
2192
+ "src/targets/catalog/ignore-output.ts"() {
2193
+ }
2194
+ });
2195
+
2180
2196
  // src/targets/aider/generator.ts
2181
2197
  function buildAiderConventions(canonical) {
2182
2198
  const root = canonical.rules.find((rule) => rule.root);
@@ -2206,11 +2222,7 @@ function generateAgents(canonical) {
2206
2222
  content: serializeProjectedAgentSkill(agent)
2207
2223
  }));
2208
2224
  }
2209
- function generateIgnore(canonical) {
2210
- if (canonical.ignore.length === 0) return [];
2211
- return [{ path: AIDER_IGNORE, content: canonical.ignore.join("\n") }];
2212
- }
2213
- var generateMcp, generatePermissions;
2225
+ var generateIgnore, generateMcp, generatePermissions;
2214
2226
  var init_generator = __esm({
2215
2227
  "src/targets/aider/generator.ts"() {
2216
2228
  init_no_outputs();
@@ -2219,6 +2231,8 @@ var init_generator = __esm({
2219
2231
  init_projected_agent_skill();
2220
2232
  init_command_skill();
2221
2233
  init_constants();
2234
+ init_ignore_output();
2235
+ generateIgnore = ignoreOutput(AIDER_IGNORE);
2222
2236
  generateMcp = NO_OUTPUTS;
2223
2237
  generatePermissions = NO_OUTPUTS;
2224
2238
  }
@@ -7013,10 +7027,6 @@ function generateAgents4(canonical) {
7013
7027
  content: serializeAntigravityAgent(agent)
7014
7028
  }));
7015
7029
  }
7016
- function generateIgnore3(canonical) {
7017
- if (canonical.ignore.length === 0) return [];
7018
- return [{ path: ANTIGRAVITY_IGNORE_FILE, content: canonical.ignore.join("\n") }];
7019
- }
7020
7030
  function renderAntigravityGlobalInstructions(canonical) {
7021
7031
  const root = canonical.rules.find((rule) => rule.root);
7022
7032
  const nonRootRules = canonical.rules.filter((rule) => {
@@ -7031,7 +7041,7 @@ function generateHooks2(canonical) {
7031
7041
  if (Object.keys(hooks).length === 0) return [];
7032
7042
  return [{ path: ANTIGRAVITY_HOOKS_FILE, content: JSON.stringify(hooks, null, 2) }];
7033
7043
  }
7034
- var generatePermissions3;
7044
+ var generateIgnore3, generatePermissions3;
7035
7045
  var init_generator4 = __esm({
7036
7046
  "src/targets/antigravity/generator.ts"() {
7037
7047
  init_no_outputs();
@@ -7040,6 +7050,8 @@ var init_generator4 = __esm({
7040
7050
  init_hooks_format2();
7041
7051
  init_agents_format();
7042
7052
  init_constants5();
7053
+ init_ignore_output();
7054
+ generateIgnore3 = ignoreOutput(ANTIGRAVITY_IGNORE_FILE);
7043
7055
  generatePermissions3 = NO_OUTPUTS;
7044
7056
  }
7045
7057
  });
@@ -8502,16 +8514,14 @@ function generateHooks3(canonical) {
8502
8514
  const content = JSON.stringify({ hooks: claudeHooks }, null, 2);
8503
8515
  return [{ path: CLAUDE_SETTINGS, content }];
8504
8516
  }
8505
- function generateIgnore5(canonical) {
8506
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
8507
- const content = canonical.ignore.join("\n");
8508
- return [{ path: CLAUDE_IGNORE, content }];
8509
- }
8517
+ var generateIgnore5;
8510
8518
  var init_generator6 = __esm({
8511
8519
  "src/targets/claude-code/generator.ts"() {
8512
8520
  init_markdown();
8513
8521
  init_constants7();
8514
8522
  init_hooks_format2();
8523
+ init_ignore_output();
8524
+ generateIgnore5 = ignoreOutput(CLAUDE_IGNORE);
8515
8525
  }
8516
8526
  });
8517
8527
  function ruleSectionTitle(rule) {
@@ -10330,11 +10340,7 @@ function generateMcp5(canonical) {
10330
10340
  if (!canonical.mcp || Object.keys(canonical.mcp.mcpServers).length === 0) return [];
10331
10341
  return [{ path: CODEBUFF_MCP_FILE, content: serializeCodebuffMcp(canonical.mcp) }];
10332
10342
  }
10333
- function generateIgnore7(canonical) {
10334
- if (canonical.ignore.length === 0) return [];
10335
- return [{ path: CODEBUFF_IGNORE_FILE, content: canonical.ignore.join("\n") }];
10336
- }
10337
- var generateAgents8, generateHooks5, generatePermissions6;
10343
+ var generateIgnore7, generateAgents8, generateHooks5, generatePermissions6;
10338
10344
  var init_generator8 = __esm({
10339
10345
  "src/targets/codebuff/generator.ts"() {
10340
10346
  init_no_outputs();
@@ -10344,6 +10350,8 @@ var init_generator8 = __esm({
10344
10350
  init_nested_rules();
10345
10351
  init_mcp_format2();
10346
10352
  init_constants9();
10353
+ init_ignore_output();
10354
+ generateIgnore7 = ignoreOutput(CODEBUFF_IGNORE_FILE);
10347
10355
  generateAgents8 = NO_OUTPUTS;
10348
10356
  generateHooks5 = NO_OUTPUTS;
10349
10357
  generatePermissions6 = NO_OUTPUTS;
@@ -12856,53 +12864,37 @@ var init_mcp_generator = __esm({
12856
12864
  }
12857
12865
  });
12858
12866
 
12859
- // src/targets/copilot/hook-entry.ts
12860
- function hasHookCommand2(entry) {
12861
- return hasHookCommand(entry);
12862
- }
12863
- var init_hook_entry = __esm({
12864
- "src/targets/copilot/hook-entry.ts"() {
12865
- init_hook_command();
12866
- }
12867
- });
12868
-
12869
12867
  // src/targets/copilot/hook-format.ts
12870
- function mapHookEvent(event) {
12871
- switch (event) {
12872
- case "PreToolUse":
12873
- return "preToolUse";
12874
- case "PostToolUse":
12875
- return "postToolUse";
12876
- case "Notification":
12877
- return "notification";
12878
- case "UserPromptSubmit":
12879
- return "userPromptSubmitted";
12880
- default:
12881
- return null;
12882
- }
12868
+ function copilotHookGroups(hooks) {
12869
+ return Object.entries(hooks ?? {}).flatMap(([event, entries]) => {
12870
+ const copilotEvent = CANONICAL_TO_COPILOT.get(event);
12871
+ if (!copilotEvent || !Array.isArray(entries)) return [];
12872
+ const kept = entries.filter(
12873
+ (entry) => typeof entry === "object" && entry !== null && hasHookCommand(entry)
12874
+ );
12875
+ return kept.length > 0 ? [{ event, copilotEvent, entries: kept }] : [];
12876
+ });
12877
+ }
12878
+ function wrapperScriptName(event, index) {
12879
+ return `${event.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase()}-${index}.sh`;
12883
12880
  }
12884
12881
  function buildCopilotHooksObject(hooks) {
12885
- if (!hooks) return null;
12886
- const result2 = Object.fromEntries(
12887
- Object.entries(hooks).flatMap(([event, entries]) => {
12888
- const mappedEvent = mapHookEvent(event);
12889
- if (!mappedEvent || !Array.isArray(entries)) return [];
12890
- const mappedEntries = entries.filter(
12891
- (entry) => typeof entry === "object" && entry !== null && hasHookCommand2(entry)
12892
- ).map((entry, index) => {
12893
- const safePhase = event.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
12882
+ const groups = copilotHookGroups(hooks);
12883
+ if (groups.length === 0) return null;
12884
+ return Object.fromEntries(
12885
+ groups.map(({ event, copilotEvent, entries }) => [
12886
+ copilotEvent,
12887
+ entries.map((entry, index) => {
12894
12888
  const hook = {
12895
12889
  type: "command",
12896
- bash: `./scripts/${safePhase}-${index}.sh`
12890
+ bash: `./scripts/${wrapperScriptName(event, index)}`
12897
12891
  };
12898
12892
  if (entry.matcher && entry.matcher !== "*") hook.matcher = entry.matcher;
12899
12893
  if (entry.timeout !== void 0) hook.timeoutSec = Math.ceil(entry.timeout / 1e3);
12900
12894
  return hook;
12901
- });
12902
- return mappedEntries.length > 0 ? [[mappedEvent, mappedEntries]] : [];
12903
- })
12895
+ })
12896
+ ])
12904
12897
  );
12905
- return Object.keys(result2).length > 0 ? result2 : null;
12906
12898
  }
12907
12899
  function generateHooks8(canonical) {
12908
12900
  const hooks = buildCopilotHooksObject(canonical.hooks);
@@ -12914,10 +12906,24 @@ function generateHooks8(canonical) {
12914
12906
  }
12915
12907
  ];
12916
12908
  }
12909
+ var COPILOT_HOOK_CONTEXT_EVENTS, CANONICAL_TO_COPILOT;
12917
12910
  var init_hook_format = __esm({
12918
12911
  "src/targets/copilot/hook-format.ts"() {
12919
12912
  init_constants32();
12920
- init_hook_entry();
12913
+ init_hook_command();
12914
+ COPILOT_HOOK_CONTEXT_EVENTS = [
12915
+ "SessionStart",
12916
+ "PostToolUse",
12917
+ "PostToolUseFailure"
12918
+ ];
12919
+ CANONICAL_TO_COPILOT = /* @__PURE__ */ new Map([
12920
+ ["PreToolUse", "preToolUse"],
12921
+ ["PostToolUse", "postToolUse"],
12922
+ ["PostToolUseFailure", "postToolUseFailure"],
12923
+ ["Notification", "notification"],
12924
+ ["UserPromptSubmit", "userPromptSubmitted"],
12925
+ ["SessionStart", "sessionStart"]
12926
+ ]);
12921
12927
  }
12922
12928
  });
12923
12929
  function ruleSlug3(source) {
@@ -13023,18 +13029,7 @@ var init_generator12 = __esm({
13023
13029
  }
13024
13030
  });
13025
13031
  function mapCopilotHookEvent(event) {
13026
- switch (event) {
13027
- case "preToolUse":
13028
- return "PreToolUse";
13029
- case "postToolUse":
13030
- return "PostToolUse";
13031
- case "notification":
13032
- return "Notification";
13033
- case "userPromptSubmitted":
13034
- return "UserPromptSubmit";
13035
- default:
13036
- return null;
13037
- }
13032
+ return COPILOT_TO_CANONICAL.get(event) ?? null;
13038
13033
  }
13039
13034
  function extractMatcher(comment) {
13040
13035
  if (typeof comment !== "string") return "*";
@@ -13122,11 +13117,16 @@ async function importHooks(projectRoot, results, options = {}) {
13122
13117
  feature: "hooks"
13123
13118
  });
13124
13119
  }
13120
+ var COPILOT_TO_CANONICAL;
13125
13121
  var init_hook_parser = __esm({
13126
13122
  "src/targets/copilot/hook-parser.ts"() {
13127
13123
  init_canonical_paths();
13128
13124
  init_fs();
13129
13125
  init_constants32();
13126
+ init_hook_format();
13127
+ COPILOT_TO_CANONICAL = new Map(
13128
+ [...CANONICAL_TO_COPILOT].map(([canonical, copilot]) => [copilot, canonical])
13129
+ );
13130
13130
  }
13131
13131
  });
13132
13132
  async function importSkills2(projectRoot, results, normalize, skillsDirRel = COPILOT_SKILLS_DIR) {
@@ -13363,7 +13363,7 @@ function lintCommands4(canonical) {
13363
13363
  }
13364
13364
  function lintHooks9(canonical) {
13365
13365
  if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
13366
- const supported = ["PreToolUse", "PostToolUse", "Notification", "UserPromptSubmit"];
13366
+ const supported = [...CANONICAL_TO_COPILOT.keys()];
13367
13367
  const diagnostics = unsupportedHookEventNames(canonical.hooks, supported).map(
13368
13368
  (event) => createUnsupportedHookWarning(event, "copilot", supported, {
13369
13369
  unsupportedBy: "Copilot hooks"
@@ -13386,11 +13386,9 @@ function lintHooks9(canonical) {
13386
13386
  var init_lint10 = __esm({
13387
13387
  "src/targets/copilot/lint.ts"() {
13388
13388
  init_helpers();
13389
+ init_hook_format();
13389
13390
  }
13390
13391
  });
13391
- function safePhaseName(phase) {
13392
- return phase.replace(/[^a-zA-Z0-9]/g, "-").toLowerCase();
13393
- }
13394
13392
  function toRepoRelative(projectRoot, sourcePath) {
13395
13393
  const repoRelative = relative(projectRoot, sourcePath).replace(/\\/g, "/");
13396
13394
  if (!repoRelative || repoRelative.startsWith("../")) return null;
@@ -13418,9 +13416,6 @@ async function buildAssetOutput(projectRoot, command, hooksDirRel) {
13418
13416
  rewrittenCommand: rewriteWrapperCommand(command, repoRelative)
13419
13417
  };
13420
13418
  }
13421
- function wrapperPath(event, index, hooksDirRel) {
13422
- return `${hooksDirRel}/scripts/${safePhaseName(event)}-${index}.sh`;
13423
- }
13424
13419
  function safeShellLine2(value) {
13425
13420
  return value.replace(/[\r\n]+/g, " ");
13426
13421
  }
@@ -13435,15 +13430,13 @@ function buildWrapper(command, matcher) {
13435
13430
  ].join("\n");
13436
13431
  }
13437
13432
  async function addHookScriptAssets(projectRoot, canonical, outputs, hooksDirRel = COPILOT_HOOKS_DIR) {
13438
- if (!canonical.hooks) return outputs;
13433
+ const groups = copilotHookGroups(canonical.hooks);
13434
+ if (groups.length === 0) return outputs;
13439
13435
  const wrapperOutputs = [];
13440
13436
  const assetOutputs = /* @__PURE__ */ new Map();
13441
- for (const [event, entries] of Object.entries(canonical.hooks)) {
13442
- if (!Array.isArray(entries)) continue;
13443
- let index = 0;
13444
- for (const entry of entries) {
13445
- if (!hasHookCommand2(entry)) continue;
13446
- const scriptPath = wrapperPath(event, index, hooksDirRel);
13437
+ for (const { event, entries } of groups) {
13438
+ for (const [index, entry] of entries.entries()) {
13439
+ const scriptPath = `${hooksDirRel}/scripts/${wrapperScriptName(event, index)}`;
13447
13440
  let command = entry.command;
13448
13441
  const asset = await buildAssetOutput(projectRoot, entry.command, hooksDirRel);
13449
13442
  if (asset) {
@@ -13457,7 +13450,6 @@ async function addHookScriptAssets(projectRoot, canonical, outputs, hooksDirRel
13457
13450
  'set -eu\nHOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"\n'
13458
13451
  );
13459
13452
  wrapperOutputs.push({ path: scriptPath, content: wrapper });
13460
- index++;
13461
13453
  }
13462
13454
  }
13463
13455
  return [...outputs, ...wrapperOutputs, ...assetOutputs.values()];
@@ -13467,7 +13459,7 @@ var init_hook_assets = __esm({
13467
13459
  "src/targets/copilot/hook-assets.ts"() {
13468
13460
  init_fs();
13469
13461
  init_constants32();
13470
- init_hook_entry();
13462
+ init_hook_format();
13471
13463
  SCRIPT_PREFIX_RE = /^(?<prefix>\s*(?:(?:bash|sh|zsh)\s+)?)["']?(?<path>(?:\.\.\/|\.\/|[^/\s"'`]+\/)[^\s"'`]+)["']?(?<suffix>(?:\s.*)?)$/;
13472
13464
  }
13473
13465
  });
@@ -13785,6 +13777,7 @@ var init_copilot2 = __esm({
13785
13777
  init_command_prompt();
13786
13778
  init_lint10();
13787
13779
  init_hook_assets();
13780
+ init_hook_format();
13788
13781
  init_scope_extras2();
13789
13782
  init_importer_spec2();
13790
13783
  init_capabilities6();
@@ -13915,6 +13908,7 @@ var init_copilot2 = __esm({
13915
13908
  permissions: lintPermissions7
13916
13909
  },
13917
13910
  postProcessHookOutputs: async (projectRoot, canonical, outputs) => addHookScriptAssets(projectRoot, canonical, [...outputs]),
13911
+ hookContextEvents: COPILOT_HOOK_CONTEXT_EVENTS,
13918
13912
  mergeGeneratedOutputContent: mergeCopilotMcpJson,
13919
13913
  project: project7,
13920
13914
  globalSupport: {
@@ -14002,11 +13996,6 @@ function generatePermissions8(canonical) {
14002
13996
  });
14003
13997
  return [{ path: CRUSH_CONFIG_FILE, content: JSON.stringify(crushConfig, null, 2) }];
14004
13998
  }
14005
- function generateIgnore9(canonical) {
14006
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
14007
- const content = canonical.ignore.join("\n");
14008
- return [{ path: CRUSH_IGNORE, content }];
14009
- }
14010
13999
  function buildCrushHooksFromCanonical(canonical) {
14011
14000
  if (!canonical.hooks) return {};
14012
14001
  const result2 = {};
@@ -14024,7 +14013,7 @@ function buildCrushHooksFromCanonical(canonical) {
14024
14013
  }
14025
14014
  return result2;
14026
14015
  }
14027
- var generateRules12;
14016
+ var generateRules12, generateIgnore9;
14028
14017
  var init_generator13 = __esm({
14029
14018
  "src/targets/crush/generator.ts"() {
14030
14019
  init_managed_blocks();
@@ -14033,7 +14022,9 @@ var init_generator13 = __esm({
14033
14022
  init_command_skill();
14034
14023
  init_constants12();
14035
14024
  init_config_format();
14025
+ init_ignore_output();
14036
14026
  generateRules12 = (canonical) => embeddedRootRule(canonical, CRUSH_TARGET, CRUSH_ROOT_FILE);
14027
+ generateIgnore9 = ignoreOutput(CRUSH_IGNORE);
14037
14028
  }
14038
14029
  });
14039
14030
  async function importFromCrush(projectRoot, options = {}) {
@@ -14569,7 +14560,7 @@ function cursorHooksToCanonical(hooks) {
14569
14560
  }
14570
14561
  return result2;
14571
14562
  }
14572
- var CANONICAL_TO_CURSOR, CURSOR_TO_CANONICAL;
14563
+ var CANONICAL_TO_CURSOR, CURSOR_HOOK_CONTEXT_EVENTS, CURSOR_TO_CANONICAL;
14573
14564
  var init_hook_format2 = __esm({
14574
14565
  "src/targets/cursor/hook-format.ts"() {
14575
14566
  init_hook_types();
@@ -14577,6 +14568,7 @@ var init_hook_format2 = __esm({
14577
14568
  CANONICAL_TO_CURSOR = {
14578
14569
  PreToolUse: "preToolUse",
14579
14570
  PostToolUse: "postToolUse",
14571
+ PostToolUseFailure: "postToolUseFailure",
14580
14572
  UserPromptSubmit: "beforeSubmitPrompt",
14581
14573
  SubagentStart: "subagentStart",
14582
14574
  SubagentStop: "subagentStop",
@@ -14585,6 +14577,11 @@ var init_hook_format2 = __esm({
14585
14577
  SessionEnd: "sessionEnd",
14586
14578
  PreCompact: "preCompact"
14587
14579
  };
14580
+ CURSOR_HOOK_CONTEXT_EVENTS = [
14581
+ "SessionStart",
14582
+ "PostToolUse",
14583
+ "PostToolUseFailure"
14584
+ ];
14588
14585
  CURSOR_TO_CANONICAL = new Map(
14589
14586
  Object.entries(CANONICAL_TO_CURSOR).map(([canonical, cursor]) => [cursor, canonical])
14590
14587
  );
@@ -14593,7 +14590,7 @@ var init_hook_format2 = __esm({
14593
14590
 
14594
14591
  // src/targets/cursor/generator/hooks.ts
14595
14592
  function generateHooks10(canonical) {
14596
- if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
14593
+ if (!canonical.hooks) return [];
14597
14594
  const cursorHooks = toCursorHooks(canonical.hooks);
14598
14595
  if (Object.keys(cursorHooks).length === 0) return [];
14599
14596
  const content = JSON.stringify({ version: 1, hooks: cursorHooks }, null, 2);
@@ -14607,14 +14604,12 @@ var init_hooks4 = __esm({
14607
14604
  });
14608
14605
 
14609
14606
  // src/targets/cursor/generator/ignore.ts
14610
- function generateIgnore10(canonical) {
14611
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
14612
- const content = canonical.ignore.join("\n");
14613
- return [{ path: CURSOR_IGNORE, content }];
14614
- }
14607
+ var generateIgnore10;
14615
14608
  var init_ignore = __esm({
14616
14609
  "src/targets/cursor/generator/ignore.ts"() {
14617
14610
  init_constants13();
14611
+ init_ignore_output();
14612
+ generateIgnore10 = ignoreOutput(CURSOR_IGNORE);
14618
14613
  }
14619
14614
  });
14620
14615
 
@@ -15168,7 +15163,7 @@ var init_importer13 = __esm({
15168
15163
  });
15169
15164
 
15170
15165
  // src/targets/cursor/merge.ts
15171
- var mergeMcp3, mergeHooks2, mergePermissions2, mergeCursorOutput;
15166
+ var mergeMcp3, mergeHooks, mergePermissions2, mergeCursorOutput;
15172
15167
  var init_merge4 = __esm({
15173
15168
  "src/targets/cursor/merge.ts"() {
15174
15169
  init_target_descriptor();
@@ -15176,14 +15171,14 @@ var init_merge4 = __esm({
15176
15171
  init_mcp_servers_merge();
15177
15172
  init_constants13();
15178
15173
  mergeMcp3 = mcpServersJsonMerger([CURSOR_MCP], CANONICAL_MCP_SERVER_KEYS);
15179
- mergeHooks2 = ownedJsonKeysMerger([CURSOR_HOOKS], ["version", "hooks"]);
15174
+ mergeHooks = ownedJsonKeysMerger([CURSOR_HOOKS], ["version", "hooks"]);
15180
15175
  mergePermissions2 = ownedJsonKeysMerger(
15181
15176
  [CURSOR_CLI_JSON, CURSOR_GLOBAL_CLI_CONFIG],
15182
15177
  ["permissions"]
15183
15178
  );
15184
15179
  mergeCursorOutput = firstMerger([
15185
15180
  mergeMcp3,
15186
- mergeHooks2,
15181
+ mergeHooks,
15187
15182
  mergePermissions2
15188
15183
  ]);
15189
15184
  }
@@ -15310,6 +15305,7 @@ var init_cursor2 = __esm({
15310
15305
  init_linter13();
15311
15306
  init_import_map_builders();
15312
15307
  init_lint12();
15308
+ init_hook_format2();
15313
15309
  target13 = {
15314
15310
  name: "cursor",
15315
15311
  primaryRootInstructionPath: CURSOR_GENERAL_RULE,
@@ -15431,6 +15427,7 @@ var init_cursor2 = __esm({
15431
15427
  permissions: "native"
15432
15428
  },
15433
15429
  emptyImportMessage: "No Cursor config found (AGENTS.md or .cursor/rules/*.mdc; with --global: ~/.cursor/{rules/*.mdc,AGENTS.md,mcp.json,hooks.json,cursorignore,skills/,agents/,commands/} and legacy ~/.agentsmesh-exports/cursor/user-rules.md).",
15430
+ hookContextEvents: CURSOR_HOOK_CONTEXT_EVENTS,
15434
15431
  lintRules: lintRules13,
15435
15432
  lint: {
15436
15433
  commands: lintCommands6,
@@ -16328,7 +16325,7 @@ var init_importer15 = __esm({
16328
16325
  });
16329
16326
 
16330
16327
  // src/targets/factory-droid/merge.ts
16331
- var mergeMcp4, mergeHooks3, mergeSettings, mergeFactoryDroidOutput;
16328
+ var mergeMcp4, mergeHooks2, mergeSettings, mergeFactoryDroidOutput;
16332
16329
  var init_merge5 = __esm({
16333
16330
  "src/targets/factory-droid/merge.ts"() {
16334
16331
  init_target_descriptor();
@@ -16339,7 +16336,7 @@ var init_merge5 = __esm({
16339
16336
  [FACTORY_DROID_MCP_FILE, FACTORY_DROID_GLOBAL_MCP_FILE],
16340
16337
  CANONICAL_MCP_SERVER_KEYS
16341
16338
  );
16342
- mergeHooks3 = ownedJsonKeysMerger(
16339
+ mergeHooks2 = ownedJsonKeysMerger(
16343
16340
  [FACTORY_DROID_HOOKS_FILE, FACTORY_DROID_GLOBAL_HOOKS_FILE],
16344
16341
  ["hooks"]
16345
16342
  );
@@ -16349,7 +16346,7 @@ var init_merge5 = __esm({
16349
16346
  );
16350
16347
  mergeFactoryDroidOutput = firstMerger([
16351
16348
  mergeMcp4,
16352
- mergeHooks3,
16349
+ mergeHooks2,
16353
16350
  mergeSettings
16354
16351
  ]);
16355
16352
  }
@@ -16692,25 +16689,127 @@ var init_skills3 = __esm({
16692
16689
  }
16693
16690
  });
16694
16691
 
16695
- // src/targets/gemini-cli/generator/settings.ts
16696
- function mapHookEvent2(event) {
16697
- switch (event) {
16698
- case "PreToolUse":
16699
- return "BeforeTool";
16700
- case "PostToolUse":
16701
- return "AfterTool";
16702
- case "Notification":
16703
- return "Notification";
16704
- case "SubagentStart":
16705
- return "BeforeAgent";
16706
- case "SubagentStop":
16707
- return "AfterAgent";
16708
- case "SessionStart":
16709
- return "SessionStart";
16710
- default:
16711
- return null;
16692
+ // src/targets/gemini-cli/hook-map.ts
16693
+ function geminiHookEvent(event) {
16694
+ return CANONICAL_TO_GEMINI.get(event) ?? null;
16695
+ }
16696
+ function mapGeminiHookEvent(event) {
16697
+ return GEMINI_TO_CANONICAL.get(event) ?? null;
16698
+ }
16699
+ function splitNames(list, separator) {
16700
+ return list.split(separator).map((name) => name.trim()).filter((name) => name.length > 0);
16701
+ }
16702
+ function toGeminiMatcher(geminiEvent, matcher) {
16703
+ if (!TOOL_EVENTS.has(geminiEvent) || !NAME_LIST.test(matcher)) return matcher;
16704
+ const tools = unique(
16705
+ splitNames(matcher, /[|,]/).flatMap((name) => CANONICAL_TO_GEMINI_TOOLS.get(name) ?? [name])
16706
+ );
16707
+ return tools.length > 0 ? `^(?:${tools.join("|")})$` : matcher;
16708
+ }
16709
+ function fromGeminiMatcher(geminiEvent, matcher) {
16710
+ if (!TOOL_EVENTS.has(geminiEvent)) return matcher;
16711
+ const list = ANCHORED_LIST.exec(matcher)?.[1] ?? matcher;
16712
+ if (!NAME_LIST.test(list) || list.includes(",")) return matcher;
16713
+ return unique(
16714
+ splitNames(list, /\|/).map((name) => GEMINI_TO_CANONICAL_TOOLS.get(name) ?? name)
16715
+ ).join("|");
16716
+ }
16717
+ var GEMINI_HOOK_CONTEXT_EVENTS, CANONICAL_TO_GEMINI, GEMINI_TO_CANONICAL, TOOL_EVENTS, CANONICAL_TO_GEMINI_TOOLS, GEMINI_TO_CANONICAL_TOOLS, NAME_LIST, ANCHORED_LIST, unique;
16718
+ var init_hook_map = __esm({
16719
+ "src/targets/gemini-cli/hook-map.ts"() {
16720
+ GEMINI_HOOK_CONTEXT_EVENTS = [
16721
+ "UserPromptSubmit",
16722
+ "SessionStart",
16723
+ "PostToolUse"
16724
+ ];
16725
+ CANONICAL_TO_GEMINI = /* @__PURE__ */ new Map([
16726
+ ["PreToolUse", "BeforeTool"],
16727
+ ["PostToolUse", "AfterTool"],
16728
+ ["Notification", "Notification"],
16729
+ // BeforeAgent fires after the user submits a prompt and carries `prompt`.
16730
+ ["UserPromptSubmit", "BeforeAgent"],
16731
+ // Older mapping, kept so existing SubagentStart hooks still reach Gemini.
16732
+ ["SubagentStart", "BeforeAgent"],
16733
+ ["SubagentStop", "AfterAgent"],
16734
+ ["SessionStart", "SessionStart"]
16735
+ ]);
16736
+ GEMINI_TO_CANONICAL = new Map([
16737
+ ...[...CANONICAL_TO_GEMINI].map(([canonical, gemini]) => [gemini, canonical]),
16738
+ // BeforeAgent is shared with SubagentStart; import it as the prompt event.
16739
+ ["BeforeAgent", "UserPromptSubmit"],
16740
+ // Legacy lowercase names.
16741
+ ["preToolUse", "PreToolUse"],
16742
+ ["postToolUse", "PostToolUse"],
16743
+ ["notification", "Notification"]
16744
+ ]);
16745
+ TOOL_EVENTS = /* @__PURE__ */ new Set(["BeforeTool", "AfterTool"]);
16746
+ CANONICAL_TO_GEMINI_TOOLS = /* @__PURE__ */ new Map([
16747
+ ["Bash", ["run_shell_command"]],
16748
+ ["PowerShell", ["run_shell_command"]],
16749
+ ["Edit", ["replace"]],
16750
+ ["MultiEdit", ["replace"]],
16751
+ ["Write", ["write_file"]],
16752
+ ["NotebookEdit", []],
16753
+ ["Read", ["read_file", "read_many_files"]],
16754
+ ["Grep", ["grep_search"]],
16755
+ ["Glob", ["glob"]],
16756
+ ["LS", ["list_directory"]],
16757
+ ["WebFetch", ["web_fetch"]],
16758
+ ["WebSearch", ["google_web_search"]],
16759
+ ["TodoWrite", ["write_todos"]]
16760
+ ]);
16761
+ GEMINI_TO_CANONICAL_TOOLS = /* @__PURE__ */ new Map([
16762
+ ["run_shell_command", "Bash"],
16763
+ ["replace", "Edit"],
16764
+ ["write_file", "Write"],
16765
+ ["read_file", "Read"],
16766
+ ["read_many_files", "Read"],
16767
+ ["grep_search", "Grep"],
16768
+ ["search_file_content", "Grep"],
16769
+ ["glob", "Glob"],
16770
+ ["list_directory", "LS"],
16771
+ ["web_fetch", "WebFetch"],
16772
+ ["google_web_search", "WebSearch"],
16773
+ ["write_todos", "TodoWrite"]
16774
+ ]);
16775
+ NAME_LIST = /^[\w\s,|-]+$/;
16776
+ ANCHORED_LIST = /^\^\(\?:(.*)\)\$$/;
16777
+ unique = (values) => [...new Set(values)];
16712
16778
  }
16779
+ });
16780
+
16781
+ // src/targets/gemini-cli/generator/hooks.ts
16782
+ function buildGeminiHooks(hooks) {
16783
+ const result2 = {};
16784
+ for (const [event, entries] of Object.entries(hooks ?? {})) {
16785
+ const geminiEvent = geminiHookEvent(event);
16786
+ if (!geminiEvent || !Array.isArray(entries)) continue;
16787
+ for (const entry of entries) {
16788
+ if (typeof entry !== "object" || entry === null || !hasHookCommand(entry)) continue;
16789
+ const list = result2[geminiEvent] ??= [];
16790
+ list.push({
16791
+ matcher: typeof entry.matcher === "string" ? toGeminiMatcher(geminiEvent, entry.matcher) : entry.matcher,
16792
+ hooks: [
16793
+ {
16794
+ name: `${geminiEvent}-${list.length + 1}`,
16795
+ type: "command",
16796
+ command: getHookCommand(entry),
16797
+ timeout: entry.timeout
16798
+ }
16799
+ ]
16800
+ });
16801
+ }
16802
+ }
16803
+ return Object.keys(result2).length > 0 ? result2 : null;
16713
16804
  }
16805
+ var init_hooks5 = __esm({
16806
+ "src/targets/gemini-cli/generator/hooks.ts"() {
16807
+ init_hook_command();
16808
+ init_hook_map();
16809
+ }
16810
+ });
16811
+
16812
+ // src/targets/gemini-cli/generator/settings.ts
16714
16813
  function generateGeminiSettingsFiles(canonical, enabledFeatures) {
16715
16814
  const settings = {};
16716
16815
  let hasAnyNativeSettings = false;
@@ -16722,29 +16821,10 @@ function generateGeminiSettingsFiles(canonical, enabledFeatures) {
16722
16821
  settings.experimental = { enableAgents: true };
16723
16822
  hasAnyNativeSettings = true;
16724
16823
  }
16725
- if (enabledFeatures.has("hooks") && canonical.hooks) {
16726
- const hookEntries = Object.entries(canonical.hooks).flatMap(([event, entries]) => {
16727
- const mappedEvent = mapHookEvent2(event);
16728
- if (!mappedEvent || !Array.isArray(entries)) return [];
16729
- const mappedEntries = entries.filter(
16730
- (entry) => typeof entry === "object" && entry !== null && hasHookCommand(entry)
16731
- ).map((entry, index) => ({
16732
- matcher: entry.matcher,
16733
- hooks: [
16734
- {
16735
- name: `${mappedEvent}-${index + 1}`,
16736
- type: "command",
16737
- command: getHookCommand(entry),
16738
- timeout: entry.timeout
16739
- }
16740
- ]
16741
- }));
16742
- return mappedEntries.length > 0 ? [[mappedEvent, mappedEntries]] : [];
16743
- });
16744
- if (hookEntries.length > 0) {
16745
- settings.hooks = Object.fromEntries(hookEntries);
16746
- hasAnyNativeSettings = true;
16747
- }
16824
+ const hooks = enabledFeatures.has("hooks") ? buildGeminiHooks(canonical.hooks) : null;
16825
+ if (hooks) {
16826
+ settings.hooks = hooks;
16827
+ hasAnyNativeSettings = true;
16748
16828
  }
16749
16829
  if (hasAnyNativeSettings) {
16750
16830
  settings.context = { fileName: [GEMINI_ROOT, GEMINI_COMPAT_AGENTS] };
@@ -16754,19 +16834,18 @@ function generateGeminiSettingsFiles(canonical, enabledFeatures) {
16754
16834
  }
16755
16835
  var init_settings2 = __esm({
16756
16836
  "src/targets/gemini-cli/generator/settings.ts"() {
16757
- init_hook_command();
16758
16837
  init_constants33();
16838
+ init_hooks5();
16759
16839
  }
16760
16840
  });
16761
16841
 
16762
16842
  // src/targets/gemini-cli/generator/ignore.ts
16763
- function generateIgnore13(canonical) {
16764
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
16765
- return [{ path: GEMINI_IGNORE, content: canonical.ignore.join("\n") }];
16766
- }
16843
+ var generateIgnore13;
16767
16844
  var init_ignore2 = __esm({
16768
16845
  "src/targets/gemini-cli/generator/ignore.ts"() {
16769
16846
  init_constants33();
16847
+ init_ignore_output();
16848
+ generateIgnore13 = ignoreOutput(GEMINI_IGNORE);
16770
16849
  }
16771
16850
  });
16772
16851
 
@@ -17045,27 +17124,6 @@ var init_layout6 = __esm({
17045
17124
  };
17046
17125
  }
17047
17126
  });
17048
- function mapGeminiHookEvent(event) {
17049
- switch (event) {
17050
- case "BeforeTool":
17051
- case "preToolUse":
17052
- return "PreToolUse";
17053
- case "AfterTool":
17054
- case "postToolUse":
17055
- return "PostToolUse";
17056
- case "Notification":
17057
- case "notification":
17058
- return "Notification";
17059
- case "BeforeAgent":
17060
- return "SubagentStart";
17061
- case "AfterAgent":
17062
- return "SubagentStop";
17063
- case "SessionStart":
17064
- return "SessionStart";
17065
- default:
17066
- return null;
17067
- }
17068
- }
17069
17127
  function parseFlexibleFrontmatter(content) {
17070
17128
  const yamlOpen = content.indexOf("---");
17071
17129
  const tomlOpen = content.indexOf("+++");
@@ -17139,7 +17197,7 @@ async function importGeminiSettings(projectRoot, results) {
17139
17197
  (entry) => entry.hooks.filter(
17140
17198
  (hook) => hook !== null && typeof hook === "object" && hasHookCommand(hook)
17141
17199
  ).map((hook) => ({
17142
- matcher: entry.matcher,
17200
+ matcher: fromGeminiMatcher(event, entry.matcher),
17143
17201
  command: getHookCommand(hook),
17144
17202
  type: "command",
17145
17203
  timeout: typeof hook.timeout === "number" ? hook.timeout : void 0
@@ -17149,7 +17207,7 @@ async function importGeminiSettings(projectRoot, results) {
17149
17207
  const legacyMapped = value.filter(
17150
17208
  (entry) => entry !== null && typeof entry === "object" && typeof entry.matcher === "string" && hasHookCommand(entry)
17151
17209
  ).map((entry) => ({
17152
- matcher: entry.matcher,
17210
+ matcher: fromGeminiMatcher(event, entry.matcher),
17153
17211
  command: getHookCommand(entry),
17154
17212
  type: "command"
17155
17213
  }));
@@ -17178,7 +17236,7 @@ var init_format_helpers_settings = __esm({
17178
17236
  init_hook_command();
17179
17237
  init_fs();
17180
17238
  init_constants33();
17181
- init_format_helpers_shared();
17239
+ init_hook_map();
17182
17240
  }
17183
17241
  });
17184
17242
  async function importGeminiIgnore(projectRoot, results) {
@@ -17674,14 +17732,7 @@ function lintPermissions10(canonical, options) {
17674
17732
  }
17675
17733
  function lintHooks12(canonical) {
17676
17734
  if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
17677
- const supported = [
17678
- "PreToolUse",
17679
- "PostToolUse",
17680
- "Notification",
17681
- "SubagentStart",
17682
- "SubagentStop",
17683
- "SessionStart"
17684
- ];
17735
+ const supported = [...CANONICAL_TO_GEMINI.keys()];
17685
17736
  return unsupportedHookEventNames(canonical.hooks, supported).map(
17686
17737
  (event) => createUnsupportedHookWarning(event, "gemini-cli", supported)
17687
17738
  );
@@ -17689,6 +17740,7 @@ function lintHooks12(canonical) {
17689
17740
  var init_lint15 = __esm({
17690
17741
  "src/targets/gemini-cli/lint.ts"() {
17691
17742
  init_helpers();
17743
+ init_hook_map();
17692
17744
  }
17693
17745
  });
17694
17746
 
@@ -17725,6 +17777,7 @@ var init_gemini_cli2 = __esm({
17725
17777
  init_import_map_builders();
17726
17778
  init_lint15();
17727
17779
  init_scoped_settings_emit();
17780
+ init_hook_map();
17728
17781
  init_settings();
17729
17782
  target16 = {
17730
17783
  name: "gemini-cli",
@@ -17775,6 +17828,7 @@ var init_gemini_cli2 = __esm({
17775
17828
  permissions: lintPermissions10
17776
17829
  },
17777
17830
  emitScopedSettings: emitScopedGeminiSettings,
17831
+ hookContextEvents: GEMINI_HOOK_CONTEXT_EVENTS,
17778
17832
  mergeGeneratedOutputContent(existing, pending, newContent, resolvedPath) {
17779
17833
  const base = pending?.content ?? existing;
17780
17834
  if (base !== null && resolvedPath === GEMINI_SETTINGS) {
@@ -17867,14 +17921,10 @@ function generateAgents17(canonical) {
17867
17921
  content: serializeProjectedAgentSkill(agent)
17868
17922
  }));
17869
17923
  }
17870
- function generateIgnore14(canonical) {
17871
- if (canonical.ignore.length === 0) return [];
17872
- return [{ path: GOOSE_IGNORE, content: canonical.ignore.join("\n") }];
17873
- }
17874
17924
  function generateHooks12(canonical) {
17875
17925
  return buildWrappedCommandHooks(canonical, GOOSE_HOOKS_FILE);
17876
17926
  }
17877
- var generateRules17, generatePermissions12;
17927
+ var generateRules17, generateIgnore14, generatePermissions12;
17878
17928
  var init_generator20 = __esm({
17879
17929
  "src/targets/goose/generator.ts"() {
17880
17930
  init_managed_blocks();
@@ -17884,7 +17934,9 @@ var init_generator20 = __esm({
17884
17934
  init_command_skill();
17885
17935
  init_wrapped_command_hooks();
17886
17936
  init_constants16();
17937
+ init_ignore_output();
17887
17938
  generateRules17 = (canonical) => embeddedRootRule(canonical, GOOSE_TARGET, GOOSE_ROOT_FILE);
17939
+ generateIgnore14 = ignoreOutput(GOOSE_IGNORE);
17888
17940
  generatePermissions12 = NO_OUTPUTS;
17889
17941
  }
17890
17942
  });
@@ -18789,10 +18841,6 @@ function generateAgents18(canonical) {
18789
18841
  };
18790
18842
  });
18791
18843
  }
18792
- function generateIgnore16(canonical) {
18793
- if (canonical.ignore.length === 0) return [];
18794
- return [{ path: JUNIE_IGNORE, content: canonical.ignore.join("\n") }];
18795
- }
18796
18844
  function generateSkills17(canonical) {
18797
18845
  return generateEmbeddedSkills(canonical, JUNIE_SKILLS_DIR);
18798
18846
  }
@@ -18804,6 +18852,7 @@ function renderJunieGlobalInstructions(canonical) {
18804
18852
  });
18805
18853
  return appendEmbeddedRulesBlock(root?.body.trim() ?? "", nonRootRules);
18806
18854
  }
18855
+ var generateIgnore16;
18807
18856
  var init_generator22 = __esm({
18808
18857
  "src/targets/junie/generator.ts"() {
18809
18858
  init_mcp_servers();
@@ -18811,7 +18860,9 @@ var init_generator22 = __esm({
18811
18860
  init_managed_blocks();
18812
18861
  init_markdown();
18813
18862
  init_constants18();
18863
+ init_ignore_output();
18814
18864
  init_global_config2();
18865
+ generateIgnore16 = ignoreOutput(JUNIE_IGNORE);
18815
18866
  }
18816
18867
  });
18817
18868
 
@@ -19227,10 +19278,6 @@ function generateMcp15(canonical) {
19227
19278
  }
19228
19279
  ];
19229
19280
  }
19230
- function generateIgnore17(canonical) {
19231
- if (canonical.ignore.length === 0) return [];
19232
- return [{ path: KILO_CODE_IGNORE, content: canonical.ignore.join("\n") }];
19233
- }
19234
19281
  function generatePermissions15(canonical) {
19235
19282
  if (!canonical.permissions) return [];
19236
19283
  const { allow, deny } = canonical.permissions;
@@ -19245,11 +19292,14 @@ function generatePermissions15(canonical) {
19245
19292
  function generateSkills18(canonical) {
19246
19293
  return generateEmbeddedSkills(canonical, KILO_CODE_SKILLS_DIR);
19247
19294
  }
19295
+ var generateIgnore17;
19248
19296
  var init_generator23 = __esm({
19249
19297
  "src/targets/kilo-code/generator.ts"() {
19250
19298
  init_embedded_skill();
19251
19299
  init_markdown();
19252
19300
  init_constants19();
19301
+ init_ignore_output();
19302
+ generateIgnore17 = ignoreOutput(KILO_CODE_IGNORE);
19253
19303
  }
19254
19304
  });
19255
19305
  var kiloNonRootRuleMapper, kiloCommandMapper, kiloAgentMapper;
@@ -20994,11 +21044,7 @@ function buildKiroAgentOutputs(canonical, rules = []) {
20994
21044
  function generateAgents21(canonical) {
20995
21045
  return buildKiroAgentOutputs(canonical);
20996
21046
  }
20997
- function generateIgnore18(canonical) {
20998
- if (canonical.ignore.length === 0) return [];
20999
- return [{ path: KIRO_IGNORE, content: canonical.ignore.join("\n") }];
21000
- }
21001
- var generatePermissions17;
21047
+ var generateIgnore18, generatePermissions17;
21002
21048
  var init_generator25 = __esm({
21003
21049
  "src/targets/kiro/generator.ts"() {
21004
21050
  init_no_outputs();
@@ -21007,6 +21053,8 @@ var init_generator25 = __esm({
21007
21053
  init_markdown();
21008
21054
  init_hook_format3();
21009
21055
  init_constants21();
21056
+ init_ignore_output();
21057
+ generateIgnore18 = ignoreOutput(KIRO_IGNORE);
21010
21058
  generatePermissions17 = NO_OUTPUTS;
21011
21059
  }
21012
21060
  });
@@ -23649,10 +23697,6 @@ function generateMcp19(canonical) {
23649
23697
  const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
23650
23698
  return [{ path: QWEN_SETTINGS, content }];
23651
23699
  }
23652
- function generateIgnore21(canonical) {
23653
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
23654
- return [{ path: QWEN_IGNORE, content: canonical.ignore.join("\n") }];
23655
- }
23656
23700
  function generateHooks18(canonical) {
23657
23701
  if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
23658
23702
  const hooks = buildClaudeHooksObjectFromCanonical(canonical);
@@ -23670,11 +23714,14 @@ function generatePermissions21(canonical) {
23670
23714
  if (ask.length > 0) permissions.ask = ask;
23671
23715
  return [{ path: QWEN_SETTINGS, content: JSON.stringify({ permissions }, null, 2) }];
23672
23716
  }
23717
+ var generateIgnore21;
23673
23718
  var init_generator29 = __esm({
23674
23719
  "src/targets/qwen-code/generator.ts"() {
23675
23720
  init_markdown();
23676
23721
  init_hooks_format2();
23677
23722
  init_constants25();
23723
+ init_ignore_output();
23724
+ generateIgnore21 = ignoreOutput(QWEN_IGNORE);
23678
23725
  }
23679
23726
  });
23680
23727
 
@@ -25372,10 +25419,6 @@ function generateMcp23(canonical) {
25372
25419
  }
25373
25420
  ];
25374
25421
  }
25375
- function generateIgnore24(canonical) {
25376
- if (canonical.ignore.length === 0) return [];
25377
- return [{ path: TRAE_IGNORE, content: canonical.ignore.join("\n") }];
25378
- }
25379
25422
  function generateHooks20(canonical) {
25380
25423
  if (!canonical.hooks) return [];
25381
25424
  const hooks = {};
@@ -25396,12 +25439,15 @@ function generateHooks20(canonical) {
25396
25439
  if (Object.keys(hooks).length === 0) return [];
25397
25440
  return [{ path: TRAE_HOOKS_FILE, content: JSON.stringify({ version: 1, hooks }, null, 2) }];
25398
25441
  }
25442
+ var generateIgnore24;
25399
25443
  var init_generator33 = __esm({
25400
25444
  "src/targets/trae/generator.ts"() {
25401
25445
  init_embedded_skill();
25402
25446
  init_markdown();
25403
25447
  init_hook_command();
25404
25448
  init_constants29();
25449
+ init_ignore_output();
25450
+ generateIgnore24 = ignoreOutput(TRAE_IGNORE);
25405
25451
  }
25406
25452
  });
25407
25453
 
@@ -25776,7 +25822,7 @@ var init_importer30 = __esm({
25776
25822
  });
25777
25823
 
25778
25824
  // src/targets/trae/merge.ts
25779
- var mergeMcp6, mergeHooks4, mergeTraeOutput;
25825
+ var mergeMcp6, mergeHooks3, mergeTraeOutput;
25780
25826
  var init_merge12 = __esm({
25781
25827
  "src/targets/trae/merge.ts"() {
25782
25828
  init_target_descriptor();
@@ -25787,11 +25833,11 @@ var init_merge12 = __esm({
25787
25833
  [TRAE_MCP_FILE, TRAE_GLOBAL_MCP_FILE],
25788
25834
  CANONICAL_MCP_SERVER_KEYS
25789
25835
  );
25790
- mergeHooks4 = ownedJsonKeysMerger(
25836
+ mergeHooks3 = ownedJsonKeysMerger(
25791
25837
  [TRAE_HOOKS_FILE, TRAE_GLOBAL_HOOKS_FILE],
25792
25838
  ["version", "hooks"]
25793
25839
  );
25794
- mergeTraeOutput = firstMerger([mergeMcp6, mergeHooks4]);
25840
+ mergeTraeOutput = firstMerger([mergeMcp6, mergeHooks3]);
25795
25841
  }
25796
25842
  });
25797
25843
 
@@ -26108,11 +26154,7 @@ function generateMcp24(canonical, ctx) {
26108
26154
  const content = JSON.stringify({ mcpServers: canonical.mcp.mcpServers }, null, 2);
26109
26155
  return [{ path, content }];
26110
26156
  }
26111
- function generateIgnore25(canonical) {
26112
- if (canonical.ignore.length === 0) return [];
26113
- return [{ path: WARP_IGNORE_FILE, content: canonical.ignore.join("\n") }];
26114
- }
26115
- var generateRules31, generatePermissions24, generateHooks21;
26157
+ var generateRules31, generatePermissions24, generateHooks21, generateIgnore25;
26116
26158
  var init_generator34 = __esm({
26117
26159
  "src/targets/warp/generator.ts"() {
26118
26160
  init_managed_blocks();
@@ -26121,9 +26163,11 @@ var init_generator34 = __esm({
26121
26163
  init_projected_agent_skill();
26122
26164
  init_command_skill();
26123
26165
  init_constants30();
26166
+ init_ignore_output();
26124
26167
  generateRules31 = (canonical) => embeddedRootRule(canonical, WARP_TARGET, WARP_ROOT_FILE);
26125
26168
  generatePermissions24 = NO_OUTPUTS;
26126
26169
  generateHooks21 = NO_OUTPUTS;
26170
+ generateIgnore25 = ignoreOutput(WARP_IGNORE_FILE);
26127
26171
  }
26128
26172
  });
26129
26173
 
@@ -26748,13 +26792,12 @@ var init_rules4 = __esm({
26748
26792
  });
26749
26793
 
26750
26794
  // src/targets/windsurf/generator/ignore.ts
26751
- function generateIgnore26(canonical) {
26752
- if (!canonical.ignore || canonical.ignore.length === 0) return [];
26753
- return [{ path: CODEIUM_IGNORE, content: canonical.ignore.join("\n") }];
26754
- }
26795
+ var generateIgnore26;
26755
26796
  var init_ignore3 = __esm({
26756
26797
  "src/targets/windsurf/generator/ignore.ts"() {
26757
26798
  init_constants34();
26799
+ init_ignore_output();
26800
+ generateIgnore26 = ignoreOutput(CODEIUM_IGNORE);
26758
26801
  }
26759
26802
  });
26760
26803
 
@@ -26820,7 +26863,7 @@ function canonicalHookEventName(event) {
26820
26863
  if (KNOWN_CANONICAL_HOOK_EVENTS.includes(event)) return event;
26821
26864
  return WINDSURF_TO_CANONICAL.get(event) ?? null;
26822
26865
  }
26823
- var KNOWN_CANONICAL_HOOK_EVENTS, WINDSURF_TO_CANONICAL;
26866
+ var KNOWN_CANONICAL_HOOK_EVENTS, WINDSURF_HOOK_CONTEXT_EVENTS, WINDSURF_TO_CANONICAL;
26824
26867
  var init_hook_events = __esm({
26825
26868
  "src/targets/windsurf/hook-events.ts"() {
26826
26869
  init_hook_types();
@@ -26833,6 +26876,7 @@ var init_hook_events = __esm({
26833
26876
  "SubagentStop",
26834
26877
  ...BEST_EFFORT_HOOK_EVENTS
26835
26878
  ];
26879
+ WINDSURF_HOOK_CONTEXT_EVENTS = [];
26836
26880
  WINDSURF_TO_CANONICAL = new Map(
26837
26881
  KNOWN_CANONICAL_HOOK_EVENTS.map((event) => [windsurfEventName(event), event])
26838
26882
  );
@@ -26858,12 +26902,12 @@ function toWindsurfHooks(hooks) {
26858
26902
  return result2;
26859
26903
  }
26860
26904
  function generateHooks22(canonical) {
26861
- if (!canonical.hooks || Object.keys(canonical.hooks).length === 0) return [];
26905
+ if (!canonical.hooks) return [];
26862
26906
  const hooks = toWindsurfHooks(canonical.hooks);
26863
26907
  if (Object.keys(hooks).length === 0) return [];
26864
26908
  return [{ path: WINDSURF_HOOKS_FILE, content: JSON.stringify({ hooks }, null, 2) }];
26865
26909
  }
26866
- var init_hooks5 = __esm({
26910
+ var init_hooks6 = __esm({
26867
26911
  "src/targets/windsurf/generator/hooks.ts"() {
26868
26912
  init_hook_command();
26869
26913
  init_constants34();
@@ -26915,7 +26959,7 @@ var init_generator35 = __esm({
26915
26959
  init_workflows();
26916
26960
  init_agents4();
26917
26961
  init_mcp4();
26918
- init_hooks5();
26962
+ init_hooks6();
26919
26963
  init_skills4();
26920
26964
  init_permissions6();
26921
26965
  }
@@ -27253,7 +27297,7 @@ var init_importer32 = __esm({
27253
27297
  });
27254
27298
 
27255
27299
  // src/targets/windsurf/merge.ts
27256
- var mergeMcp7, mergeHooks5, mergeWindsurfOutput;
27300
+ var mergeMcp7, mergeHooks4, mergeWindsurfOutput;
27257
27301
  var init_merge14 = __esm({
27258
27302
  "src/targets/windsurf/merge.ts"() {
27259
27303
  init_target_descriptor();
@@ -27261,11 +27305,11 @@ var init_merge14 = __esm({
27261
27305
  init_mcp_servers_merge();
27262
27306
  init_constants34();
27263
27307
  mergeMcp7 = mcpServersJsonMerger([WINDSURF_GLOBAL_MCP_FILE], CANONICAL_MCP_SERVER_KEYS);
27264
- mergeHooks5 = ownedJsonKeysMerger(
27308
+ mergeHooks4 = ownedJsonKeysMerger(
27265
27309
  [WINDSURF_HOOKS_FILE, WINDSURF_GLOBAL_HOOKS_FILE],
27266
27310
  ["hooks"]
27267
27311
  );
27268
- mergeWindsurfOutput = firstMerger([mergeMcp7, mergeHooks5]);
27312
+ mergeWindsurfOutput = firstMerger([mergeMcp7, mergeHooks4]);
27269
27313
  }
27270
27314
  });
27271
27315
  function lintRules32(canonical, projectRoot, _projectFiles) {
@@ -27365,6 +27409,7 @@ var init_windsurf2 = __esm({
27365
27409
  init_merge14();
27366
27410
  init_linter32();
27367
27411
  init_lint31();
27412
+ init_hook_events();
27368
27413
  init_import_map_builders();
27369
27414
  init_conversions();
27370
27415
  init_projected_agent_skill();
@@ -27496,6 +27541,7 @@ var init_windsurf2 = __esm({
27496
27541
  },
27497
27542
  emptyImportMessage: "No Windsurf config found (.windsurfrules, .windsurf/rules, .windsurfignore, or .codeiumignore).",
27498
27543
  supportsConversion: { agents: true },
27544
+ hookContextEvents: WINDSURF_HOOK_CONTEXT_EVENTS,
27499
27545
  lintRules: lintRules32,
27500
27546
  lint: {
27501
27547
  commands: lintCommands10,
@@ -29716,10 +29762,10 @@ function ruleSlug(r) {
29716
29762
  function mergeByKey(base, overlay, key) {
29717
29763
  return [...new Map([...base, ...overlay].map((item) => [key(item), item])).values()];
29718
29764
  }
29719
- function mergeCanonicalFiles(base, overlay) {
29765
+ function mergeCanonicalFiles(base, overlay, options = {}) {
29720
29766
  const mcp = mergeMcp(base.mcp, overlay.mcp);
29721
29767
  const permissions = mergePermissions(base.permissions, overlay.permissions);
29722
- const hooks = mergeHooks(base.hooks, overlay.hooks);
29768
+ const hooks = options.hooks === "combine" ? combineHooks(base.hooks, overlay.hooks) : overrideHooks(base.hooks, overlay.hooks);
29723
29769
  const ignore = mergeUniqueStrings(base.ignore, overlay.ignore);
29724
29770
  return {
29725
29771
  rules: mergeByKey(base.rules, overlay.rules, ruleSlug),
@@ -29758,17 +29804,31 @@ function mergeUniqueStrings(base, overlay) {
29758
29804
  }
29759
29805
  return merged;
29760
29806
  }
29761
- function mergeHooks(base, overlay) {
29807
+ function overrideHooks(base, overlay) {
29762
29808
  if (!base && !overlay) return null;
29763
29809
  const result2 = {};
29764
- const keys = /* @__PURE__ */ new Set([...Object.keys(base ?? {}), ...Object.keys(overlay ?? {})]);
29765
- for (const k of keys) {
29810
+ for (const k of hookEvents(base, overlay)) {
29766
29811
  const o = overlay?.[k];
29767
- const b = base?.[k];
29768
- result2[k] = o !== void 0 && o.length > 0 ? o : b ?? [];
29812
+ result2[k] = o !== void 0 && o.length > 0 ? o : base?.[k] ?? [];
29813
+ }
29814
+ return result2;
29815
+ }
29816
+ function combineHooks(first, then) {
29817
+ if (!first && !then) return null;
29818
+ const result2 = {};
29819
+ for (const k of hookEvents(first, then)) {
29820
+ const kept = first?.[k] ?? [];
29821
+ const defined = new Set(kept.map(hookKey));
29822
+ result2[k] = [...kept, ...(then?.[k] ?? []).filter((entry) => !defined.has(hookKey(entry)))];
29769
29823
  }
29770
29824
  return result2;
29771
29825
  }
29826
+ function hookEvents(a, b) {
29827
+ return [.../* @__PURE__ */ new Set([...Object.keys(a ?? {}), ...Object.keys(b ?? {})])];
29828
+ }
29829
+ function hookKey(entry) {
29830
+ return JSON.stringify([entry.type ?? "command", entry.matcher, entry.command]);
29831
+ }
29772
29832
 
29773
29833
  // src/config/resolve/native-format-detector.ts
29774
29834
  init_fs();
@@ -30709,7 +30769,7 @@ async function loadPacksCanonical(abDir) {
30709
30769
  const canonical = await loadPackCanonical(packDir);
30710
30770
  const filtered = filterCanonicalByFeatures(canonical, meta.features);
30711
30771
  const picked = applyExtendPick(filtered, meta.features, meta.pick, meta.name);
30712
- merged = mergeCanonicalFiles(merged, picked);
30772
+ merged = mergeCanonicalFiles(merged, picked, { hooks: "combine" });
30713
30773
  }
30714
30774
  return merged;
30715
30775
  }
@@ -30760,9 +30820,10 @@ async function loadCanonicalWithExtends(config, configDir, options = {}, canonic
30760
30820
  merged = mergeCanonicalFiles(merged, picked);
30761
30821
  }
30762
30822
  const packsCanonical = await loadPacksCanonical(canonicalDir);
30763
- merged = mergeCanonicalFiles(merged, packsCanonical);
30823
+ merged = mergeCanonicalFiles(merged, packsCanonical, { hooks: "combine" });
30764
30824
  const localCanonical = await loadCanonicalFiles(canonicalDir);
30765
30825
  merged = mergeCanonicalFiles(merged, localCanonical);
30826
+ merged = { ...merged, hooks: combineHooks(merged.hooks, packsCanonical.hooks) };
30766
30827
  return { canonical: merged, resolvedExtends };
30767
30828
  }
30768
30829