@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
  };
@@ -58,20 +52,31 @@ __export(hooks_config_exports, {
58
52
  writeIndexStatus: () => writeIndexStatus
59
53
  });
60
54
  import * as fs from "node:fs/promises";
55
+ import * as fsSync from "node:fs";
61
56
  import * as path from "node:path";
62
57
  import { homedir } from "node:os";
63
58
  import { fileURLToPath } from "node:url";
64
59
  function getHookCommand(hookName) {
65
- const fs3 = __require("node:fs");
66
- const binaryPath = "/usr/local/bin/contextstream-mcp";
67
- if (fs3.existsSync(binaryPath)) {
68
- return `${binaryPath} hook ${hookName}`;
60
+ const isWindows = process.platform === "win32";
61
+ if (isWindows) {
62
+ const localAppData = process.env.LOCALAPPDATA;
63
+ if (localAppData) {
64
+ const windowsBinaryPath = path.join(localAppData, "ContextStream", "contextstream-mcp.exe");
65
+ if (fsSync.existsSync(windowsBinaryPath)) {
66
+ return `"${windowsBinaryPath}" hook ${hookName}`;
67
+ }
68
+ }
69
+ } else {
70
+ const unixBinaryPath = "/usr/local/bin/contextstream-mcp";
71
+ if (fsSync.existsSync(unixBinaryPath)) {
72
+ return `${unixBinaryPath} hook ${hookName}`;
73
+ }
69
74
  }
70
75
  try {
71
76
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
72
77
  const indexPath = path.join(__dirname, "index.js");
73
- if (fs3.existsSync(indexPath)) {
74
- return `node ${indexPath} hook ${hookName}`;
78
+ if (fsSync.existsSync(indexPath)) {
79
+ return `node "${indexPath}" hook ${hookName}`;
75
80
  }
76
81
  } catch {
77
82
  }
@@ -484,20 +489,43 @@ function getClineHooksDir(scope, projectPath) {
484
489
  }
485
490
  return path.join(projectPath, ".clinerules", "hooks");
486
491
  }
492
+ function getHookWrapperScript(hookName) {
493
+ const isWindows = process.platform === "win32";
494
+ const command = getHookCommand(hookName);
495
+ if (isWindows) {
496
+ return {
497
+ content: `@echo off\r
498
+ ${command}\r
499
+ `,
500
+ extension: ".cmd"
501
+ };
502
+ } else {
503
+ return {
504
+ content: `#!/bin/bash
505
+ # ContextStream ${hookName} Hook Wrapper for Cline/Roo/Kilo Code
506
+ exec ${command}
507
+ `,
508
+ extension: ""
509
+ };
510
+ }
511
+ }
487
512
  async function installClineHookScripts(options) {
488
513
  const hooksDir = getClineHooksDir(options.scope, options.projectPath);
489
514
  await fs.mkdir(hooksDir, { recursive: true });
490
- const preToolUsePath = path.join(hooksDir, "PreToolUse");
491
- const userPromptPath = path.join(hooksDir, "UserPromptSubmit");
492
- const postToolUsePath = path.join(hooksDir, "PostToolUse");
493
- await fs.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
494
- await fs.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
515
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
516
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
517
+ const postWriteWrapper = getHookWrapperScript("post-write");
518
+ const preToolUsePath = path.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
519
+ const userPromptPath = path.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
520
+ const postToolUsePath = path.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
521
+ await fs.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
522
+ await fs.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
495
523
  const result = {
496
524
  preToolUse: preToolUsePath,
497
525
  userPromptSubmit: userPromptPath
498
526
  };
499
527
  if (options.includePostWrite !== false) {
500
- await fs.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
528
+ await fs.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
501
529
  result.postToolUse = postToolUsePath;
502
530
  }
503
531
  return result;
@@ -514,17 +542,20 @@ function getRooCodeHooksDir(scope, projectPath) {
514
542
  async function installRooCodeHookScripts(options) {
515
543
  const hooksDir = getRooCodeHooksDir(options.scope, options.projectPath);
516
544
  await fs.mkdir(hooksDir, { recursive: true });
517
- const preToolUsePath = path.join(hooksDir, "PreToolUse");
518
- const userPromptPath = path.join(hooksDir, "UserPromptSubmit");
519
- const postToolUsePath = path.join(hooksDir, "PostToolUse");
520
- await fs.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
521
- await fs.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
545
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
546
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
547
+ const postWriteWrapper = getHookWrapperScript("post-write");
548
+ const preToolUsePath = path.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
549
+ const userPromptPath = path.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
550
+ const postToolUsePath = path.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
551
+ await fs.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
552
+ await fs.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
522
553
  const result = {
523
554
  preToolUse: preToolUsePath,
524
555
  userPromptSubmit: userPromptPath
525
556
  };
526
557
  if (options.includePostWrite !== false) {
527
- await fs.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
558
+ await fs.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
528
559
  result.postToolUse = postToolUsePath;
529
560
  }
530
561
  return result;
@@ -541,17 +572,20 @@ function getKiloCodeHooksDir(scope, projectPath) {
541
572
  async function installKiloCodeHookScripts(options) {
542
573
  const hooksDir = getKiloCodeHooksDir(options.scope, options.projectPath);
543
574
  await fs.mkdir(hooksDir, { recursive: true });
544
- const preToolUsePath = path.join(hooksDir, "PreToolUse");
545
- const userPromptPath = path.join(hooksDir, "UserPromptSubmit");
546
- const postToolUsePath = path.join(hooksDir, "PostToolUse");
547
- await fs.writeFile(preToolUsePath, CLINE_HOOK_WRAPPER("pre-tool-use"), { mode: 493 });
548
- await fs.writeFile(userPromptPath, CLINE_HOOK_WRAPPER("user-prompt-submit"), { mode: 493 });
575
+ const preToolUseWrapper = getHookWrapperScript("pre-tool-use");
576
+ const userPromptWrapper = getHookWrapperScript("user-prompt-submit");
577
+ const postWriteWrapper = getHookWrapperScript("post-write");
578
+ const preToolUsePath = path.join(hooksDir, `PreToolUse${preToolUseWrapper.extension}`);
579
+ const userPromptPath = path.join(hooksDir, `UserPromptSubmit${userPromptWrapper.extension}`);
580
+ const postToolUsePath = path.join(hooksDir, `PostToolUse${postWriteWrapper.extension}`);
581
+ await fs.writeFile(preToolUsePath, preToolUseWrapper.content, { mode: 493 });
582
+ await fs.writeFile(userPromptPath, userPromptWrapper.content, { mode: 493 });
549
583
  const result = {
550
584
  preToolUse: preToolUsePath,
551
585
  userPromptSubmit: userPromptPath
552
586
  };
553
587
  if (options.includePostWrite !== false) {
554
- await fs.writeFile(postToolUsePath, CLINE_HOOK_WRAPPER("post-write"), { mode: 493 });
588
+ await fs.writeFile(postToolUsePath, postWriteWrapper.content, { mode: 493 });
555
589
  result.postToolUse = postToolUsePath;
556
590
  }
557
591
  return result;
@@ -780,7 +814,7 @@ Set environment variables:
780
814
  - \`CONTEXTSTREAM_REMINDER_ENABLED=false\` - Disable UserPromptSubmit reminders
781
815
  `.trim();
782
816
  }
783
- 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;
817
+ 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;
784
818
  var init_hooks_config = __esm({
785
819
  "src/hooks-config.ts"() {
786
820
  "use strict";
@@ -891,7 +925,7 @@ def main():
891
925
  if tool == "Glob":
892
926
  pattern = inp.get("pattern", "")
893
927
  if is_discovery_glob(pattern):
894
- print(f"STOP: Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of Glob.", file=sys.stderr)
928
+ print(f"STOP: Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of Glob.", file=sys.stderr)
895
929
  sys.exit(2)
896
930
 
897
931
  elif tool == "Grep" or tool == "Search":
@@ -903,12 +937,12 @@ def main():
903
937
  # Specific file - suggest Read instead
904
938
  print(f"STOP: Use Read(\\"{path}\\") to view file content, or mcp__contextstream__search(mode=\\"keyword\\", query=\\"{pattern}\\") for codebase search.", file=sys.stderr)
905
939
  else:
906
- print(f"STOP: Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}.", file=sys.stderr)
940
+ print(f"STOP: Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}.", file=sys.stderr)
907
941
  sys.exit(2)
908
942
 
909
943
  elif tool == "Task":
910
944
  if inp.get("subagent_type", "").lower() == "explore":
911
- print("STOP: Use mcp__contextstream__search(mode=\\"hybrid\\") instead of Task(Explore).", file=sys.stderr)
945
+ print("STOP: Use mcp__contextstream__search(mode=\\"auto\\") instead of Task(Explore).", file=sys.stderr)
912
946
  sys.exit(2)
913
947
  if inp.get("subagent_type", "").lower() == "plan":
914
948
  print("STOP: Use mcp__contextstream__session(action=\\"capture_plan\\") for planning. ContextStream plans persist across sessions.", file=sys.stderr)
@@ -935,7 +969,7 @@ import os
935
969
  ENABLED = os.environ.get("CONTEXTSTREAM_REMINDER_ENABLED", "true").lower() == "true"
936
970
 
937
971
  REMINDER = """[CONTEXTSTREAM RULES]
938
- 1. BEFORE Glob/Grep/Read/Search: mcp__contextstream__search(mode="hybrid") FIRST
972
+ 1. BEFORE Glob/Grep/Read/Search: mcp__contextstream__search(mode="auto") FIRST
939
973
  2. Call context_smart at start of EVERY response
940
974
  3. Local tools ONLY if ContextStream returns 0 results
941
975
  [END RULES]"""
@@ -1371,7 +1405,7 @@ def main():
1371
1405
  pattern = params.get("path", "") or params.get("regex", "")
1372
1406
  if is_discovery_glob(pattern) or is_discovery_grep(pattern):
1373
1407
  output_block(
1374
- f"Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}. "
1408
+ f"Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}. "
1375
1409
  "ContextStream search is indexed and faster. Only use local tools if ContextStream returns 0 results.",
1376
1410
  "[CONTEXTSTREAM] Use ContextStream search for code discovery."
1377
1411
  )
@@ -1398,7 +1432,7 @@ import os
1398
1432
  ENABLED = os.environ.get("CONTEXTSTREAM_REMINDER_ENABLED", "true").lower() == "true"
1399
1433
 
1400
1434
  REMINDER = """[CONTEXTSTREAM RULES]
1401
- 1. BEFORE list_files/search_files/read_file: mcp__contextstream__search(mode="hybrid") FIRST
1435
+ 1. BEFORE list_files/search_files/read_file: mcp__contextstream__search(mode="auto") FIRST
1402
1436
  2. Call context_smart at start of EVERY response
1403
1437
  3. Local tools ONLY if ContextStream returns 0 results
1404
1438
  [END RULES]"""
@@ -1440,13 +1474,6 @@ esac
1440
1474
 
1441
1475
  exit 0
1442
1476
  `;
1443
- CLINE_HOOK_WRAPPER = (hookName) => {
1444
- const command = getHookCommand(hookName);
1445
- return `#!/bin/bash
1446
- # ContextStream ${hookName} Hook Wrapper for Cline/Roo/Kilo Code
1447
- exec ${command}
1448
- `;
1449
- };
1450
1477
  CURSOR_PRETOOLUSE_HOOK_SCRIPT = `#!/usr/bin/env python3
1451
1478
  """
1452
1479
  ContextStream PreToolUse Hook for Cursor
@@ -1556,7 +1583,7 @@ def main():
1556
1583
  pattern = params.get("pattern", "") or params.get("path", "")
1557
1584
  if is_discovery_glob(pattern):
1558
1585
  output_deny(
1559
- f"Use mcp__contextstream__search(mode=\\"hybrid\\", query=\\"{pattern}\\") instead of {tool}. "
1586
+ f"Use mcp__contextstream__search(mode=\\"auto\\", query=\\"{pattern}\\") instead of {tool}. "
1560
1587
  "ContextStream search is indexed and faster."
1561
1588
  )
1562
1589
 
@@ -173,7 +173,7 @@ async function runPreToolUseHook() {
173
173
  fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Glob pattern=${pattern}, isDiscovery=${isDiscoveryGlob(pattern)}
174
174
  `);
175
175
  if (isDiscoveryGlob(pattern)) {
176
- const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of Glob.`;
176
+ const msg = `STOP: Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of Glob.`;
177
177
  fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Intercepting discovery glob: ${msg}
178
178
  `);
179
179
  if (editorFormat === "cline") {
@@ -196,7 +196,7 @@ async function runPreToolUseHook() {
196
196
  }
197
197
  blockClaudeCode(msg);
198
198
  } else {
199
- const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of ${tool}.`;
199
+ const msg = `STOP: Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of ${tool}.`;
200
200
  if (editorFormat === "cline") {
201
201
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
202
202
  } else if (editorFormat === "cursor") {
@@ -208,7 +208,7 @@ async function runPreToolUseHook() {
208
208
  } else if (tool === "Task") {
209
209
  const subagentType = toolInput?.subagent_type?.toLowerCase() || "";
210
210
  if (subagentType === "explore") {
211
- const msg = 'STOP: Use mcp__contextstream__search(mode="hybrid") instead of Task(Explore).';
211
+ const msg = 'STOP: Use mcp__contextstream__search(mode="auto") instead of Task(Explore).';
212
212
  if (editorFormat === "cline") {
213
213
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
214
214
  } else if (editorFormat === "cursor") {
@@ -237,7 +237,7 @@ async function runPreToolUseHook() {
237
237
  if (tool === "list_files" || tool === "search_files") {
238
238
  const pattern = toolInput?.path || toolInput?.regex || "";
239
239
  if (isDiscoveryGlob(pattern) || isDiscoveryGrep(pattern)) {
240
- const msg = `Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of ${tool}. ContextStream search is indexed and faster.`;
240
+ const msg = `Use mcp__contextstream__search(mode="auto", query="${pattern}") instead of ${tool}. ContextStream search is indexed and faster.`;
241
241
  if (editorFormat === "cline") {
242
242
  outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
243
243
  } else if (editorFormat === "cursor") {