@contextstream/mcp-server 0.4.65 → 0.4.67

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.
@@ -1159,10 +1159,12 @@ var init_files = __esm({
1159
1159
  // src/hooks-config.ts
1160
1160
  var hooks_config_exports = {};
1161
1161
  __export(hooks_config_exports, {
1162
+ CLAUDE_ENFORCEMENT_CRITICAL_HOOKS: () => CLAUDE_ENFORCEMENT_CRITICAL_HOOKS,
1162
1163
  CLINE_POSTTOOLUSE_HOOK_SCRIPT: () => CLINE_POSTTOOLUSE_HOOK_SCRIPT,
1163
1164
  CLINE_PRETOOLUSE_HOOK_SCRIPT: () => CLINE_PRETOOLUSE_HOOK_SCRIPT,
1164
1165
  CLINE_USER_PROMPT_HOOK_SCRIPT: () => CLINE_USER_PROMPT_HOOK_SCRIPT,
1165
1166
  CURSOR_BEFORE_SUBMIT_HOOK_SCRIPT: () => CURSOR_BEFORE_SUBMIT_HOOK_SCRIPT,
1167
+ CURSOR_ENFORCEMENT_CRITICAL_HOOKS: () => CURSOR_ENFORCEMENT_CRITICAL_HOOKS,
1166
1168
  CURSOR_PRETOOLUSE_HOOK_SCRIPT: () => CURSOR_PRETOOLUSE_HOOK_SCRIPT,
1167
1169
  MEDIA_AWARE_HOOK_SCRIPT: () => MEDIA_AWARE_HOOK_SCRIPT,
1168
1170
  PRECOMPACT_HOOK_SCRIPT: () => PRECOMPACT_HOOK_SCRIPT,
@@ -1181,6 +1183,7 @@ __export(hooks_config_exports, {
1181
1183
  getIndexStatusPath: () => getIndexStatusPath,
1182
1184
  getKiloCodeHooksDir: () => getKiloCodeHooksDir,
1183
1185
  getRooCodeHooksDir: () => getRooCodeHooksDir,
1186
+ getWindsurfHooksConfigPath: () => getWindsurfHooksConfigPath,
1184
1187
  installAllEditorHooks: () => installAllEditorHooks,
1185
1188
  installClaudeCodeHooks: () => installClaudeCodeHooks,
1186
1189
  installClineHookScripts: () => installClineHookScripts,
@@ -1189,15 +1192,18 @@ __export(hooks_config_exports, {
1189
1192
  installHookScripts: () => installHookScripts,
1190
1193
  installKiloCodeHookScripts: () => installKiloCodeHookScripts,
1191
1194
  installRooCodeHookScripts: () => installRooCodeHookScripts,
1195
+ installWindsurfHookScripts: () => installWindsurfHookScripts,
1192
1196
  markProjectIndexed: () => markProjectIndexed,
1193
1197
  mergeHooksIntoSettings: () => mergeHooksIntoSettings,
1194
1198
  readClaudeSettings: () => readClaudeSettings,
1195
1199
  readCursorHooksConfig: () => readCursorHooksConfig,
1196
1200
  readIndexStatus: () => readIndexStatus,
1201
+ readWindsurfHooksConfig: () => readWindsurfHooksConfig,
1197
1202
  unmarkProjectIndexed: () => unmarkProjectIndexed,
1198
1203
  writeClaudeSettings: () => writeClaudeSettings,
1199
1204
  writeCursorHooksConfig: () => writeCursorHooksConfig,
1200
- writeIndexStatus: () => writeIndexStatus
1205
+ writeIndexStatus: () => writeIndexStatus,
1206
+ writeWindsurfHooksConfig: () => writeWindsurfHooksConfig
1201
1207
  });
1202
1208
  import * as fs3 from "node:fs/promises";
1203
1209
  import * as fsSync from "node:fs";
@@ -1307,6 +1313,18 @@ function buildHooksConfig(options) {
1307
1313
  ]
1308
1314
  }
1309
1315
  ];
1316
+ config.PostCompact = [
1317
+ {
1318
+ matcher: "*",
1319
+ hooks: [
1320
+ {
1321
+ type: "command",
1322
+ command: getHookCommand("post-compact"),
1323
+ timeout: 15
1324
+ }
1325
+ ]
1326
+ }
1327
+ ];
1310
1328
  }
1311
1329
  if (options?.includeSessionInit !== false) {
1312
1330
  config.SessionStart = [
@@ -1321,6 +1339,102 @@ function buildHooksConfig(options) {
1321
1339
  ]
1322
1340
  }
1323
1341
  ];
1342
+ config.InstructionsLoaded = [
1343
+ {
1344
+ matcher: "*",
1345
+ hooks: [
1346
+ {
1347
+ type: "command",
1348
+ command: getHookCommand("instructions-loaded"),
1349
+ timeout: 10
1350
+ }
1351
+ ]
1352
+ }
1353
+ ];
1354
+ config.ConfigChange = [
1355
+ {
1356
+ matcher: "*",
1357
+ hooks: [
1358
+ {
1359
+ type: "command",
1360
+ command: getHookCommand("config-change"),
1361
+ timeout: 10
1362
+ }
1363
+ ]
1364
+ }
1365
+ ];
1366
+ config.CwdChanged = [
1367
+ {
1368
+ matcher: "*",
1369
+ hooks: [
1370
+ {
1371
+ type: "command",
1372
+ command: getHookCommand("cwd-changed"),
1373
+ timeout: 10
1374
+ }
1375
+ ]
1376
+ }
1377
+ ];
1378
+ config.FileChanged = [
1379
+ {
1380
+ matcher: ".*",
1381
+ hooks: [
1382
+ {
1383
+ type: "command",
1384
+ command: getHookCommand("file-changed"),
1385
+ timeout: 10
1386
+ }
1387
+ ]
1388
+ }
1389
+ ];
1390
+ config.WorktreeCreate = [
1391
+ {
1392
+ matcher: "*",
1393
+ hooks: [
1394
+ {
1395
+ type: "command",
1396
+ command: getHookCommand("worktree-create"),
1397
+ timeout: 15
1398
+ }
1399
+ ]
1400
+ }
1401
+ ];
1402
+ config.WorktreeRemove = [
1403
+ {
1404
+ matcher: "*",
1405
+ hooks: [
1406
+ {
1407
+ type: "command",
1408
+ command: getHookCommand("worktree-remove"),
1409
+ timeout: 15
1410
+ }
1411
+ ]
1412
+ }
1413
+ ];
1414
+ config.Elicitation = [
1415
+ {
1416
+ matcher: ".*",
1417
+ hooks: [
1418
+ {
1419
+ type: "command",
1420
+ command: getHookCommand("elicitation"),
1421
+ timeout: 10
1422
+ }
1423
+ ]
1424
+ }
1425
+ ];
1426
+ config.ElicitationResult = [
1427
+ {
1428
+ matcher: ".*",
1429
+ hooks: [
1430
+ {
1431
+ type: "command",
1432
+ command: getHookCommand("elicitation-result"),
1433
+ timeout: 10
1434
+ }
1435
+ ]
1436
+ }
1437
+ ];
1324
1438
  }
1325
1439
  if (options?.includeSessionEnd !== false) {
1326
1440
  config.Stop = [
@@ -1347,6 +1461,18 @@ function buildHooksConfig(options) {
1347
1461
  ]
1348
1462
  }
1349
1463
  ];
1464
+ config.StopFailure = [
1465
+ {
1466
+ matcher: "*",
1467
+ hooks: [
1468
+ {
1469
+ type: "command",
1470
+ command: getHookCommand("stop-failure"),
1471
+ timeout: 10
1472
+ }
1473
+ ]
1474
+ }
1475
+ ];
1350
1476
  }
1351
1477
  const postToolUseHooks = [];
1352
1478
  if (options?.includePostWrite !== false) {
@@ -1442,6 +1568,12 @@ function buildHooksConfig(options) {
1442
1568
  hooks: [{ type: "command", command: getHookCommand("subagent-stop"), timeout: 15 }]
1443
1569
  }
1444
1570
  ];
1571
+ config.TaskCreated = [
1572
+ {
1573
+ matcher: "*",
1574
+ hooks: [{ type: "command", command: getHookCommand("task-created"), timeout: 10 }]
1575
+ }
1576
+ ];
1445
1577
  config.TaskCompleted = [
1446
1578
  {
1447
1579
  matcher: "*",
@@ -1522,11 +1654,21 @@ async function installClaudeCodeHooks(options) {
1522
1654
  getHookCommand("user-prompt-submit"),
1523
1655
  getHookCommand("on-save-intent"),
1524
1656
  getHookCommand("session-start"),
1657
+ getHookCommand("instructions-loaded"),
1658
+ getHookCommand("config-change"),
1659
+ getHookCommand("cwd-changed"),
1660
+ getHookCommand("file-changed"),
1661
+ getHookCommand("worktree-create"),
1662
+ getHookCommand("worktree-remove"),
1663
+ getHookCommand("elicitation"),
1664
+ getHookCommand("elicitation-result"),
1525
1665
  getHookCommand("stop"),
1666
+ getHookCommand("stop-failure"),
1526
1667
  getHookCommand("session-end"),
1527
1668
  getHookCommand("post-tool-use-failure"),
1528
1669
  getHookCommand("subagent-start"),
1529
1670
  getHookCommand("subagent-stop"),
1671
+ getHookCommand("task-created"),
1530
1672
  getHookCommand("task-completed"),
1531
1673
  getHookCommand("teammate-idle"),
1532
1674
  getHookCommand("notification"),
@@ -1534,6 +1676,7 @@ async function installClaudeCodeHooks(options) {
1534
1676
  );
1535
1677
  if (options.includePreCompact !== false) {
1536
1678
  result.scripts.push(getHookCommand("pre-compact"));
1679
+ result.scripts.push(getHookCommand("post-compact"));
1537
1680
  }
1538
1681
  if (options.includeMediaAware === true) {
1539
1682
  result.scripts.push(getHookCommand("media-aware"));
@@ -1828,6 +1971,15 @@ function getCursorHooksDir(scope, projectPath) {
1828
1971
  }
1829
1972
  return path3.join(projectPath, ".cursor", "hooks");
1830
1973
  }
1974
+ function getWindsurfHooksConfigPath(scope, projectPath) {
1975
+ if (scope === "global") {
1976
+ return path3.join(homedir2(), ".codeium", "windsurf", "hooks.json");
1977
+ }
1978
+ if (!projectPath) {
1979
+ throw new Error("projectPath required for project scope");
1980
+ }
1981
+ return path3.join(projectPath, ".windsurf", "hooks.json");
1982
+ }
1831
1983
  async function readCursorHooksConfig(scope, projectPath) {
1832
1984
  const configPath = getCursorHooksConfigPath(scope, projectPath);
1833
1985
  try {
@@ -1854,17 +2006,31 @@ async function installCursorHookScripts(options) {
1854
2006
  return !hook.command?.includes("contextstream");
1855
2007
  });
1856
2008
  };
1857
- const filteredPreToolUse = filterContextStreamHooks(existingConfig.hooks.preToolUse);
1858
- const filteredBeforeSubmit = filterContextStreamHooks(existingConfig.hooks.beforeSubmitPrompt);
2009
+ const cleanedHooks = {};
2010
+ for (const [eventName, entries] of Object.entries(existingConfig.hooks || {})) {
2011
+ cleanedHooks[eventName] = filterContextStreamHooks(entries);
2012
+ }
1859
2013
  const preToolUseCommand = getHookCommand("pre-tool-use");
1860
2014
  const userPromptCommand = getHookCommand("user-prompt-submit");
1861
2015
  const saveIntentCommand = getHookCommand("on-save-intent");
2016
+ const postToolUseCommand = getHookCommand("post-tool-use");
2017
+ const postToolUseFailureCommand = getHookCommand("post-tool-use-failure");
2018
+ const preCompactCommand = getHookCommand("pre-compact");
2019
+ const sessionStartCommand = getHookCommand("session-start");
2020
+ const sessionEndCommand = getHookCommand("session-end");
2021
+ const stopCommand = getHookCommand("stop");
2022
+ const notificationCommand = getHookCommand("notification");
2023
+ const permissionRequestCommand = getHookCommand("permission-request");
2024
+ const subagentStartCommand = getHookCommand("subagent-start");
2025
+ const subagentStopCommand = getHookCommand("subagent-stop");
2026
+ const taskCompletedCommand = getHookCommand("task-completed");
2027
+ const teammateIdleCommand = getHookCommand("teammate-idle");
1862
2028
  const config = {
1863
2029
  version: 1,
1864
2030
  hooks: {
1865
- ...existingConfig.hooks,
2031
+ ...cleanedHooks,
1866
2032
  preToolUse: [
1867
- ...filteredPreToolUse,
2033
+ ...cleanedHooks.preToolUse || [],
1868
2034
  {
1869
2035
  command: preToolUseCommand,
1870
2036
  type: "command",
@@ -1872,7 +2038,7 @@ async function installCursorHookScripts(options) {
1872
2038
  }
1873
2039
  ],
1874
2040
  beforeSubmitPrompt: [
1875
- ...filteredBeforeSubmit,
2041
+ ...cleanedHooks.beforeSubmitPrompt || [],
1876
2042
  {
1877
2043
  command: userPromptCommand,
1878
2044
  type: "command",
@@ -1883,6 +2049,70 @@ async function installCursorHookScripts(options) {
1883
2049
  type: "command",
1884
2050
  timeout: 5
1885
2051
  }
2052
+ ],
2053
+ beforeMCPExecution: [
2054
+ ...cleanedHooks.beforeMCPExecution || [],
2055
+ { command: preToolUseCommand, type: "command", timeout: 5 }
2056
+ ],
2057
+ afterMCPExecution: [
2058
+ ...cleanedHooks.afterMCPExecution || [],
2059
+ { command: postToolUseCommand, type: "command", timeout: 10 }
2060
+ ],
2061
+ beforeShellExecution: [
2062
+ ...cleanedHooks.beforeShellExecution || [],
2063
+ { command: preToolUseCommand, type: "command", timeout: 5 }
2064
+ ],
2065
+ afterShellExecution: [
2066
+ ...cleanedHooks.afterShellExecution || [],
2067
+ { command: postToolUseFailureCommand, type: "command", timeout: 10 }
2068
+ ],
2069
+ beforeReadFile: [
2070
+ ...cleanedHooks.beforeReadFile || [],
2071
+ { command: preToolUseCommand, type: "command", timeout: 5 }
2072
+ ],
2073
+ afterFileEdit: [
2074
+ ...cleanedHooks.afterFileEdit || [],
2075
+ { command: postToolUseCommand, type: "command", timeout: 10 }
2076
+ ],
2077
+ preCompact: [
2078
+ ...cleanedHooks.preCompact || [],
2079
+ { command: preCompactCommand, type: "command", timeout: 15 }
2080
+ ],
2081
+ sessionStart: [
2082
+ ...cleanedHooks.sessionStart || [],
2083
+ { command: sessionStartCommand, type: "command", timeout: 15 }
2084
+ ],
2085
+ sessionEnd: [
2086
+ ...cleanedHooks.sessionEnd || [],
2087
+ { command: sessionEndCommand, type: "command", timeout: 10 }
2088
+ ],
2089
+ stop: [
2090
+ ...cleanedHooks.stop || [],
2091
+ { command: stopCommand, type: "command", timeout: 15 }
2092
+ ],
2093
+ subagentStart: [
2094
+ ...cleanedHooks.subagentStart || [],
2095
+ { command: subagentStartCommand, type: "command", timeout: 10 }
2096
+ ],
2097
+ subagentStop: [
2098
+ ...cleanedHooks.subagentStop || [],
2099
+ { command: subagentStopCommand, type: "command", timeout: 10 }
2100
+ ],
2101
+ taskCompleted: [
2102
+ ...cleanedHooks.taskCompleted || [],
2103
+ { command: taskCompletedCommand, type: "command", timeout: 10 }
2104
+ ],
2105
+ teammateIdle: [
2106
+ ...cleanedHooks.teammateIdle || [],
2107
+ { command: teammateIdleCommand, type: "command", timeout: 10 }
2108
+ ],
2109
+ notification: [
2110
+ ...cleanedHooks.notification || [],
2111
+ { command: notificationCommand, type: "command", timeout: 10 }
2112
+ ],
2113
+ permissionRequest: [
2114
+ ...cleanedHooks.permissionRequest || [],
2115
+ { command: permissionRequestCommand, type: "command", timeout: 10 }
1886
2116
  ]
1887
2117
  }
1888
2118
  };
@@ -1894,6 +2124,83 @@ async function installCursorHookScripts(options) {
1894
2124
  config: configPath
1895
2125
  };
1896
2126
  }
2127
+ async function readWindsurfHooksConfig(scope, projectPath) {
2128
+ const configPath = getWindsurfHooksConfigPath(scope, projectPath);
2129
+ try {
2130
+ const content = await fs3.readFile(configPath, "utf-8");
2131
+ return JSON.parse(content);
2132
+ } catch {
2133
+ return { hooks: {} };
2134
+ }
2135
+ }
2136
+ async function writeWindsurfHooksConfig(config, scope, projectPath) {
2137
+ const configPath = getWindsurfHooksConfigPath(scope, projectPath);
2138
+ const dir = path3.dirname(configPath);
2139
+ await fs3.mkdir(dir, { recursive: true });
2140
+ await fs3.writeFile(configPath, JSON.stringify(config, null, 2));
2141
+ }
2142
+ async function installWindsurfHookScripts(options) {
2143
+ const existingConfig = await readWindsurfHooksConfig(options.scope, options.projectPath);
2144
+ const filterContextStreamHooks = (hooks) => {
2145
+ if (!hooks) return [];
2146
+ return hooks.filter((h) => {
2147
+ const hook = h;
2148
+ return !hook.command?.toLowerCase().includes("contextstream");
2149
+ });
2150
+ };
2151
+ const cleanedHooks = {};
2152
+ for (const [eventName, entries] of Object.entries(existingConfig.hooks || {})) {
2153
+ cleanedHooks[eventName] = filterContextStreamHooks(entries);
2154
+ }
2155
+ const preToolUseCommand = getHookCommand("pre-tool-use");
2156
+ const userPromptCommand = getHookCommand("user-prompt-submit");
2157
+ const postToolUseCommand = getHookCommand("post-tool-use");
2158
+ const sessionEndCommand = getHookCommand("session-end");
2159
+ const config = {
2160
+ hooks: {
2161
+ ...cleanedHooks,
2162
+ pre_mcp_tool_use: [
2163
+ ...cleanedHooks.pre_mcp_tool_use || [],
2164
+ { command: preToolUseCommand, show_output: true }
2165
+ ],
2166
+ pre_user_prompt: [
2167
+ ...cleanedHooks.pre_user_prompt || [],
2168
+ { command: userPromptCommand }
2169
+ ],
2170
+ pre_read_code: [
2171
+ ...cleanedHooks.pre_read_code || [],
2172
+ { command: preToolUseCommand, show_output: true }
2173
+ ],
2174
+ pre_write_code: [
2175
+ ...cleanedHooks.pre_write_code || [],
2176
+ { command: preToolUseCommand, show_output: true }
2177
+ ],
2178
+ pre_run_command: [
2179
+ ...cleanedHooks.pre_run_command || [],
2180
+ { command: preToolUseCommand, show_output: true }
2181
+ ],
2182
+ post_write_code: [
2183
+ ...cleanedHooks.post_write_code || [],
2184
+ { command: postToolUseCommand, show_output: false }
2185
+ ],
2186
+ post_mcp_tool_use: [
2187
+ ...cleanedHooks.post_mcp_tool_use || [],
2188
+ { command: postToolUseCommand, show_output: false }
2189
+ ],
2190
+ post_cascade_response_with_transcript: [
2191
+ ...cleanedHooks.post_cascade_response_with_transcript || [],
2192
+ { command: sessionEndCommand }
2193
+ ]
2194
+ }
2195
+ };
2196
+ await writeWindsurfHooksConfig(config, options.scope, options.projectPath);
2197
+ const configPath = getWindsurfHooksConfigPath(options.scope, options.projectPath);
2198
+ return {
2199
+ preMcpToolUse: preToolUseCommand,
2200
+ preUserPrompt: userPromptCommand,
2201
+ config: configPath
2202
+ };
2203
+ }
1897
2204
  async function installEditorHooks(options) {
1898
2205
  const { editor, scope, projectPath, includePreCompact, includePostWrite } = options;
1899
2206
  switch (editor) {
@@ -1953,12 +2260,20 @@ async function installEditorHooks(options) {
1953
2260
  hooksDir: getCursorHooksDir(scope, projectPath)
1954
2261
  };
1955
2262
  }
2263
+ case "windsurf": {
2264
+ const scripts = await installWindsurfHookScripts({ scope, projectPath });
2265
+ return {
2266
+ editor: "windsurf",
2267
+ installed: [scripts.preMcpToolUse, scripts.preUserPrompt, scripts.config],
2268
+ hooksDir: path3.dirname(scripts.config)
2269
+ };
2270
+ }
1956
2271
  default:
1957
2272
  throw new Error(`Unsupported editor: ${editor}`);
1958
2273
  }
1959
2274
  }
1960
2275
  async function installAllEditorHooks(options) {
1961
- const editors = options.editors || ["claude", "cline", "roo", "kilo", "cursor"];
2276
+ const editors = options.editors || ["claude", "cline", "roo", "kilo", "cursor", "windsurf"];
1962
2277
  const results = [];
1963
2278
  for (const editor of editors) {
1964
2279
  try {
@@ -1986,8 +2301,9 @@ ContextStream can install hooks for multiple AI code editors to enforce ContextS
1986
2301
 
1987
2302
  | Editor | Hooks Location | Hook Types |
1988
2303
  |--------|---------------|------------|
1989
- | **Claude Code** | \`~/.claude/hooks/\` | PreToolUse, UserPromptSubmit, PreCompact |
1990
- | **Cursor** | \`~/.cursor/hooks/\` | preToolUse, beforeSubmit |
2304
+ | **Claude Code** | \`~/.claude/hooks/\` | PreToolUse, UserPromptSubmit, SessionStart, Pre/PostCompact, PostToolUse |
2305
+ | **Cursor** | \`~/.cursor/hooks/\` | preToolUse, beforeSubmitPrompt, before/after MCP+Shell, beforeReadFile, afterFileEdit |
2306
+ | **Windsurf** | \`~/.codeium/windsurf/hooks.json\` | pre_mcp_tool_use, pre_user_prompt, pre/post code + command hooks |
1991
2307
  | **Cline** | \`~/Documents/Cline/Rules/Hooks/\` | PreToolUse, UserPromptSubmit |
1992
2308
  | **Roo Code** | \`~/.roo/hooks/\` | PreToolUse, UserPromptSubmit |
1993
2309
  | **Kilo Code** | \`~/.kilocode/hooks/\` | PreToolUse, UserPromptSubmit |
@@ -1998,9 +2314,19 @@ ${generateHooksDocumentation()}
1998
2314
 
1999
2315
  ### Cursor Hooks
2000
2316
 
2001
- Cursor uses a \`hooks.json\` configuration file:
2002
- - **preToolUse**: Blocks discovery tools before execution
2003
- - **beforeSubmitPrompt**: Injects ContextStream rules reminder
2317
+ Cursor uses a \`hooks.json\` configuration file with enforcement + lifecycle hooks:
2318
+ - **preToolUse / beforeMCPExecution / beforeShellExecution / beforeReadFile**: blocks or redirects non-ContextStream-first flows
2319
+ - **beforeSubmitPrompt**: injects ContextStream rules reminder + save-intent capture
2320
+ - **afterMCPExecution / afterShellExecution / afterFileEdit**: post-action bookkeeping/index updates
2321
+ - **sessionStart / preCompact / stop / sessionEnd**: lifecycle persistence and reliability
2322
+
2323
+ ### Windsurf Hooks
2324
+
2325
+ Windsurf uses a \`hooks.json\` configuration file:
2326
+ - **pre_mcp_tool_use / pre_read_code / pre_write_code / pre_run_command**: pre-action gating and enforcement
2327
+ - **pre_user_prompt**: injects ContextStream-first guidance each prompt
2328
+ - **post_write_code / post_mcp_tool_use**: post-action indexing bookkeeping
2329
+ - **post_cascade_response_with_transcript**: end-of-response/session capture
2004
2330
 
2005
2331
  #### Output Format
2006
2332
  \`\`\`json
@@ -2030,7 +2356,7 @@ Hooks are executable scripts named after the hook type (no extension).
2030
2356
 
2031
2357
  ### Installation
2032
2358
 
2033
- Use \`generate_rules(install_hooks=true, editors=["claude", "cursor", "cline", "roo", "kilo"])\` to install hooks for specific editors, or omit \`editors\` to install for all.
2359
+ Use \`generate_rules(install_hooks=true, editors=["claude", "cursor", "windsurf", "cline", "roo", "kilo"])\` to install hooks for specific editors, or omit \`editors\` to install for all.
2034
2360
 
2035
2361
  ### Disabling Hooks
2036
2362
 
@@ -2039,7 +2365,7 @@ Set environment variables:
2039
2365
  - \`CONTEXTSTREAM_REMINDER_ENABLED=false\` - Disable UserPromptSubmit reminders
2040
2366
  `.trim();
2041
2367
  }
2042
- var PRETOOLUSE_HOOK_SCRIPT, USER_PROMPT_HOOK_SCRIPT, MEDIA_AWARE_HOOK_SCRIPT, PRECOMPACT_HOOK_SCRIPT, CLINE_PRETOOLUSE_HOOK_SCRIPT, CLINE_USER_PROMPT_HOOK_SCRIPT, CLINE_POSTTOOLUSE_HOOK_SCRIPT, CURSOR_PRETOOLUSE_HOOK_SCRIPT, CURSOR_BEFORE_SUBMIT_HOOK_SCRIPT;
2368
+ var PRETOOLUSE_HOOK_SCRIPT, USER_PROMPT_HOOK_SCRIPT, MEDIA_AWARE_HOOK_SCRIPT, PRECOMPACT_HOOK_SCRIPT, CLAUDE_ENFORCEMENT_CRITICAL_HOOKS, CURSOR_ENFORCEMENT_CRITICAL_HOOKS, CLINE_PRETOOLUSE_HOOK_SCRIPT, CLINE_USER_PROMPT_HOOK_SCRIPT, CLINE_POSTTOOLUSE_HOOK_SCRIPT, CURSOR_PRETOOLUSE_HOOK_SCRIPT, CURSOR_BEFORE_SUBMIT_HOOK_SCRIPT;
2043
2369
  var init_hooks_config = __esm({
2044
2370
  "src/hooks-config.ts"() {
2045
2371
  "use strict";
@@ -2520,6 +2846,23 @@ After compaction, call session_init(is_post_compact=true) to restore context.
2520
2846
  if __name__ == "__main__":
2521
2847
  main()
2522
2848
  `;
2849
+ CLAUDE_ENFORCEMENT_CRITICAL_HOOKS = [
2850
+ "PreToolUse",
2851
+ "UserPromptSubmit",
2852
+ "SessionStart",
2853
+ "PreCompact",
2854
+ "PostToolUse"
2855
+ ];
2856
+ CURSOR_ENFORCEMENT_CRITICAL_HOOKS = [
2857
+ "preToolUse",
2858
+ "beforeSubmitPrompt",
2859
+ "beforeMCPExecution",
2860
+ "beforeShellExecution",
2861
+ "beforeReadFile",
2862
+ "afterFileEdit",
2863
+ "sessionStart",
2864
+ "preCompact"
2865
+ ];
2523
2866
  CLINE_PRETOOLUSE_HOOK_SCRIPT = `#!/usr/bin/env python3
2524
2867
  """
2525
2868
  ContextStream PreToolUse Hook for Cline
@@ -2410,6 +2410,9 @@ ${options.workspaceId ? `# Workspace ID: ${options.workspaceId}` : ""}
2410
2410
  if (NO_HOOKS_EDITORS.includes(editor.toLowerCase())) {
2411
2411
  content += NO_HOOKS_SUPPLEMENT;
2412
2412
  }
2413
+ if (editor.toLowerCase() === "antigravity") {
2414
+ content += ANTIGRAVITY_SUPPLEMENT;
2415
+ }
2413
2416
  if (options?.additionalRules) {
2414
2417
  content += "\n\n## Project-Specific Rules\n\n" + options.additionalRules;
2415
2418
  }
@@ -2421,7 +2424,7 @@ ${options.workspaceId ? `# Workspace ID: ${options.workspaceId}` : ""}
2421
2424
  content: content.trim() + "\n"
2422
2425
  };
2423
2426
  }
2424
- var DEFAULT_CLAUDE_MCP_SERVER_NAME, RULES_VERSION, CONTEXTSTREAM_TOOL_NAMES, CONTEXTSTREAM_RULES_BOOTSTRAP, CONTEXTSTREAM_RULES_DYNAMIC, CONTEXTSTREAM_RULES_FULL, CONTEXTSTREAM_RULES_MINIMAL, NO_HOOKS_SUPPLEMENT, NO_HOOKS_EDITORS, TEMPLATES;
2427
+ var DEFAULT_CLAUDE_MCP_SERVER_NAME, RULES_VERSION, CONTEXTSTREAM_TOOL_NAMES, CONTEXTSTREAM_RULES_BOOTSTRAP, CONTEXTSTREAM_RULES_DYNAMIC, CONTEXTSTREAM_RULES_FULL, CONTEXTSTREAM_RULES_MINIMAL, NO_HOOKS_SUPPLEMENT, ANTIGRAVITY_SUPPLEMENT, NO_HOOKS_EDITORS, TEMPLATES;
2425
2428
  var init_rules_templates = __esm({
2426
2429
  "src/rules-templates.ts"() {
2427
2430
  "use strict";
@@ -3353,13 +3356,32 @@ After updating, user should restart their AI tool.
3353
3356
 
3354
3357
  ---
3355
3358
  `;
3356
- NO_HOOKS_EDITORS = ["codex", "aider", "antigravity"];
3359
+ ANTIGRAVITY_SUPPLEMENT = `
3360
+ ---
3361
+ ## Antigravity-Specific Reliability Notes
3362
+
3363
+ - Antigravity currently has no documented lifecycle hooks for ContextStream enforcement.
3364
+ - Treat ContextStream-first behavior as mandatory policy: run \`context(...)\` first, then \`search(mode="auto", ...)\` before local discovery.
3365
+ - Keep \`mcp_config.json\` valid and minimal: preserve non-ContextStream servers and only update the \`contextstream\` server block.
3366
+ - If ContextStream appears skipped, verify:
3367
+ 1. MCP server status is healthy in Antigravity settings
3368
+ 2. Project is indexed and \`search(mode="auto", ...)\` is retried before local fallbacks
3369
+ 3. Instructions file contains the current ContextStream managed block
3370
+ `;
3371
+ NO_HOOKS_EDITORS = ["copilot", "codex", "opencode", "aider", "antigravity"];
3357
3372
  TEMPLATES = {
3358
3373
  codex: {
3359
3374
  filename: "AGENTS.md",
3360
3375
  description: "Codex CLI agent instructions",
3361
3376
  build: (rules) => `# Codex CLI Instructions
3362
3377
  ${rules}
3378
+ `
3379
+ },
3380
+ opencode: {
3381
+ filename: "AGENTS.md",
3382
+ description: "OpenCode CLI agent instructions",
3383
+ build: (rules) => `# OpenCode CLI Instructions
3384
+ ${rules}
3363
3385
  `
3364
3386
  },
3365
3387
  cursor: {
@@ -3367,6 +3389,17 @@ ${rules}
3367
3389
  description: "Cursor AI rules",
3368
3390
  build: (rules) => `# Cursor Rules
3369
3391
  ${rules}
3392
+ `
3393
+ },
3394
+ windsurf: {
3395
+ filename: ".windsurf/rules/contextstream.md",
3396
+ description: "Windsurf AI rules",
3397
+ build: (rules) => `---
3398
+ trigger: always_on
3399
+ ---
3400
+
3401
+ # Windsurf Rules
3402
+ ${rules}
3370
3403
  `
3371
3404
  },
3372
3405
  cline: {
@@ -4952,8 +4985,17 @@ var hooks = {
4952
4985
  notification: async () => (await Promise.resolve().then(() => (init_notification(), notification_exports))).runNotificationHook(),
4953
4986
  "permission-request": async () => (await Promise.resolve().then(() => (init_permission_request(), permission_request_exports))).runPermissionRequestHook(),
4954
4987
  "post-tool-use-failure": async () => (await Promise.resolve().then(() => (init_post_tool_use_failure(), post_tool_use_failure_exports))).runPostToolUseFailureHook(),
4988
+ "instructions-loaded": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4989
+ "config-change": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4990
+ "cwd-changed": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4991
+ "file-changed": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4992
+ "worktree-create": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4993
+ "worktree-remove": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4994
+ elicitation: async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4995
+ "elicitation-result": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4955
4996
  "subagent-start": async () => (await Promise.resolve().then(() => (init_subagent_start(), subagent_start_exports))).runSubagentStartHook(),
4956
4997
  "subagent-stop": async () => (await Promise.resolve().then(() => (init_subagent_stop(), subagent_stop_exports))).runSubagentStopHook(),
4998
+ "task-created": async () => (await Promise.resolve().then(() => (init_noop(), noop_exports))).runNoopHook(),
4957
4999
  "task-completed": async () => (await Promise.resolve().then(() => (init_task_completed(), task_completed_exports))).runTaskCompletedHook(),
4958
5000
  "teammate-idle": async () => (await Promise.resolve().then(() => (init_teammate_idle(), teammate_idle_exports))).runTeammateIdleHook(),
4959
5001
  "on-save-intent": async () => (await Promise.resolve().then(() => (init_on_save_intent(), on_save_intent_exports))).runOnSaveIntentHook()
@@ -1264,13 +1264,32 @@ After updating, user should restart their AI tool.
1264
1264
 
1265
1265
  ---
1266
1266
  `;
1267
- var NO_HOOKS_EDITORS = ["codex", "aider", "antigravity"];
1267
+ var ANTIGRAVITY_SUPPLEMENT = `
1268
+ ---
1269
+ ## Antigravity-Specific Reliability Notes
1270
+
1271
+ - Antigravity currently has no documented lifecycle hooks for ContextStream enforcement.
1272
+ - Treat ContextStream-first behavior as mandatory policy: run \`context(...)\` first, then \`search(mode="auto", ...)\` before local discovery.
1273
+ - Keep \`mcp_config.json\` valid and minimal: preserve non-ContextStream servers and only update the \`contextstream\` server block.
1274
+ - If ContextStream appears skipped, verify:
1275
+ 1. MCP server status is healthy in Antigravity settings
1276
+ 2. Project is indexed and \`search(mode="auto", ...)\` is retried before local fallbacks
1277
+ 3. Instructions file contains the current ContextStream managed block
1278
+ `;
1279
+ var NO_HOOKS_EDITORS = ["copilot", "codex", "opencode", "aider", "antigravity"];
1268
1280
  var TEMPLATES = {
1269
1281
  codex: {
1270
1282
  filename: "AGENTS.md",
1271
1283
  description: "Codex CLI agent instructions",
1272
1284
  build: (rules) => `# Codex CLI Instructions
1273
1285
  ${rules}
1286
+ `
1287
+ },
1288
+ opencode: {
1289
+ filename: "AGENTS.md",
1290
+ description: "OpenCode CLI agent instructions",
1291
+ build: (rules) => `# OpenCode CLI Instructions
1292
+ ${rules}
1274
1293
  `
1275
1294
  },
1276
1295
  cursor: {
@@ -1278,6 +1297,17 @@ ${rules}
1278
1297
  description: "Cursor AI rules",
1279
1298
  build: (rules) => `# Cursor Rules
1280
1299
  ${rules}
1300
+ `
1301
+ },
1302
+ windsurf: {
1303
+ filename: ".windsurf/rules/contextstream.md",
1304
+ description: "Windsurf AI rules",
1305
+ build: (rules) => `---
1306
+ trigger: always_on
1307
+ ---
1308
+
1309
+ # Windsurf Rules
1310
+ ${rules}
1281
1311
  `
1282
1312
  },
1283
1313
  cline: {
@@ -1369,6 +1399,9 @@ ${options.workspaceId ? `# Workspace ID: ${options.workspaceId}` : ""}
1369
1399
  if (NO_HOOKS_EDITORS.includes(editor.toLowerCase())) {
1370
1400
  content += NO_HOOKS_SUPPLEMENT;
1371
1401
  }
1402
+ if (editor.toLowerCase() === "antigravity") {
1403
+ content += ANTIGRAVITY_SUPPLEMENT;
1404
+ }
1372
1405
  if (options?.additionalRules) {
1373
1406
  content += "\n\n## Project-Specific Rules\n\n" + options.additionalRules;
1374
1407
  }