@contextstream/mcp-server 0.4.57 → 0.4.59

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.
@@ -1,12 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined") return require.apply(this, arguments);
8
- throw Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
4
  var __esm = (fn, res) => function __init() {
11
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
6
  };
@@ -187,7 +181,7 @@ async function runPreToolUseHook() {
187
181
  fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Glob pattern=${pattern}, isDiscovery=${isDiscoveryGlob(pattern)}
188
182
  `);
189
183
  if (isDiscoveryGlob(pattern)) {
190
- const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of Glob.`;
184
+ const msg = `STOP: Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of Glob.`;
191
185
  fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Intercepting discovery glob: ${msg}
192
186
  `);
193
187
  if (editorFormat === "cline") {
@@ -210,7 +204,7 @@ async function runPreToolUseHook() {
210
204
  }
211
205
  blockClaudeCode(msg);
212
206
  } else {
213
- const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of ${tool}.`;
207
+ const msg = `STOP: Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of ${tool}.`;
214
208
  if (editorFormat === "cline") {
215
209
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
216
210
  } else if (editorFormat === "cursor") {
@@ -222,7 +216,7 @@ async function runPreToolUseHook() {
222
216
  } else if (tool === "Task") {
223
217
  const subagentType = toolInput?.subagent_type?.toLowerCase() || "";
224
218
  if (subagentType === "explore") {
225
- const msg = 'STOP: Use mcp__contextstream__search(mode="hybrid") instead of Task(Explore).';
219
+ const msg = 'STOP: Use mcp__contextstream__search(mode="auto") instead of Task(Explore).';
226
220
  if (editorFormat === "cline") {
227
221
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
228
222
  } else if (editorFormat === "cursor") {
@@ -251,7 +245,7 @@ async function runPreToolUseHook() {
251
245
  if (tool === "list_files" || tool === "search_files") {
252
246
  const pattern = toolInput?.path || toolInput?.regex || "";
253
247
  if (isDiscoveryGlob(pattern) || isDiscoveryGrep(pattern)) {
254
- const msg = `Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of ${tool}. ContextStream search is indexed and faster.`;
248
+ const msg = `Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of ${tool}. ContextStream search is indexed and faster.`;
255
249
  if (editorFormat === "cline") {
256
250
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
257
251
  } else if (editorFormat === "cursor") {
@@ -451,7 +445,7 @@ var init_version = __esm({
451
445
  };
452
446
  UPGRADE_COMMAND = UPDATE_COMMANDS.npm;
453
447
  VERSION = getVersion();
454
- CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
448
+ CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
455
449
  latestVersionPromise = null;
456
450
  }
457
451
  });
@@ -683,6 +677,34 @@ async function saveLastExchange(exchange, cwd, clientName) {
683
677
  } catch {
684
678
  }
685
679
  }
680
+ async function fetchHookContext() {
681
+ if (!API_KEY) return null;
682
+ try {
683
+ const controller = new AbortController();
684
+ const timeoutId = setTimeout(() => controller.abort(), 2e3);
685
+ const url = `${API_URL}/api/v1/context/hook`;
686
+ const body = {};
687
+ if (WORKSPACE_ID) body.workspace_id = WORKSPACE_ID;
688
+ if (PROJECT_ID) body.project_id = PROJECT_ID;
689
+ const response = await fetch(url, {
690
+ method: "POST",
691
+ headers: {
692
+ "X-API-Key": API_KEY,
693
+ "Content-Type": "application/json"
694
+ },
695
+ body: JSON.stringify(body),
696
+ signal: controller.signal
697
+ });
698
+ clearTimeout(timeoutId);
699
+ if (response.ok) {
700
+ const data = await response.json();
701
+ return data?.data?.context || null;
702
+ }
703
+ return null;
704
+ } catch {
705
+ return null;
706
+ }
707
+ }
686
708
  async function fetchSessionContext() {
687
709
  if (!API_KEY) return null;
688
710
  try {
@@ -761,26 +783,6 @@ function transformSmartContextResponse(data) {
761
783
  return null;
762
784
  }
763
785
  }
764
- function buildClaudeReminder(ctx, versionNotice) {
765
- const parts = [];
766
- if (versionNotice?.behind) {
767
- const versionInfo = getVersionNoticeForHook(versionNotice);
768
- if (versionInfo) {
769
- parts.push(versionInfo);
770
- parts.push("");
771
- }
772
- }
773
- const highImportancePrefs = ctx?.preferences?.filter((p) => p.importance === "high") || [];
774
- if (highImportancePrefs.length > 0) {
775
- parts.push(`[USER PREFERENCES - Always respect these]`);
776
- for (const pref of highImportancePrefs.slice(0, 5)) {
777
- parts.push(`\u2022 ${pref.title}: ${pref.content}`);
778
- }
779
- parts.push("");
780
- }
781
- parts.push(REMINDER);
782
- return parts.join("\n");
783
- }
784
786
  function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
785
787
  const parts = [ENHANCED_REMINDER_HEADER];
786
788
  if (versionNotice?.behind) {
@@ -798,7 +800,7 @@ function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
798
800
  2. Wait for indexing: if \`init\` returns \`indexing_status: "started"\`, files are being indexed
799
801
  3. Generate a unique session_id (e.g., "session-" + timestamp or UUID) - use this for ALL context() calls
800
802
  4. Call \`context(user_message="...", save_exchange=true, session_id="<your-session-id>")\` for task-specific context
801
- 5. Use \`search(mode="hybrid")\` for code discovery (not Glob/Grep/Read)
803
+ 5. Use \`search(mode="auto")\` for code discovery (not Glob/Grep/Read)
802
804
 
803
805
  `);
804
806
  }
@@ -839,7 +841,7 @@ function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
839
841
  parts.push("");
840
842
  }
841
843
  parts.push("---\n");
842
- parts.push(REMINDER);
844
+ parts.push(FULL_REMINDER);
843
845
  parts.push(`
844
846
 
845
847
  ---
@@ -856,7 +858,7 @@ Returns: \`indexed\` (true/false), \`last_indexed_at\`, \`file_count\`
856
858
  ### \u{1F50D} Search Decision Tree:
857
859
 
858
860
  **IF indexed=true AND last_indexed_at is recent:**
859
- \u2192 Use \`search(mode="hybrid", query="...")\`
861
+ \u2192 Use \`search(mode="auto", query="...")\`
860
862
 
861
863
  **IF indexed=false OR last_indexed_at is stale (>7 days):**
862
864
  \u2192 Use local tools (Glob/Grep/Read) directly
@@ -927,59 +929,58 @@ async function runUserPromptSubmitHook() {
927
929
  }
928
930
  const editorFormat = detectEditorFormat2(input);
929
931
  const cwd = input.cwd || process.cwd();
930
- loadConfigFromMcpJson(cwd);
931
- const versionNoticePromise = getUpdateNotice();
932
- const lastExchange = extractLastExchange(input, editorFormat);
933
- const clientName = editorFormat === "claude" ? "claude-code" : editorFormat;
934
- const saveExchangePromise = lastExchange ? saveLastExchange(lastExchange, cwd, clientName) : Promise.resolve();
935
932
  if (editorFormat === "claude") {
936
- const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
937
- const claudeReminder = buildClaudeReminder(ctx, versionNotice);
933
+ loadConfigFromMcpJson(cwd);
934
+ let context = REMINDER;
935
+ if (API_KEY) {
936
+ try {
937
+ const hookContext = await fetchHookContext();
938
+ if (hookContext) {
939
+ context = hookContext;
940
+ }
941
+ } catch {
942
+ }
943
+ }
938
944
  console.log(
939
945
  JSON.stringify({
940
946
  hookSpecificOutput: {
941
947
  hookEventName: "UserPromptSubmit",
942
- additionalContext: claudeReminder
948
+ additionalContext: context
943
949
  }
944
950
  })
945
951
  );
946
- } else if (editorFormat === "cline") {
947
- const newSession = isNewSession(input, editorFormat);
948
- const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
949
- const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
950
- console.log(
951
- JSON.stringify({
952
- cancel: false,
953
- contextModification: enhancedReminder
954
- })
955
- );
956
- } else if (editorFormat === "cursor") {
952
+ } else {
953
+ loadConfigFromMcpJson(cwd);
954
+ const versionNoticePromise = getUpdateNotice();
955
+ const lastExchange = extractLastExchange(input, editorFormat);
956
+ const clientName = editorFormat;
957
+ const saveExchangePromise = lastExchange ? saveLastExchange(lastExchange, cwd, clientName) : Promise.resolve();
957
958
  const newSession = isNewSession(input, editorFormat);
958
959
  const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
959
- let cursorReminder = ctx?.lessons?.length ? `[CONTEXTSTREAM] \u26A0\uFE0F ${ctx.lessons.length} lessons from past mistakes. Call context(save_exchange=true, session_id="...") FIRST. Use search(mode="hybrid") before Glob/Grep. After file edits: project(action="index").` : `[CONTEXTSTREAM] Call context(save_exchange=true, session_id="...") FIRST. Use search(mode="hybrid") before Glob/Grep/Read. After file edits: project(action="index").`;
960
- if (versionNotice?.behind) {
961
- cursorReminder += ` [UPDATE v${versionNotice.current}\u2192${versionNotice.latest}]`;
960
+ if (editorFormat === "cursor") {
961
+ let cursorReminder = ctx?.lessons?.length ? `[CONTEXTSTREAM] \u26A0\uFE0F ${ctx.lessons.length} lessons from past mistakes. Call context(save_exchange=true, session_id="...") FIRST. Use search(mode="auto") before Glob/Grep. After file edits: project(action="index").` : `[CONTEXTSTREAM] Call context(save_exchange=true, session_id="...") FIRST. Use search(mode="auto") before Glob/Grep/Read. After file edits: project(action="index").`;
962
+ if (versionNotice?.behind) {
963
+ cursorReminder += ` [UPDATE v${versionNotice.current}\u2192${versionNotice.latest}]`;
964
+ }
965
+ console.log(
966
+ JSON.stringify({
967
+ continue: true,
968
+ user_message: cursorReminder
969
+ })
970
+ );
971
+ } else {
972
+ const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
973
+ console.log(
974
+ JSON.stringify({
975
+ cancel: false,
976
+ contextModification: enhancedReminder
977
+ })
978
+ );
962
979
  }
963
- console.log(
964
- JSON.stringify({
965
- continue: true,
966
- user_message: cursorReminder
967
- })
968
- );
969
- } else if (editorFormat === "antigravity") {
970
- const newSession = isNewSession(input, editorFormat);
971
- const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
972
- const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
973
- console.log(
974
- JSON.stringify({
975
- cancel: false,
976
- contextModification: enhancedReminder
977
- })
978
- );
979
980
  }
980
981
  process.exit(0);
981
982
  }
982
- var ENABLED2, API_URL, API_KEY, WORKSPACE_ID, PROJECT_ID, REMINDER, ENHANCED_REMINDER_HEADER, isDirectRun2;
983
+ var ENABLED2, API_URL, API_KEY, WORKSPACE_ID, PROJECT_ID, REMINDER, FULL_REMINDER, ENHANCED_REMINDER_HEADER, isDirectRun2;
983
984
  var init_user_prompt_submit = __esm({
984
985
  "src/hooks/user-prompt-submit.ts"() {
985
986
  "use strict";
@@ -989,7 +990,9 @@ var init_user_prompt_submit = __esm({
989
990
  API_KEY = process.env.CONTEXTSTREAM_API_KEY || "";
990
991
  WORKSPACE_ID = null;
991
992
  PROJECT_ID = null;
992
- REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
993
+ REMINDER = `[CONTEXTSTREAM] Call mcp__contextstream__context(user_message="...", save_exchange=true, session_id="<session-id>") FIRST before any other tool. Response contains dynamic rules, lessons, preferences. For search: use search(mode="auto") if indexed, else local tools.
994
+ [END]`;
995
+ FULL_REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
993
996
 
994
997
  1. FIRST: Call mcp__contextstream__context(user_message="...", save_exchange=true, session_id="<session-id>") before ANY other tool
995
998
  - Returns: dynamic rules, lessons from past mistakes, relevant context
@@ -999,7 +1002,7 @@ var init_user_prompt_submit = __esm({
999
1002
 
1000
1003
  2. FOR CODE SEARCH: Check index status, then search appropriately
1001
1004
  \u26A0\uFE0F BEFORE searching: mcp__contextstream__project(action="index_status")
1002
- \u2705 IF indexed & fresh: Use mcp__contextstream__search(mode="hybrid", query="...")
1005
+ \u2705 IF indexed & fresh: Use mcp__contextstream__search(mode="auto", query="...")
1003
1006
  \u2705 IF NOT indexed OR stale: Use local tools (Glob/Grep/Read) directly
1004
1007
  \u2705 IF search returns 0 results: Fallback to local tools (Glob/Grep/Read)
1005
1008
 
@@ -1857,20 +1860,31 @@ __export(hooks_config_exports, {
1857
1860
  writeIndexStatus: () => writeIndexStatus
1858
1861
  });
1859
1862
  import * as fs5 from "node:fs/promises";
1863
+ import * as fsSync from "node:fs";
1860
1864
  import * as path5 from "node:path";
1861
1865
  import { homedir as homedir6 } from "node:os";
1862
1866
  import { fileURLToPath } from "node:url";
1863
1867
  function getHookCommand(hookName2) {
1864
- const fs7 = __require("node:fs");
1865
- const binaryPath = "/usr/local/bin/contextstream-mcp";
1866
- if (fs7.existsSync(binaryPath)) {
1867
- return `${binaryPath} hook ${hookName2}`;
1868
+ const isWindows = process.platform === "win32";
1869
+ if (isWindows) {
1870
+ const localAppData = process.env.LOCALAPPDATA;
1871
+ if (localAppData) {
1872
+ const windowsBinaryPath = path5.join(localAppData, "ContextStream", "contextstream-mcp.exe");
1873
+ if (fsSync.existsSync(windowsBinaryPath)) {
1874
+ return `"${windowsBinaryPath}" hook ${hookName2}`;
1875
+ }
1876
+ }
1877
+ } else {
1878
+ const unixBinaryPath = "/usr/local/bin/contextstream-mcp";
1879
+ if (fsSync.existsSync(unixBinaryPath)) {
1880
+ return `${unixBinaryPath} hook ${hookName2}`;
1881
+ }
1868
1882
  }
1869
1883
  try {
1870
1884
  const __dirname = path5.dirname(fileURLToPath(import.meta.url));
1871
1885
  const indexPath = path5.join(__dirname, "index.js");
1872
- if (fs7.existsSync(indexPath)) {
1873
- return `node ${indexPath} hook ${hookName2}`;
1886
+ if (fsSync.existsSync(indexPath)) {
1887
+ return `node "${indexPath}" hook ${hookName2}`;
1874
1888
  }
1875
1889
  } catch {
1876
1890
  }
@@ -2283,20 +2297,43 @@ function getClineHooksDir(scope, projectPath) {
2283
2297
  }
2284
2298
  return path5.join(projectPath, ".clinerules", "hooks");
2285
2299
  }
2300
+ function getHookWrapperScript(hookName2) {
2301
+ const isWindows = process.platform === "win32";
2302
+ const command = getHookCommand(hookName2);
2303
+ if (isWindows) {
2304
+ return {
2305
+ content: `@echo off\r
2306
+ ${command}\r
2307
+ `,
2308
+ extension: ".cmd"
2309
+ };
2310
+ } else {
2311
+ return {
2312
+ content: `#!/bin/bash
2313
+ # ContextStream ${hookName2} Hook Wrapper for Cline/Roo/Kilo Code
2314
+ exec ${command}
2315
+ `,
2316
+ extension: ""
2317
+ };
2318
+ }
2319
+ }
2286
2320
  async function installClineHookScripts(options) {
2287
2321
  const hooksDir = getClineHooksDir(options.scope, options.projectPath);
2288
2322
  await fs5.mkdir(hooksDir, { recursive: true });
2289
- const preToolUsePath = path5.join(hooksDir, "PreToolUse");
2290
- const userPromptPath = path5.join(hooksDir, "UserPromptSubmit");
2291
- const postToolUsePath = path5.join(hooksDir, "PostToolUse");
2292
- await fs5.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
2293
- await fs5.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
2323
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
2324
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
2325
+ const postWriteWrapper = getHookWrapperScript("post-write");
2326
+ const preToolUsePath = path5.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
2327
+ const userPromptPath = path5.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
2328
+ const postToolUsePath = path5.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
2329
+ await fs5.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
2330
+ await fs5.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
2294
2331
  const result = {
2295
2332
  preToolUse: preToolUsePath,
2296
2333
  userPromptSubmit: userPromptPath
2297
2334
  };
2298
2335
  if (options.includePostWrite !== false) {
2299
- await fs5.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
2336
+ await fs5.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
2300
2337
  result.postToolUse = postToolUsePath;
2301
2338
  }
2302
2339
  return result;
@@ -2313,17 +2350,20 @@ function getRooCodeHooksDir(scope, projectPath) {
2313
2350
  async function installRooCodeHookScripts(options) {
2314
2351
  const hooksDir = getRooCodeHooksDir(options.scope, options.projectPath);
2315
2352
  await fs5.mkdir(hooksDir, { recursive: true });
2316
- const preToolUsePath = path5.join(hooksDir, "PreToolUse");
2317
- const userPromptPath = path5.join(hooksDir, "UserPromptSubmit");
2318
- const postToolUsePath = path5.join(hooksDir, "PostToolUse");
2319
- await fs5.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
2320
- await fs5.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
2353
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
2354
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
2355
+ const postWriteWrapper = getHookWrapperScript("post-write");
2356
+ const preToolUsePath = path5.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
2357
+ const userPromptPath = path5.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
2358
+ const postToolUsePath = path5.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
2359
+ await fs5.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
2360
+ await fs5.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
2321
2361
  const result = {
2322
2362
  preToolUse: preToolUsePath,
2323
2363
  userPromptSubmit: userPromptPath
2324
2364
  };
2325
2365
  if (options.includePostWrite !== false) {
2326
- await fs5.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
2366
+ await fs5.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
2327
2367
  result.postToolUse = postToolUsePath;
2328
2368
  }
2329
2369
  return result;
@@ -2340,17 +2380,20 @@ function getKiloCodeHooksDir(scope, projectPath) {
2340
2380
  async function installKiloCodeHookScripts(options) {
2341
2381
  const hooksDir = getKiloCodeHooksDir(options.scope, options.projectPath);
2342
2382
  await fs5.mkdir(hooksDir, { recursive: true });
2343
- const preToolUsePath = path5.join(hooksDir, "PreToolUse");
2344
- const userPromptPath = path5.join(hooksDir, "UserPromptSubmit");
2345
- const postToolUsePath = path5.join(hooksDir, "PostToolUse");
2346
- await fs5.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
2347
- await fs5.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
2383
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
2384
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
2385
+ const postWriteWrapper = getHookWrapperScript("post-write");
2386
+ const preToolUsePath = path5.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
2387
+ const userPromptPath = path5.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
2388
+ const postToolUsePath = path5.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
2389
+ await fs5.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
2390
+ await fs5.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
2348
2391
  const result = {
2349
2392
  preToolUse: preToolUsePath,
2350
2393
  userPromptSubmit: userPromptPath
2351
2394
  };
2352
2395
  if (options.includePostWrite !== false) {
2353
- await fs5.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
2396
+ await fs5.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
2354
2397
  result.postToolUse = postToolUsePath;
2355
2398
  }
2356
2399
  return result;
@@ -2579,7 +2622,7 @@ Set environment variables:
2579
2622
  - \`CONTEXTSTREAM_REMINDER_ENABLED=false\` - Disable UserPromptSubmit reminders
2580
2623
  `.trim();
2581
2624
  }
2582
- 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, CLINE_HOOK_WRAPPER, CURSOR_PRETOOLUSE_HOOK_SCRIPT, CURSOR_BEFORE_SUBMIT_HOOK_SCRIPT;
2625
+ 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;
2583
2626
  var init_hooks_config = __esm({
2584
2627
  "src/hooks-config.ts"() {
2585
2628
  "use strict";
@@ -2690,7 +2733,7 @@ def main():
2690
2733
  if tool == "Glob":
2691
2734
  pattern = inp.get("pattern", "")
2692
2735
  if is_discovery_glob(pattern):
2693
- print(f"STOP: Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of Glob.", file=sys.stderr)
2736
+ print(f"STOP: Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of Glob.", file=sys.stderr)
2694
2737
  sys.exit(2)
2695
2738
 
2696
2739
  elif tool == "Grep" or tool == "Search":
@@ -2702,12 +2745,12 @@ def main():
2702
2745
  # Specific file - suggest Read instead
2703
2746
  print(f"STOP: Use Read(\\"{path}\\") to view file content, or mcp__contextstream__search(mode=\\"keyword\\", query=\\"{pattern}\\") for codebase search.", file=sys.stderr)
2704
2747
  else:
2705
- print(f"STOP: Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}.", file=sys.stderr)
2748
+ print(f"STOP: Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}.", file=sys.stderr)
2706
2749
  sys.exit(2)
2707
2750
 
2708
2751
  elif tool == "Task":
2709
2752
  if inp.get("subagent_type", "").lower() == "explore":
2710
- print("STOP: Use mcp__contextstream__search(mode=\\"hybrid\\") instead of Task(Explore).", file=sys.stderr)
2753
+ print("STOP: Use mcp__contextstream__search(mode=\\"auto\\") instead of Task(Explore).", file=sys.stderr)
2711
2754
  sys.exit(2)
2712
2755
  if inp.get("subagent_type", "").lower() == "plan":
2713
2756
  print("STOP: Use mcp__contextstream__session(action=\\"capture_plan\\") for planning. ContextStream plans persist across sessions.", file=sys.stderr)
@@ -2734,7 +2777,7 @@ import os
2734
2777
  ENABLED = os.environ.get("CONTEXTSTREAM_REMINDER_ENABLED", "true").lower() == "true"
2735
2778
 
2736
2779
  REMINDER = """[CONTEXTSTREAM RULES]
2737
- 1. BEFORE Glob/Grep/Read/Search: mcp__contextstream__search(mode="hybrid") FIRST
2780
+ 1. BEFORE Glob/Grep/Read/Search: mcp__contextstream__search(mode="auto") FIRST
2738
2781
  2. Call context_smart at start of EVERY response
2739
2782
  3. Local tools ONLY if ContextStream returns 0 results
2740
2783
  [END RULES]"""
@@ -3170,7 +3213,7 @@ def main():
3170
3213
  pattern = params.get("path", "") or params.get("regex", "")
3171
3214
  if is_discovery_glob(pattern) or is_discovery_grep(pattern):
3172
3215
  output_block(
3173
- f"Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}. "
3216
+ f"Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}. "
3174
3217
  "ContextStream search is indexed and faster. Only use local tools if ContextStream returns 0 results.",
3175
3218
  "[CONTEXTSTREAM] Use ContextStream search for code discovery."
3176
3219
  )
@@ -3197,7 +3240,7 @@ import os
3197
3240
  ENABLED = os.environ.get("CONTEXTSTREAM_REMINDER_ENABLED", "true").lower() == "true"
3198
3241
 
3199
3242
  REMINDER = """[CONTEXTSTREAM RULES]
3200
- 1. BEFORE list_files/search_files/read_file: mcp__contextstream__search(mode="hybrid") FIRST
3243
+ 1. BEFORE list_files/search_files/read_file: mcp__contextstream__search(mode="auto") FIRST
3201
3244
  2. Call context_smart at start of EVERY response
3202
3245
  3. Local tools ONLY if ContextStream returns 0 results
3203
3246
  [END RULES]"""
@@ -3239,13 +3282,6 @@ esac
3239
3282
 
3240
3283
  exit 0
3241
3284
  `;
3242
- CLINE_HOOK_WRAPPER = (hookName2) => {
3243
- const command = getHookCommand(hookName2);
3244
- return `#!/bin/bash
3245
- # ContextStream ${hookName2} Hook Wrapper for Cline/Roo/Kilo Code
3246
- exec ${command}
3247
- `;
3248
- };
3249
3285
  CURSOR_PRETOOLUSE_HOOK_SCRIPT = `#!/usr/bin/env python3
3250
3286
  """
3251
3287
  ContextStream PreToolUse Hook for Cursor
@@ -3355,7 +3391,7 @@ def main():
3355
3391
  pattern = params.get("pattern", "") or params.get("path", "")
3356
3392
  if is_discovery_glob(pattern):
3357
3393
  output_deny(
3358
- f"Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}. "
3394
+ f"Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}. "
3359
3395
  "ContextStream search is indexed and faster."
3360
3396
  )
3361
3397