@contextstream/mcp-server 0.4.73 → 0.4.80

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.
@@ -536,6 +536,13 @@ var init_ignore = __esm({
536
536
  "out/",
537
537
  ".next/",
538
538
  ".nuxt/",
539
+ ".svelte-kit/",
540
+ ".parcel-cache/",
541
+ ".turbo/",
542
+ ".gradle/",
543
+ ".cache/",
544
+ "bin/",
545
+ "obj/",
539
546
  // Python
540
547
  "__pycache__/",
541
548
  ".pytest_cache/",
@@ -559,6 +566,8 @@ var init_ignore = __esm({
559
566
  "poetry.lock",
560
567
  "Gemfile.lock",
561
568
  "composer.lock",
569
+ "*.min.js",
570
+ "*.min.css",
562
571
  // OS files
563
572
  ".DS_Store",
564
573
  "Thumbs.db"
@@ -726,6 +735,7 @@ async function readFilesFromDirectory(rootPath, options = {}) {
726
735
  const file = {
727
736
  path: relPath,
728
737
  content,
738
+ language: detectLanguage(relPath),
729
739
  // Always include machine_id and source_modified_at
730
740
  machine_id: gitCtx.machineId,
731
741
  source_modified_at: stat.mtime.toISOString()
@@ -785,6 +795,7 @@ async function* readAllFilesInBatches(rootPath, options = {}) {
785
795
  const file = {
786
796
  path: relPath,
787
797
  content,
798
+ language: detectLanguage(relPath),
788
799
  sizeBytes: stat.size,
789
800
  // Always include machine_id and source_modified_at
790
801
  machine_id: gitCtx.machineId,
@@ -875,6 +886,7 @@ async function* readChangedFilesInBatches(rootPath, sinceTimestamp, options = {}
875
886
  const file = {
876
887
  path: relPath,
877
888
  content,
889
+ language: detectLanguage(relPath),
878
890
  sizeBytes: stat.size,
879
891
  // Always include machine_id and source_modified_at
880
892
  machine_id: gitCtx.machineId,
@@ -1125,6 +1137,11 @@ var init_files = __esm({
1125
1137
  "out",
1126
1138
  ".next",
1127
1139
  ".nuxt",
1140
+ ".svelte-kit",
1141
+ ".parcel-cache",
1142
+ ".turbo",
1143
+ ".gradle",
1144
+ ".cache",
1128
1145
  "__pycache__",
1129
1146
  ".pytest_cache",
1130
1147
  ".mypy_cache",
@@ -1135,6 +1152,8 @@ var init_files = __esm({
1135
1152
  "vendor",
1136
1153
  "coverage",
1137
1154
  ".coverage",
1155
+ "bin",
1156
+ "obj",
1138
1157
  ".idea",
1139
1158
  ".vscode",
1140
1159
  ".vs"
@@ -1153,9 +1172,9 @@ var init_files = __esm({
1153
1172
  "composer.lock"
1154
1173
  ]);
1155
1174
  MAX_FILE_SIZE = 5 * 1024 * 1024;
1156
- MAX_BATCH_BYTES = 10 * 1024 * 1024;
1175
+ MAX_BATCH_BYTES = 1024 * 1024;
1157
1176
  LARGE_FILE_THRESHOLD = 2 * 1024 * 1024;
1158
- MAX_FILES_PER_BATCH = 200;
1177
+ MAX_FILES_PER_BATCH = 20;
1159
1178
  gitContextCache = /* @__PURE__ */ new Map();
1160
1179
  }
1161
1180
  });
@@ -1827,10 +1846,13 @@ async function writeIndexStatus(status) {
1827
1846
  async function markProjectIndexed(projectPath, options) {
1828
1847
  const status = await readIndexStatus();
1829
1848
  const resolvedPath = path3.resolve(projectPath);
1849
+ const previous = status.projects[resolvedPath];
1830
1850
  status.projects[resolvedPath] = {
1831
1851
  indexed_at: (/* @__PURE__ */ new Date()).toISOString(),
1832
- project_id: options?.project_id,
1833
- project_name: options?.project_name
1852
+ project_id: options?.project_id ?? previous?.project_id,
1853
+ project_name: options?.project_name ?? previous?.project_name,
1854
+ git_head: options?.git_head ?? previous?.git_head,
1855
+ git_remote: options?.git_remote ?? previous?.git_remote
1834
1856
  };
1835
1857
  await writeIndexStatus(status);
1836
1858
  }
@@ -2014,21 +2036,22 @@ async function installCursorHookScripts(options) {
2014
2036
  for (const [eventName, entries] of Object.entries(existingConfig.hooks || {})) {
2015
2037
  cleanedHooks[eventName] = filterContextStreamHooks(entries);
2016
2038
  }
2017
- const preToolUseCommand = getHookCommand("pre-tool-use");
2018
- const userPromptCommand = getHookCommand("user-prompt-submit");
2019
- const saveIntentCommand = getHookCommand("on-save-intent");
2020
- const postToolUseCommand = getHookCommand("post-tool-use");
2021
- const postToolUseFailureCommand = getHookCommand("post-tool-use-failure");
2022
- const preCompactCommand = getHookCommand("pre-compact");
2023
- const sessionStartCommand = getHookCommand("session-start");
2024
- const sessionEndCommand = getHookCommand("session-end");
2025
- const stopCommand = getHookCommand("stop");
2026
- const notificationCommand = getHookCommand("notification");
2027
- const permissionRequestCommand = getHookCommand("permission-request");
2028
- const subagentStartCommand = getHookCommand("subagent-start");
2029
- const subagentStopCommand = getHookCommand("subagent-stop");
2030
- const taskCompletedCommand = getHookCommand("task-completed");
2031
- const teammateIdleCommand = getHookCommand("teammate-idle");
2039
+ const cursorHookCommand = (name) => `${getHookCommand(name)} --editor=cursor`;
2040
+ const preToolUseCommand = cursorHookCommand("pre-tool-use");
2041
+ const userPromptCommand = cursorHookCommand("user-prompt-submit");
2042
+ const saveIntentCommand = cursorHookCommand("on-save-intent");
2043
+ const postToolUseCommand = cursorHookCommand("post-tool-use");
2044
+ const postToolUseFailureCommand = cursorHookCommand("post-tool-use-failure");
2045
+ const preCompactCommand = cursorHookCommand("pre-compact");
2046
+ const sessionStartCommand = cursorHookCommand("session-start");
2047
+ const sessionEndCommand = cursorHookCommand("session-end");
2048
+ const stopCommand = cursorHookCommand("stop");
2049
+ const notificationCommand = cursorHookCommand("notification");
2050
+ const permissionRequestCommand = cursorHookCommand("permission-request");
2051
+ const subagentStartCommand = cursorHookCommand("subagent-start");
2052
+ const subagentStopCommand = cursorHookCommand("subagent-stop");
2053
+ const taskCompletedCommand = cursorHookCommand("task-completed");
2054
+ const teammateIdleCommand = cursorHookCommand("teammate-idle");
2032
2055
  const config = {
2033
2056
  version: 1,
2034
2057
  hooks: {
@@ -151,44 +151,6 @@ function isContextFreshAndClean(cwd, maxAgeSeconds) {
151
151
  }
152
152
  return true;
153
153
  }
154
- function startIndexWaitWindow(cwd, waitSeconds) {
155
- if (!cwd.trim() || waitSeconds <= 0) return;
156
- const state = readState();
157
- const target = getOrCreateEntry(state, cwd);
158
- if (!target) return;
159
- const now = Date.now();
160
- const existingUntil = target.entry.index_wait_until ? new Date(target.entry.index_wait_until).getTime() : NaN;
161
- if (!Number.isNaN(existingUntil) && existingUntil > now) {
162
- target.entry.updated_at = nowIso();
163
- writeState(state);
164
- return;
165
- }
166
- target.entry.index_wait_started_at = new Date(now).toISOString();
167
- target.entry.index_wait_until = new Date(now + waitSeconds * 1e3).toISOString();
168
- target.entry.updated_at = nowIso();
169
- writeState(state);
170
- }
171
- function clearIndexWaitWindow(cwd) {
172
- if (!cwd.trim()) return;
173
- const state = readState();
174
- const target = getOrCreateEntry(state, cwd);
175
- if (!target) return;
176
- target.entry.index_wait_started_at = void 0;
177
- target.entry.index_wait_until = void 0;
178
- target.entry.updated_at = nowIso();
179
- writeState(state);
180
- }
181
- function indexWaitRemainingSeconds(cwd) {
182
- if (!cwd.trim()) return null;
183
- const state = readState();
184
- const target = getOrCreateEntry(state, cwd);
185
- if (!target?.entry.index_wait_until) return null;
186
- const until = new Date(target.entry.index_wait_until).getTime();
187
- if (Number.isNaN(until)) return null;
188
- const remainingMs = until - Date.now();
189
- if (remainingMs <= 0) return null;
190
- return Math.ceil(remainingMs / 1e3);
191
- }
192
154
 
193
155
  // src/hooks/pre-tool-use.ts
194
156
  var ENABLED = process.env.CONTEXTSTREAM_HOOK_ENABLED !== "false";
@@ -196,9 +158,6 @@ var INDEX_STATUS_FILE = path2.join(homedir2(), ".contextstream", "indexed-projec
196
158
  var DEBUG_FILE = "/tmp/pretooluse-hook-debug.log";
197
159
  var STALE_THRESHOLD_DAYS = 7;
198
160
  var CONTEXT_FRESHNESS_SECONDS = 120;
199
- var DEFAULT_INDEX_WAIT_SECONDS = 20;
200
- var MIN_INDEX_WAIT_SECONDS = 15;
201
- var MAX_INDEX_WAIT_SECONDS = 20;
202
161
  var DISCOVERY_PATTERNS = ["**/*", "**/", "src/**", "lib/**", "app/**", "components/**"];
203
162
  function isDiscoveryGlob(pattern) {
204
163
  const patternLower = pattern.toLowerCase();
@@ -224,33 +183,6 @@ function isDiscoveryGrep(filePath) {
224
183
  }
225
184
  return false;
226
185
  }
227
- function configuredIndexWaitSeconds() {
228
- const parsed = Number.parseInt(process.env.CONTEXTSTREAM_INDEX_WAIT_SECONDS ?? "", 10);
229
- if (Number.isNaN(parsed)) return DEFAULT_INDEX_WAIT_SECONDS;
230
- return Math.min(MAX_INDEX_WAIT_SECONDS, Math.max(MIN_INDEX_WAIT_SECONDS, parsed));
231
- }
232
- function isLocalDiscoveryToolDuringIndexWait(tool, toolInput) {
233
- if (tool === "Glob" || tool === "Explore" || tool === "SemanticSearch" || tool === "codebase_search") {
234
- return true;
235
- }
236
- if (tool === "Task") {
237
- const subagentTypeRaw = toolInput?.subagent_type || toolInput?.subagentType || "";
238
- return subagentTypeRaw.toLowerCase().includes("explore");
239
- }
240
- if (tool === "Grep" || tool === "Search" || tool === "grep_search" || tool === "code_search") {
241
- const filePath = toolInput?.path || "";
242
- return isDiscoveryGrep(filePath);
243
- }
244
- if (tool === "Read" || tool === "ReadFile" || tool === "read_file") {
245
- const filePath = toolInput?.file_path || toolInput?.path || toolInput?.file || toolInput?.target_file || "";
246
- return isDiscoveryGrep(filePath);
247
- }
248
- if (tool === "list_files" || tool === "search_files" || tool === "search_files_content" || tool === "find_files" || tool === "find_by_name") {
249
- const pattern = toolInput?.path || toolInput?.regex || toolInput?.pattern || toolInput?.query || "";
250
- return !pattern || isDiscoveryGlob(pattern) || isDiscoveryGrep(pattern);
251
- }
252
- return false;
253
- }
254
186
  function isProjectIndexed(cwd) {
255
187
  if (!fs2.existsSync(INDEX_STATUS_FILE)) {
256
188
  return { isIndexed: false, isStale: false };
@@ -420,11 +352,13 @@ function outputClineAllow() {
420
352
  process.exit(0);
421
353
  }
422
354
  function outputCursorBlock(reason) {
423
- console.log(JSON.stringify({ decision: "deny", reason }));
355
+ console.log(
356
+ JSON.stringify({ permission: "deny", agent_message: reason, user_message: reason })
357
+ );
424
358
  process.exit(0);
425
359
  }
426
360
  function outputCursorAllow() {
427
- console.log(JSON.stringify({ decision: "allow" }));
361
+ console.log(JSON.stringify({ permission: "allow" }));
428
362
  process.exit(0);
429
363
  }
430
364
  function blockWithMessage(editorFormat, message) {
@@ -447,6 +381,9 @@ function allowTool(editorFormat, cwd, recordStateChange) {
447
381
  process.exit(0);
448
382
  }
449
383
  function detectEditorFormat(input) {
384
+ if (process.argv.includes("--editor=cursor")) {
385
+ return "cursor";
386
+ }
450
387
  if (input.hookName !== void 0 || input.toolName !== void 0) {
451
388
  return "cline";
452
389
  }
@@ -515,19 +452,7 @@ async function runPreToolUseHook() {
515
452
  const { isIndexed, isStale } = isProjectIndexed(cwd);
516
453
  fs2.appendFileSync(DEBUG_FILE, `[PreToolUse] isIndexed=${isIndexed}, isStale=${isStale}
517
454
  `);
518
- if (isIndexed && !isStale) {
519
- clearIndexWaitWindow(cwd);
520
- } else {
521
- const waitSeconds = configuredIndexWaitSeconds();
522
- if (isLocalDiscoveryToolDuringIndexWait(tool, toolInput)) {
523
- startIndexWaitWindow(cwd, waitSeconds);
524
- const remaining = indexWaitRemainingSeconds(cwd);
525
- if (remaining && remaining > 0) {
526
- const msg = `Index refresh grace window is active (${remaining}s remaining). Keep ContextStream search-first flow: mcp__contextstream__search(mode="auto", query="..."). Do not use local discovery tools yet for stale/not-indexed projects. Retry after refresh; local fallback is allowed only after ~${waitSeconds}s if index is still unavailable.`;
527
- blockWithMessage(editorFormat, msg);
528
- }
529
- allowTool(editorFormat, cwd, recordStateChange);
530
- }
455
+ if (!isIndexed || isStale) {
531
456
  allowTool(editorFormat, cwd, recordStateChange);
532
457
  }
533
458
  if (tool === "Glob") {