@contextstream/mcp-server 0.4.51 → 0.4.53
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 +5 -1
- package/dist/hooks/pre-compact.js +3 -1
- package/dist/hooks/pre-tool-use.js +29 -4
- package/dist/hooks/runner.js +439 -167
- package/dist/hooks/user-prompt-submit.js +250 -9
- package/dist/index.js +824 -412
- package/package.json +1 -1
package/dist/hooks/auto-rules.js
CHANGED
|
@@ -62,10 +62,14 @@ import * as path from "node:path";
|
|
|
62
62
|
import { homedir } from "node:os";
|
|
63
63
|
import { fileURLToPath } from "node:url";
|
|
64
64
|
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}`;
|
|
69
|
+
}
|
|
65
70
|
try {
|
|
66
71
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
67
72
|
const indexPath = path.join(__dirname, "index.js");
|
|
68
|
-
const fs3 = __require("node:fs");
|
|
69
73
|
if (fs3.existsSync(indexPath)) {
|
|
70
74
|
return `node ${indexPath} hook ${hookName}`;
|
|
71
75
|
}
|
|
@@ -269,7 +269,9 @@ async function runPreCompactHook() {
|
|
|
269
269
|
activeFiles: [],
|
|
270
270
|
toolCallCount: 0,
|
|
271
271
|
messageCount: 0,
|
|
272
|
-
lastTools: []
|
|
272
|
+
lastTools: [],
|
|
273
|
+
messages: [],
|
|
274
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
273
275
|
};
|
|
274
276
|
if (transcriptPath && fs.existsSync(transcriptPath)) {
|
|
275
277
|
transcriptData = parseTranscript(transcriptPath);
|
|
@@ -6,6 +6,7 @@ import * as path from "node:path";
|
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
var ENABLED = process.env.CONTEXTSTREAM_HOOK_ENABLED !== "false";
|
|
8
8
|
var INDEX_STATUS_FILE = path.join(homedir(), ".contextstream", "indexed-projects.json");
|
|
9
|
+
var DEBUG_FILE = "/tmp/pretooluse-hook-debug.log";
|
|
9
10
|
var STALE_THRESHOLD_DAYS = 7;
|
|
10
11
|
var DISCOVERY_PATTERNS = ["**/*", "**/", "src/**", "lib/**", "app/**", "components/**"];
|
|
11
12
|
function isDiscoveryGlob(pattern) {
|
|
@@ -82,8 +83,17 @@ function extractToolInput(input) {
|
|
|
82
83
|
return input.tool_input || input.parameters || input.toolParameters || {};
|
|
83
84
|
}
|
|
84
85
|
function blockClaudeCode(message) {
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
const response = {
|
|
87
|
+
hookSpecificOutput: {
|
|
88
|
+
hookEventName: "PreToolUse",
|
|
89
|
+
// Use additionalContext instead of deny - tool runs but Claude sees the message
|
|
90
|
+
additionalContext: `[CONTEXTSTREAM] ${message}`
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] REDIRECT (additionalContext): ${JSON.stringify(response)}
|
|
94
|
+
`);
|
|
95
|
+
console.log(JSON.stringify(response));
|
|
96
|
+
process.exit(0);
|
|
87
97
|
}
|
|
88
98
|
function outputClineBlock(errorMessage, contextMod) {
|
|
89
99
|
const result = {
|
|
@@ -112,13 +122,18 @@ function detectEditorFormat(input) {
|
|
|
112
122
|
if (input.hookName !== void 0 || input.toolName !== void 0) {
|
|
113
123
|
return "cline";
|
|
114
124
|
}
|
|
115
|
-
if (input.hook_event_name !== void 0) {
|
|
116
|
-
return "
|
|
125
|
+
if (input.hook_event_name !== void 0 || input.tool_name !== void 0) {
|
|
126
|
+
return "claude";
|
|
117
127
|
}
|
|
118
128
|
return "claude";
|
|
119
129
|
}
|
|
120
130
|
async function runPreToolUseHook() {
|
|
131
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Hook invoked at ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
132
|
+
`);
|
|
133
|
+
console.error("[PreToolUse] Hook invoked at", (/* @__PURE__ */ new Date()).toISOString());
|
|
121
134
|
if (!ENABLED) {
|
|
135
|
+
fs.appendFileSync(DEBUG_FILE, "[PreToolUse] Hook disabled, exiting\n");
|
|
136
|
+
console.error("[PreToolUse] Hook disabled, exiting");
|
|
122
137
|
process.exit(0);
|
|
123
138
|
}
|
|
124
139
|
let inputData = "";
|
|
@@ -138,8 +153,14 @@ async function runPreToolUseHook() {
|
|
|
138
153
|
const cwd = extractCwd(input);
|
|
139
154
|
const tool = extractToolName(input);
|
|
140
155
|
const toolInput = extractToolInput(input);
|
|
156
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] tool=${tool}, cwd=${cwd}, editorFormat=${editorFormat}
|
|
157
|
+
`);
|
|
141
158
|
const { isIndexed } = isProjectIndexed(cwd);
|
|
159
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] isIndexed=${isIndexed}
|
|
160
|
+
`);
|
|
142
161
|
if (!isIndexed) {
|
|
162
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Project not indexed, allowing
|
|
163
|
+
`);
|
|
143
164
|
if (editorFormat === "cline") {
|
|
144
165
|
outputClineAllow();
|
|
145
166
|
} else if (editorFormat === "cursor") {
|
|
@@ -149,8 +170,12 @@ async function runPreToolUseHook() {
|
|
|
149
170
|
}
|
|
150
171
|
if (tool === "Glob") {
|
|
151
172
|
const pattern = toolInput?.pattern || "";
|
|
173
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Glob pattern=${pattern}, isDiscovery=${isDiscoveryGlob(pattern)}
|
|
174
|
+
`);
|
|
152
175
|
if (isDiscoveryGlob(pattern)) {
|
|
153
176
|
const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of Glob.`;
|
|
177
|
+
fs.appendFileSync(DEBUG_FILE, `[PreToolUse] Intercepting discovery glob: ${msg}
|
|
178
|
+
`);
|
|
154
179
|
if (editorFormat === "cline") {
|
|
155
180
|
outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
|
|
156
181
|
} else if (editorFormat === "cursor") {
|