@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.
- package/dist/hooks/auto-rules.js +72 -45
- package/dist/hooks/pre-tool-use.js +4 -4
- package/dist/hooks/runner.js +150 -114
- package/dist/hooks/session-init.js +1037 -1
- package/dist/hooks/user-prompt-submit.js +73 -64
- package/dist/index.js +15320 -14913
- package/dist/test-server.js +1 -1
- package/package.json +1 -1
|
@@ -43,7 +43,7 @@ function compareVersions(v1, v2) {
|
|
|
43
43
|
}
|
|
44
44
|
return 0;
|
|
45
45
|
}
|
|
46
|
-
var CACHE_TTL_MS =
|
|
46
|
+
var CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
47
47
|
var latestVersionPromise = null;
|
|
48
48
|
function getCacheFilePath() {
|
|
49
49
|
return join(homedir(), ".contextstream", "version-cache.json");
|
|
@@ -179,7 +179,9 @@ var API_URL = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io
|
|
|
179
179
|
var API_KEY = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
180
180
|
var WORKSPACE_ID = null;
|
|
181
181
|
var PROJECT_ID = null;
|
|
182
|
-
var REMINDER = `[CONTEXTSTREAM
|
|
182
|
+
var 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.
|
|
183
|
+
[END]`;
|
|
184
|
+
var FULL_REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
|
|
183
185
|
|
|
184
186
|
1. FIRST: Call mcp__contextstream__context(user_message="...", save_exchange=true, session_id="<session-id>") before ANY other tool
|
|
185
187
|
- Returns: dynamic rules, lessons from past mistakes, relevant context
|
|
@@ -189,7 +191,7 @@ var REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
|
|
|
189
191
|
|
|
190
192
|
2. FOR CODE SEARCH: Check index status, then search appropriately
|
|
191
193
|
\u26A0\uFE0F BEFORE searching: mcp__contextstream__project(action="index_status")
|
|
192
|
-
\u2705 IF indexed & fresh: Use mcp__contextstream__search(mode="
|
|
194
|
+
\u2705 IF indexed & fresh: Use mcp__contextstream__search(mode="auto", query="...")
|
|
193
195
|
\u2705 IF NOT indexed OR stale: Use local tools (Glob/Grep/Read) directly
|
|
194
196
|
\u2705 IF search returns 0 results: Fallback to local tools (Glob/Grep/Read)
|
|
195
197
|
|
|
@@ -434,6 +436,34 @@ async function saveLastExchange(exchange, cwd, clientName) {
|
|
|
434
436
|
} catch {
|
|
435
437
|
}
|
|
436
438
|
}
|
|
439
|
+
async function fetchHookContext() {
|
|
440
|
+
if (!API_KEY) return null;
|
|
441
|
+
try {
|
|
442
|
+
const controller = new AbortController();
|
|
443
|
+
const timeoutId = setTimeout(() => controller.abort(), 2e3);
|
|
444
|
+
const url = `${API_URL}/api/v1/context/hook`;
|
|
445
|
+
const body = {};
|
|
446
|
+
if (WORKSPACE_ID) body.workspace_id = WORKSPACE_ID;
|
|
447
|
+
if (PROJECT_ID) body.project_id = PROJECT_ID;
|
|
448
|
+
const response = await fetch(url, {
|
|
449
|
+
method: "POST",
|
|
450
|
+
headers: {
|
|
451
|
+
"X-API-Key": API_KEY,
|
|
452
|
+
"Content-Type": "application/json"
|
|
453
|
+
},
|
|
454
|
+
body: JSON.stringify(body),
|
|
455
|
+
signal: controller.signal
|
|
456
|
+
});
|
|
457
|
+
clearTimeout(timeoutId);
|
|
458
|
+
if (response.ok) {
|
|
459
|
+
const data = await response.json();
|
|
460
|
+
return data?.data?.context || null;
|
|
461
|
+
}
|
|
462
|
+
return null;
|
|
463
|
+
} catch {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
437
467
|
async function fetchSessionContext() {
|
|
438
468
|
if (!API_KEY) return null;
|
|
439
469
|
try {
|
|
@@ -512,26 +542,6 @@ function transformSmartContextResponse(data) {
|
|
|
512
542
|
return null;
|
|
513
543
|
}
|
|
514
544
|
}
|
|
515
|
-
function buildClaudeReminder(ctx, versionNotice) {
|
|
516
|
-
const parts = [];
|
|
517
|
-
if (versionNotice?.behind) {
|
|
518
|
-
const versionInfo = getVersionNoticeForHook(versionNotice);
|
|
519
|
-
if (versionInfo) {
|
|
520
|
-
parts.push(versionInfo);
|
|
521
|
-
parts.push("");
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
const highImportancePrefs = ctx?.preferences?.filter((p) => p.importance === "high") || [];
|
|
525
|
-
if (highImportancePrefs.length > 0) {
|
|
526
|
-
parts.push(`[USER PREFERENCES - Always respect these]`);
|
|
527
|
-
for (const pref of highImportancePrefs.slice(0, 5)) {
|
|
528
|
-
parts.push(`\u2022 ${pref.title}: ${pref.content}`);
|
|
529
|
-
}
|
|
530
|
-
parts.push("");
|
|
531
|
-
}
|
|
532
|
-
parts.push(REMINDER);
|
|
533
|
-
return parts.join("\n");
|
|
534
|
-
}
|
|
535
545
|
function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
|
|
536
546
|
const parts = [ENHANCED_REMINDER_HEADER];
|
|
537
547
|
if (versionNotice?.behind) {
|
|
@@ -549,7 +559,7 @@ function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
|
|
|
549
559
|
2. Wait for indexing: if \`init\` returns \`indexing_status: "started"\`, files are being indexed
|
|
550
560
|
3. Generate a unique session_id (e.g., "session-" + timestamp or UUID) - use this for ALL context() calls
|
|
551
561
|
4. Call \`context(user_message="...", save_exchange=true, session_id="<your-session-id>")\` for task-specific context
|
|
552
|
-
5. Use \`search(mode="
|
|
562
|
+
5. Use \`search(mode="auto")\` for code discovery (not Glob/Grep/Read)
|
|
553
563
|
|
|
554
564
|
`);
|
|
555
565
|
}
|
|
@@ -590,7 +600,7 @@ function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
|
|
|
590
600
|
parts.push("");
|
|
591
601
|
}
|
|
592
602
|
parts.push("---\n");
|
|
593
|
-
parts.push(
|
|
603
|
+
parts.push(FULL_REMINDER);
|
|
594
604
|
parts.push(`
|
|
595
605
|
|
|
596
606
|
---
|
|
@@ -607,7 +617,7 @@ Returns: \`indexed\` (true/false), \`last_indexed_at\`, \`file_count\`
|
|
|
607
617
|
### \u{1F50D} Search Decision Tree:
|
|
608
618
|
|
|
609
619
|
**IF indexed=true AND last_indexed_at is recent:**
|
|
610
|
-
\u2192 Use \`search(mode="
|
|
620
|
+
\u2192 Use \`search(mode="auto", query="...")\`
|
|
611
621
|
|
|
612
622
|
**IF indexed=false OR last_indexed_at is stale (>7 days):**
|
|
613
623
|
\u2192 Use local tools (Glob/Grep/Read) directly
|
|
@@ -678,55 +688,54 @@ async function runUserPromptSubmitHook() {
|
|
|
678
688
|
}
|
|
679
689
|
const editorFormat = detectEditorFormat(input);
|
|
680
690
|
const cwd = input.cwd || process.cwd();
|
|
681
|
-
loadConfigFromMcpJson(cwd);
|
|
682
|
-
const versionNoticePromise = getUpdateNotice();
|
|
683
|
-
const lastExchange = extractLastExchange(input, editorFormat);
|
|
684
|
-
const clientName = editorFormat === "claude" ? "claude-code" : editorFormat;
|
|
685
|
-
const saveExchangePromise = lastExchange ? saveLastExchange(lastExchange, cwd, clientName) : Promise.resolve();
|
|
686
691
|
if (editorFormat === "claude") {
|
|
687
|
-
|
|
688
|
-
|
|
692
|
+
loadConfigFromMcpJson(cwd);
|
|
693
|
+
let context = REMINDER;
|
|
694
|
+
if (API_KEY) {
|
|
695
|
+
try {
|
|
696
|
+
const hookContext = await fetchHookContext();
|
|
697
|
+
if (hookContext) {
|
|
698
|
+
context = hookContext;
|
|
699
|
+
}
|
|
700
|
+
} catch {
|
|
701
|
+
}
|
|
702
|
+
}
|
|
689
703
|
console.log(
|
|
690
704
|
JSON.stringify({
|
|
691
705
|
hookSpecificOutput: {
|
|
692
706
|
hookEventName: "UserPromptSubmit",
|
|
693
|
-
additionalContext:
|
|
707
|
+
additionalContext: context
|
|
694
708
|
}
|
|
695
709
|
})
|
|
696
710
|
);
|
|
697
|
-
} else
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
cancel: false,
|
|
704
|
-
contextModification: enhancedReminder
|
|
705
|
-
})
|
|
706
|
-
);
|
|
707
|
-
} else if (editorFormat === "cursor") {
|
|
711
|
+
} else {
|
|
712
|
+
loadConfigFromMcpJson(cwd);
|
|
713
|
+
const versionNoticePromise = getUpdateNotice();
|
|
714
|
+
const lastExchange = extractLastExchange(input, editorFormat);
|
|
715
|
+
const clientName = editorFormat;
|
|
716
|
+
const saveExchangePromise = lastExchange ? saveLastExchange(lastExchange, cwd, clientName) : Promise.resolve();
|
|
708
717
|
const newSession = isNewSession(input, editorFormat);
|
|
709
718
|
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
719
|
+
if (editorFormat === "cursor") {
|
|
720
|
+
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").`;
|
|
721
|
+
if (versionNotice?.behind) {
|
|
722
|
+
cursorReminder += ` [UPDATE v${versionNotice.current}\u2192${versionNotice.latest}]`;
|
|
723
|
+
}
|
|
724
|
+
console.log(
|
|
725
|
+
JSON.stringify({
|
|
726
|
+
continue: true,
|
|
727
|
+
user_message: cursorReminder
|
|
728
|
+
})
|
|
729
|
+
);
|
|
730
|
+
} else {
|
|
731
|
+
const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
|
|
732
|
+
console.log(
|
|
733
|
+
JSON.stringify({
|
|
734
|
+
cancel: false,
|
|
735
|
+
contextModification: enhancedReminder
|
|
736
|
+
})
|
|
737
|
+
);
|
|
713
738
|
}
|
|
714
|
-
console.log(
|
|
715
|
-
JSON.stringify({
|
|
716
|
-
continue: true,
|
|
717
|
-
user_message: cursorReminder
|
|
718
|
-
})
|
|
719
|
-
);
|
|
720
|
-
} else if (editorFormat === "antigravity") {
|
|
721
|
-
const newSession = isNewSession(input, editorFormat);
|
|
722
|
-
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
723
|
-
const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
|
|
724
|
-
console.log(
|
|
725
|
-
JSON.stringify({
|
|
726
|
-
cancel: false,
|
|
727
|
-
contextModification: enhancedReminder
|
|
728
|
-
})
|
|
729
|
-
);
|
|
730
739
|
}
|
|
731
740
|
process.exit(0);
|
|
732
741
|
}
|