@contextstream/mcp-server 0.4.55 → 0.4.57
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/runner.js +474 -45
- package/dist/hooks/session-end.js +111 -17
- package/dist/hooks/session-init.js +381 -9
- package/dist/hooks/user-prompt-submit.js +453 -29
- package/dist/index.js +1604 -637
- package/dist/test-server.js +7 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38,6 +38,388 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
mod
|
|
39
39
|
));
|
|
40
40
|
|
|
41
|
+
// src/version.ts
|
|
42
|
+
import { createRequire } from "module";
|
|
43
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
44
|
+
import { homedir, platform } from "os";
|
|
45
|
+
import { join } from "path";
|
|
46
|
+
import { spawn } from "child_process";
|
|
47
|
+
function getVersion() {
|
|
48
|
+
if (typeof __CONTEXTSTREAM_VERSION__ !== "undefined" && __CONTEXTSTREAM_VERSION__) {
|
|
49
|
+
return __CONTEXTSTREAM_VERSION__;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const require2 = createRequire(import.meta.url);
|
|
53
|
+
const pkg = require2("../package.json");
|
|
54
|
+
const version = pkg?.version;
|
|
55
|
+
if (typeof version === "string" && version.trim()) return version.trim();
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
return "unknown";
|
|
59
|
+
}
|
|
60
|
+
function compareVersions(v1, v2) {
|
|
61
|
+
const parts1 = v1.split(".").map(Number);
|
|
62
|
+
const parts2 = v2.split(".").map(Number);
|
|
63
|
+
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
64
|
+
const p1 = parts1[i] ?? 0;
|
|
65
|
+
const p2 = parts2[i] ?? 0;
|
|
66
|
+
if (p1 < p2) return -1;
|
|
67
|
+
if (p1 > p2) return 1;
|
|
68
|
+
}
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
function getCacheFilePath() {
|
|
72
|
+
return join(homedir(), ".contextstream", "version-cache.json");
|
|
73
|
+
}
|
|
74
|
+
function readCache() {
|
|
75
|
+
try {
|
|
76
|
+
const cacheFile = getCacheFilePath();
|
|
77
|
+
if (!existsSync(cacheFile)) return null;
|
|
78
|
+
const data = JSON.parse(readFileSync(cacheFile, "utf-8"));
|
|
79
|
+
if (Date.now() - data.checkedAt > CACHE_TTL_MS) return null;
|
|
80
|
+
return data;
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function writeCache(latestVersion) {
|
|
86
|
+
try {
|
|
87
|
+
const configDir = join(homedir(), ".contextstream");
|
|
88
|
+
if (!existsSync(configDir)) {
|
|
89
|
+
mkdirSync(configDir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
const cacheFile = getCacheFilePath();
|
|
92
|
+
writeFileSync(
|
|
93
|
+
cacheFile,
|
|
94
|
+
JSON.stringify({
|
|
95
|
+
latestVersion,
|
|
96
|
+
checkedAt: Date.now()
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function fetchLatestVersion() {
|
|
103
|
+
try {
|
|
104
|
+
const controller = new AbortController();
|
|
105
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
106
|
+
const response = await fetch(NPM_LATEST_URL, {
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
headers: { Accept: "application/json" }
|
|
109
|
+
});
|
|
110
|
+
clearTimeout(timeout);
|
|
111
|
+
if (!response.ok) return null;
|
|
112
|
+
const data = await response.json();
|
|
113
|
+
return typeof data.version === "string" ? data.version : null;
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function resolveLatestVersion() {
|
|
119
|
+
const cached = readCache();
|
|
120
|
+
if (cached) return cached.latestVersion;
|
|
121
|
+
if (!latestVersionPromise) {
|
|
122
|
+
latestVersionPromise = fetchLatestVersion().finally(() => {
|
|
123
|
+
latestVersionPromise = null;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const latestVersion = await latestVersionPromise;
|
|
127
|
+
if (latestVersion) {
|
|
128
|
+
writeCache(latestVersion);
|
|
129
|
+
}
|
|
130
|
+
return latestVersion;
|
|
131
|
+
}
|
|
132
|
+
async function checkForUpdates() {
|
|
133
|
+
const notice = await getUpdateNotice();
|
|
134
|
+
if (notice?.behind) {
|
|
135
|
+
showUpdateWarning(notice.current, notice.latest);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function showUpdateWarning(currentVersion, latestVersion) {
|
|
139
|
+
console.error("");
|
|
140
|
+
console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
|
|
141
|
+
console.error(`\u26A0\uFE0F Update available: v${currentVersion} \u2192 v${latestVersion}`);
|
|
142
|
+
console.error("");
|
|
143
|
+
console.error(` Run: ${UPGRADE_COMMAND}`);
|
|
144
|
+
console.error("");
|
|
145
|
+
console.error(" Then restart your AI tool to use the new version.");
|
|
146
|
+
console.error("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501");
|
|
147
|
+
console.error("");
|
|
148
|
+
}
|
|
149
|
+
async function getUpdateNotice() {
|
|
150
|
+
const currentVersion = VERSION;
|
|
151
|
+
if (currentVersion === "unknown") return null;
|
|
152
|
+
try {
|
|
153
|
+
const latestVersion = await resolveLatestVersion();
|
|
154
|
+
if (!latestVersion) return null;
|
|
155
|
+
if (compareVersions(currentVersion, latestVersion) < 0) {
|
|
156
|
+
return {
|
|
157
|
+
current: currentVersion,
|
|
158
|
+
latest: latestVersion,
|
|
159
|
+
behind: true,
|
|
160
|
+
upgrade_command: UPGRADE_COMMAND
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
function getVersionsBehind(current, latest) {
|
|
168
|
+
try {
|
|
169
|
+
const currentParts = current.split(".").map(Number);
|
|
170
|
+
const latestParts = latest.split(".").map(Number);
|
|
171
|
+
if ((latestParts[0] ?? 0) > (currentParts[0] ?? 0)) {
|
|
172
|
+
return 10 + ((latestParts[1] ?? 0) - (currentParts[1] ?? 0));
|
|
173
|
+
}
|
|
174
|
+
const minorDiff = (latestParts[1] ?? 0) - (currentParts[1] ?? 0);
|
|
175
|
+
const patchDiff = (latestParts[2] ?? 0) - (currentParts[2] ?? 0);
|
|
176
|
+
if (minorDiff > 0) {
|
|
177
|
+
return minorDiff;
|
|
178
|
+
} else if (minorDiff === 0 && patchDiff > 0) {
|
|
179
|
+
return 1;
|
|
180
|
+
}
|
|
181
|
+
return 0;
|
|
182
|
+
} catch {
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function getVersionWarning(notice) {
|
|
187
|
+
if (!notice?.behind) return null;
|
|
188
|
+
const versionsBehind = getVersionsBehind(notice.current, notice.latest);
|
|
189
|
+
if (versionsBehind >= 3) {
|
|
190
|
+
return `[VERSION_CRITICAL] MCP server is ${versionsBehind} versions behind (${notice.current} \u2192 ${notice.latest}). Update immediately: ${notice.upgrade_command}`;
|
|
191
|
+
} else if (versionsBehind >= 1) {
|
|
192
|
+
return `[VERSION_NOTICE] MCP server update available (${notice.current} \u2192 ${notice.latest}). Run: ${notice.upgrade_command}`;
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
function getVersionInstructions(notice) {
|
|
197
|
+
if (!notice?.behind) return null;
|
|
198
|
+
const versionsBehind = getVersionsBehind(notice.current, notice.latest);
|
|
199
|
+
if (versionsBehind >= 5) {
|
|
200
|
+
return `\u26A0\uFE0F CRITICAL: User's MCP is ${versionsBehind} versions behind. Mention update in EVERY response until updated.`;
|
|
201
|
+
} else if (versionsBehind >= 3) {
|
|
202
|
+
return `\u26A0\uFE0F User's MCP is ${versionsBehind} versions behind. Remind about update every 2-3 messages.`;
|
|
203
|
+
} else if (versionsBehind >= 1) {
|
|
204
|
+
return `Note: MCP update available (${notice.current}\u2192${notice.latest}). Mention once at session start.`;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
function getVersionNoticeForHook(notice) {
|
|
209
|
+
if (!notice?.behind) return null;
|
|
210
|
+
const versionsBehind = getVersionsBehind(notice.current, notice.latest);
|
|
211
|
+
const severity = versionsBehind >= 5 ? "CRITICAL" : versionsBehind >= 3 ? "IMPORTANT" : "INFO";
|
|
212
|
+
let frequency = "";
|
|
213
|
+
let whatTheyAreMissing = "";
|
|
214
|
+
if (versionsBehind >= 5) {
|
|
215
|
+
frequency = "Mention this update in EVERY response until the user updates.";
|
|
216
|
+
whatTheyAreMissing = `The user is missing out on many new features, important bug fixes, and possible security patches. Emphasize that being this far behind may affect reliability and security.`;
|
|
217
|
+
} else if (versionsBehind >= 3) {
|
|
218
|
+
frequency = "Remind the user about this update every 2-3 messages.";
|
|
219
|
+
whatTheyAreMissing = `The user is missing out on several new features and important fixes that improve reliability and functionality.`;
|
|
220
|
+
} else {
|
|
221
|
+
frequency = "Mention this update once at session start, then only if user asks.";
|
|
222
|
+
whatTheyAreMissing = `Minor update with improvements and fixes available.`;
|
|
223
|
+
}
|
|
224
|
+
return `[VERSION_${severity}] MCP server is ${versionsBehind > 0 ? versionsBehind + " version(s)" : "a version"} behind (${notice.current} \u2192 ${notice.latest}).
|
|
225
|
+
|
|
226
|
+
${whatTheyAreMissing}
|
|
227
|
+
|
|
228
|
+
${frequency}
|
|
229
|
+
|
|
230
|
+
When mentioning the update, provide these commands (user can choose their preferred method):
|
|
231
|
+
- macOS/Linux: curl -fsSL https://contextstream.io/scripts/setup.sh | bash
|
|
232
|
+
- Windows: irm https://contextstream.io/scripts/setup.ps1 | iex
|
|
233
|
+
- npm: npm install -g @contextstream/mcp-server@latest
|
|
234
|
+
|
|
235
|
+
Be helpful but not annoying - frame it positively as access to new capabilities rather than criticism.`;
|
|
236
|
+
}
|
|
237
|
+
function isAutoUpdateEnabled() {
|
|
238
|
+
if (process.env.CONTEXTSTREAM_AUTO_UPDATE === "false") {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
const configPath = join(homedir(), ".contextstream", "config.json");
|
|
243
|
+
if (existsSync(configPath)) {
|
|
244
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
245
|
+
if (config.auto_update === false) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
} catch {
|
|
250
|
+
}
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
function setAutoUpdatePreference(enabled) {
|
|
254
|
+
try {
|
|
255
|
+
const configDir = join(homedir(), ".contextstream");
|
|
256
|
+
const configPath = join(configDir, "config.json");
|
|
257
|
+
let config = {};
|
|
258
|
+
if (existsSync(configPath)) {
|
|
259
|
+
config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
260
|
+
} else {
|
|
261
|
+
if (!existsSync(configDir)) {
|
|
262
|
+
mkdirSync(configDir, { recursive: true });
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
config.auto_update = enabled;
|
|
266
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
267
|
+
} catch {
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async function attemptAutoUpdate() {
|
|
271
|
+
const currentVersion = VERSION;
|
|
272
|
+
if (!isAutoUpdateEnabled()) {
|
|
273
|
+
return {
|
|
274
|
+
attempted: false,
|
|
275
|
+
success: false,
|
|
276
|
+
previousVersion: currentVersion,
|
|
277
|
+
newVersion: null,
|
|
278
|
+
error: "Auto-update disabled"
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const notice = await getUpdateNotice();
|
|
282
|
+
if (!notice?.behind) {
|
|
283
|
+
return {
|
|
284
|
+
attempted: false,
|
|
285
|
+
success: true,
|
|
286
|
+
previousVersion: currentVersion,
|
|
287
|
+
newVersion: null
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
const updateMethod = detectUpdateMethod();
|
|
291
|
+
try {
|
|
292
|
+
await runUpdate(updateMethod);
|
|
293
|
+
writeUpdateMarker(currentVersion, notice.latest);
|
|
294
|
+
return {
|
|
295
|
+
attempted: true,
|
|
296
|
+
success: true,
|
|
297
|
+
previousVersion: currentVersion,
|
|
298
|
+
newVersion: notice.latest
|
|
299
|
+
};
|
|
300
|
+
} catch (err) {
|
|
301
|
+
return {
|
|
302
|
+
attempted: true,
|
|
303
|
+
success: false,
|
|
304
|
+
previousVersion: currentVersion,
|
|
305
|
+
newVersion: notice.latest,
|
|
306
|
+
error: err instanceof Error ? err.message : "Update failed"
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function detectUpdateMethod() {
|
|
311
|
+
const execPath = process.argv[1] || "";
|
|
312
|
+
if (execPath.includes("node_modules") || execPath.includes("npm")) {
|
|
313
|
+
return "npm";
|
|
314
|
+
}
|
|
315
|
+
const os2 = platform();
|
|
316
|
+
if (os2 === "win32") {
|
|
317
|
+
return "powershell";
|
|
318
|
+
}
|
|
319
|
+
return "curl";
|
|
320
|
+
}
|
|
321
|
+
async function runUpdate(method) {
|
|
322
|
+
return new Promise((resolve16, reject) => {
|
|
323
|
+
let command;
|
|
324
|
+
let args;
|
|
325
|
+
let shell;
|
|
326
|
+
switch (method) {
|
|
327
|
+
case "npm":
|
|
328
|
+
command = "npm";
|
|
329
|
+
args = ["install", "-g", "@contextstream/mcp-server@latest"];
|
|
330
|
+
shell = false;
|
|
331
|
+
break;
|
|
332
|
+
case "curl":
|
|
333
|
+
command = "bash";
|
|
334
|
+
args = ["-c", "curl -fsSL https://contextstream.io/scripts/setup.sh | bash"];
|
|
335
|
+
shell = false;
|
|
336
|
+
break;
|
|
337
|
+
case "powershell":
|
|
338
|
+
command = "powershell";
|
|
339
|
+
args = ["-Command", "irm https://contextstream.io/scripts/setup.ps1 | iex"];
|
|
340
|
+
shell = false;
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
const proc = spawn(command, args, {
|
|
344
|
+
shell,
|
|
345
|
+
stdio: "ignore",
|
|
346
|
+
detached: true
|
|
347
|
+
});
|
|
348
|
+
proc.on("error", (err) => {
|
|
349
|
+
reject(err);
|
|
350
|
+
});
|
|
351
|
+
proc.on("close", (code) => {
|
|
352
|
+
if (code === 0) {
|
|
353
|
+
resolve16();
|
|
354
|
+
} else {
|
|
355
|
+
reject(new Error(`Update process exited with code ${code}`));
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
proc.unref();
|
|
359
|
+
setTimeout(() => resolve16(), 1e3);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
function writeUpdateMarker(previousVersion, newVersion) {
|
|
363
|
+
try {
|
|
364
|
+
const markerPath = join(homedir(), ".contextstream", "update-pending.json");
|
|
365
|
+
const configDir = join(homedir(), ".contextstream");
|
|
366
|
+
if (!existsSync(configDir)) {
|
|
367
|
+
mkdirSync(configDir, { recursive: true });
|
|
368
|
+
}
|
|
369
|
+
writeFileSync(markerPath, JSON.stringify({
|
|
370
|
+
previousVersion,
|
|
371
|
+
newVersion,
|
|
372
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
373
|
+
}));
|
|
374
|
+
} catch {
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
function checkUpdateMarker() {
|
|
378
|
+
try {
|
|
379
|
+
const markerPath = join(homedir(), ".contextstream", "update-pending.json");
|
|
380
|
+
if (!existsSync(markerPath)) return null;
|
|
381
|
+
const marker = JSON.parse(readFileSync(markerPath, "utf-8"));
|
|
382
|
+
const updatedAt = new Date(marker.updatedAt);
|
|
383
|
+
const hourAgo = new Date(Date.now() - 60 * 60 * 1e3);
|
|
384
|
+
if (updatedAt < hourAgo) {
|
|
385
|
+
try {
|
|
386
|
+
__require("fs").unlinkSync(markerPath);
|
|
387
|
+
} catch {
|
|
388
|
+
}
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
return { previousVersion: marker.previousVersion, newVersion: marker.newVersion };
|
|
392
|
+
} catch {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function clearUpdateMarker() {
|
|
397
|
+
try {
|
|
398
|
+
const markerPath = join(homedir(), ".contextstream", "update-pending.json");
|
|
399
|
+
if (existsSync(markerPath)) {
|
|
400
|
+
__require("fs").unlinkSync(markerPath);
|
|
401
|
+
}
|
|
402
|
+
} catch {
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
var NPM_LATEST_URL, AUTO_UPDATE_ENABLED, UPDATE_COMMANDS, UPGRADE_COMMAND, VERSION, CACHE_TTL_MS, latestVersionPromise;
|
|
406
|
+
var init_version = __esm({
|
|
407
|
+
"src/version.ts"() {
|
|
408
|
+
"use strict";
|
|
409
|
+
NPM_LATEST_URL = "https://registry.npmjs.org/@contextstream/mcp-server/latest";
|
|
410
|
+
AUTO_UPDATE_ENABLED = process.env.CONTEXTSTREAM_AUTO_UPDATE !== "false";
|
|
411
|
+
UPDATE_COMMANDS = {
|
|
412
|
+
npm: "npm install -g @contextstream/mcp-server@latest",
|
|
413
|
+
macLinux: "curl -fsSL https://contextstream.io/scripts/setup.sh | bash",
|
|
414
|
+
windows: "irm https://contextstream.io/scripts/setup.ps1 | iex"
|
|
415
|
+
};
|
|
416
|
+
UPGRADE_COMMAND = UPDATE_COMMANDS.npm;
|
|
417
|
+
VERSION = getVersion();
|
|
418
|
+
CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
419
|
+
latestVersionPromise = null;
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
|
|
41
423
|
// node_modules/ignore/index.js
|
|
42
424
|
var require_ignore = __commonJS({
|
|
43
425
|
"node_modules/ignore/index.js"(exports, module) {
|
|
@@ -2772,46 +3154,291 @@ function loadConfigFromMcpJson(cwd) {
|
|
|
2772
3154
|
}
|
|
2773
3155
|
}
|
|
2774
3156
|
}
|
|
3157
|
+
function readTranscriptFile(transcriptPath) {
|
|
3158
|
+
try {
|
|
3159
|
+
const content = fs10.readFileSync(transcriptPath, "utf-8");
|
|
3160
|
+
const lines = content.trim().split("\n");
|
|
3161
|
+
const messages = [];
|
|
3162
|
+
for (const line of lines) {
|
|
3163
|
+
try {
|
|
3164
|
+
const entry = JSON.parse(line);
|
|
3165
|
+
if (entry.type === "user" || entry.type === "assistant") {
|
|
3166
|
+
const msg = entry.message;
|
|
3167
|
+
if (msg?.role && msg?.content) {
|
|
3168
|
+
let textContent = "";
|
|
3169
|
+
if (typeof msg.content === "string") {
|
|
3170
|
+
textContent = msg.content;
|
|
3171
|
+
} else if (Array.isArray(msg.content)) {
|
|
3172
|
+
textContent = msg.content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n");
|
|
3173
|
+
}
|
|
3174
|
+
if (textContent) {
|
|
3175
|
+
messages.push({ role: msg.role, content: textContent });
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
} catch {
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
return messages;
|
|
3183
|
+
} catch {
|
|
3184
|
+
return [];
|
|
3185
|
+
}
|
|
3186
|
+
}
|
|
3187
|
+
function extractLastExchange(input, editorFormat) {
|
|
3188
|
+
try {
|
|
3189
|
+
if (editorFormat === "claude" && input.transcript_path) {
|
|
3190
|
+
const messages = readTranscriptFile(input.transcript_path);
|
|
3191
|
+
if (messages.length < 2) return null;
|
|
3192
|
+
let lastAssistantIdx = -1;
|
|
3193
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
3194
|
+
if (messages[i].role === "assistant") {
|
|
3195
|
+
lastAssistantIdx = i;
|
|
3196
|
+
break;
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
if (lastAssistantIdx < 1) return null;
|
|
3200
|
+
let lastUserIdx = -1;
|
|
3201
|
+
for (let i = lastAssistantIdx - 1; i >= 0; i--) {
|
|
3202
|
+
if (messages[i].role === "user") {
|
|
3203
|
+
lastUserIdx = i;
|
|
3204
|
+
break;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
if (lastUserIdx < 0) return null;
|
|
3208
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3209
|
+
return {
|
|
3210
|
+
userMessage: { role: "user", content: messages[lastUserIdx].content, timestamp: now },
|
|
3211
|
+
assistantMessage: { role: "assistant", content: messages[lastAssistantIdx].content, timestamp: now },
|
|
3212
|
+
sessionId: input.session_id
|
|
3213
|
+
};
|
|
3214
|
+
}
|
|
3215
|
+
if (editorFormat === "claude" && input.session?.messages) {
|
|
3216
|
+
const messages = input.session.messages;
|
|
3217
|
+
if (messages.length < 2) return null;
|
|
3218
|
+
let lastAssistantIdx = -1;
|
|
3219
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
3220
|
+
if (messages[i].role === "assistant") {
|
|
3221
|
+
lastAssistantIdx = i;
|
|
3222
|
+
break;
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
if (lastAssistantIdx < 1) return null;
|
|
3226
|
+
let lastUserIdx = -1;
|
|
3227
|
+
for (let i = lastAssistantIdx - 1; i >= 0; i--) {
|
|
3228
|
+
if (messages[i].role === "user") {
|
|
3229
|
+
lastUserIdx = i;
|
|
3230
|
+
break;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
if (lastUserIdx < 0) return null;
|
|
3234
|
+
const userMsg = messages[lastUserIdx];
|
|
3235
|
+
const assistantMsg = messages[lastAssistantIdx];
|
|
3236
|
+
const extractContent = (content) => {
|
|
3237
|
+
if (typeof content === "string") return content;
|
|
3238
|
+
if (Array.isArray(content)) {
|
|
3239
|
+
return content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n");
|
|
3240
|
+
}
|
|
3241
|
+
return "";
|
|
3242
|
+
};
|
|
3243
|
+
const userContent = extractContent(userMsg.content);
|
|
3244
|
+
const assistantContent = extractContent(assistantMsg.content);
|
|
3245
|
+
if (!userContent || !assistantContent) return null;
|
|
3246
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3247
|
+
return {
|
|
3248
|
+
userMessage: { role: "user", content: userContent, timestamp: now },
|
|
3249
|
+
assistantMessage: { role: "assistant", content: assistantContent, timestamp: now },
|
|
3250
|
+
sessionId: input.session_id
|
|
3251
|
+
};
|
|
3252
|
+
}
|
|
3253
|
+
if ((editorFormat === "cursor" || editorFormat === "antigravity") && input.history) {
|
|
3254
|
+
const history = input.history;
|
|
3255
|
+
if (history.length < 2) return null;
|
|
3256
|
+
let lastAssistantIdx = -1;
|
|
3257
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
3258
|
+
if (history[i].role === "assistant") {
|
|
3259
|
+
lastAssistantIdx = i;
|
|
3260
|
+
break;
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
if (lastAssistantIdx < 1) return null;
|
|
3264
|
+
let lastUserIdx = -1;
|
|
3265
|
+
for (let i = lastAssistantIdx - 1; i >= 0; i--) {
|
|
3266
|
+
if (history[i].role === "user") {
|
|
3267
|
+
lastUserIdx = i;
|
|
3268
|
+
break;
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
if (lastUserIdx < 0) return null;
|
|
3272
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3273
|
+
return {
|
|
3274
|
+
userMessage: { role: "user", content: history[lastUserIdx].content, timestamp: now },
|
|
3275
|
+
assistantMessage: { role: "assistant", content: history[lastAssistantIdx].content, timestamp: now },
|
|
3276
|
+
sessionId: input.conversationId || input.session_id
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
return null;
|
|
3280
|
+
} catch {
|
|
3281
|
+
return null;
|
|
3282
|
+
}
|
|
3283
|
+
}
|
|
3284
|
+
async function saveLastExchange(exchange, cwd, clientName) {
|
|
3285
|
+
if (!API_KEY2) return;
|
|
3286
|
+
const sessionId = exchange.sessionId || `hook-${Buffer.from(cwd).toString("base64").slice(0, 16)}`;
|
|
3287
|
+
const payload = {
|
|
3288
|
+
session_id: sessionId,
|
|
3289
|
+
user_message: exchange.userMessage.content,
|
|
3290
|
+
assistant_message: exchange.assistantMessage.content,
|
|
3291
|
+
client_name: clientName
|
|
3292
|
+
};
|
|
3293
|
+
if (WORKSPACE_ID) {
|
|
3294
|
+
payload.workspace_id = WORKSPACE_ID;
|
|
3295
|
+
}
|
|
3296
|
+
if (PROJECT_ID) {
|
|
3297
|
+
payload.project_id = PROJECT_ID;
|
|
3298
|
+
}
|
|
3299
|
+
try {
|
|
3300
|
+
const controller = new AbortController();
|
|
3301
|
+
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
3302
|
+
await fetch(`${API_URL2}/api/v1/transcripts/exchange`, {
|
|
3303
|
+
method: "POST",
|
|
3304
|
+
headers: {
|
|
3305
|
+
"Content-Type": "application/json",
|
|
3306
|
+
"X-API-Key": API_KEY2
|
|
3307
|
+
},
|
|
3308
|
+
body: JSON.stringify(payload),
|
|
3309
|
+
signal: controller.signal
|
|
3310
|
+
});
|
|
3311
|
+
clearTimeout(timeoutId);
|
|
3312
|
+
} catch {
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
2775
3315
|
async function fetchSessionContext() {
|
|
2776
3316
|
if (!API_KEY2) return null;
|
|
2777
3317
|
try {
|
|
2778
3318
|
const controller = new AbortController();
|
|
2779
3319
|
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
2780
|
-
const url =
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
const response = await fetch(url
|
|
2789
|
-
method: "
|
|
3320
|
+
const url = `${API_URL2}/api/v1/context/smart`;
|
|
3321
|
+
const body = {
|
|
3322
|
+
user_message: "hook context fetch",
|
|
3323
|
+
max_tokens: 200,
|
|
3324
|
+
format: "readable"
|
|
3325
|
+
};
|
|
3326
|
+
if (WORKSPACE_ID) body.workspace_id = WORKSPACE_ID;
|
|
3327
|
+
if (PROJECT_ID) body.project_id = PROJECT_ID;
|
|
3328
|
+
const response = await fetch(url, {
|
|
3329
|
+
method: "POST",
|
|
2790
3330
|
headers: {
|
|
2791
|
-
"X-API-Key": API_KEY2
|
|
3331
|
+
"X-API-Key": API_KEY2,
|
|
3332
|
+
"Content-Type": "application/json"
|
|
2792
3333
|
},
|
|
3334
|
+
body: JSON.stringify(body),
|
|
2793
3335
|
signal: controller.signal
|
|
2794
3336
|
});
|
|
2795
3337
|
clearTimeout(timeoutId);
|
|
2796
3338
|
if (response.ok) {
|
|
2797
|
-
|
|
3339
|
+
const data = await response.json();
|
|
3340
|
+
return transformSmartContextResponse(data);
|
|
2798
3341
|
}
|
|
2799
3342
|
return null;
|
|
2800
3343
|
} catch {
|
|
2801
3344
|
return null;
|
|
2802
3345
|
}
|
|
2803
3346
|
}
|
|
2804
|
-
function
|
|
3347
|
+
function transformSmartContextResponse(data) {
|
|
3348
|
+
try {
|
|
3349
|
+
const response = data;
|
|
3350
|
+
const result = {};
|
|
3351
|
+
if (response.data?.warnings && response.data.warnings.length > 0) {
|
|
3352
|
+
result.lessons = response.data.warnings.map((w) => ({
|
|
3353
|
+
title: "Lesson",
|
|
3354
|
+
trigger: "",
|
|
3355
|
+
prevention: w.replace(/^\[LESSONS_WARNING\]\s*/, "")
|
|
3356
|
+
}));
|
|
3357
|
+
}
|
|
3358
|
+
if (response.data?.items) {
|
|
3359
|
+
for (const item of response.data.items) {
|
|
3360
|
+
if (item.item_type === "preference") {
|
|
3361
|
+
if (!result.preferences) result.preferences = [];
|
|
3362
|
+
result.preferences.push({
|
|
3363
|
+
title: item.title,
|
|
3364
|
+
content: item.content,
|
|
3365
|
+
importance: item.metadata?.importance || "medium"
|
|
3366
|
+
});
|
|
3367
|
+
} else if (item.item_type === "plan") {
|
|
3368
|
+
if (!result.active_plans) result.active_plans = [];
|
|
3369
|
+
result.active_plans.push({
|
|
3370
|
+
title: item.title,
|
|
3371
|
+
status: "active"
|
|
3372
|
+
});
|
|
3373
|
+
} else if (item.item_type === "task") {
|
|
3374
|
+
if (!result.pending_tasks) result.pending_tasks = [];
|
|
3375
|
+
result.pending_tasks.push({
|
|
3376
|
+
title: item.title,
|
|
3377
|
+
status: "pending"
|
|
3378
|
+
});
|
|
3379
|
+
} else if (item.item_type === "reminder") {
|
|
3380
|
+
if (!result.reminders) result.reminders = [];
|
|
3381
|
+
result.reminders.push({
|
|
3382
|
+
title: item.title,
|
|
3383
|
+
content: item.content
|
|
3384
|
+
});
|
|
3385
|
+
}
|
|
3386
|
+
}
|
|
3387
|
+
}
|
|
3388
|
+
return result;
|
|
3389
|
+
} catch {
|
|
3390
|
+
return null;
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
function buildClaudeReminder(ctx, versionNotice) {
|
|
3394
|
+
const parts = [];
|
|
3395
|
+
if (versionNotice?.behind) {
|
|
3396
|
+
const versionInfo = getVersionNoticeForHook(versionNotice);
|
|
3397
|
+
if (versionInfo) {
|
|
3398
|
+
parts.push(versionInfo);
|
|
3399
|
+
parts.push("");
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
const highImportancePrefs = ctx?.preferences?.filter((p) => p.importance === "high") || [];
|
|
3403
|
+
if (highImportancePrefs.length > 0) {
|
|
3404
|
+
parts.push(`[USER PREFERENCES - Always respect these]`);
|
|
3405
|
+
for (const pref of highImportancePrefs.slice(0, 5)) {
|
|
3406
|
+
parts.push(`\u2022 ${pref.title}: ${pref.content}`);
|
|
3407
|
+
}
|
|
3408
|
+
parts.push("");
|
|
3409
|
+
}
|
|
3410
|
+
parts.push(REMINDER);
|
|
3411
|
+
return parts.join("\n");
|
|
3412
|
+
}
|
|
3413
|
+
function buildEnhancedReminder(ctx, isNewSession2, versionNotice) {
|
|
2805
3414
|
const parts = [ENHANCED_REMINDER_HEADER];
|
|
3415
|
+
if (versionNotice?.behind) {
|
|
3416
|
+
const versionInfo = getVersionNoticeForHook(versionNotice);
|
|
3417
|
+
if (versionInfo) {
|
|
3418
|
+
parts.push(`## \u{1F504} UPDATE AVAILABLE
|
|
3419
|
+
`);
|
|
3420
|
+
parts.push(versionInfo);
|
|
3421
|
+
parts.push("");
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
2806
3424
|
if (isNewSession2) {
|
|
2807
3425
|
parts.push(`## \u{1F680} NEW SESSION DETECTED
|
|
2808
3426
|
1. Call \`init(folder_path="...")\` - this triggers project indexing
|
|
2809
3427
|
2. Wait for indexing: if \`init\` returns \`indexing_status: "started"\`, files are being indexed
|
|
2810
|
-
3.
|
|
2811
|
-
4.
|
|
3428
|
+
3. Generate a unique session_id (e.g., "session-" + timestamp or UUID) - use this for ALL context() calls
|
|
3429
|
+
4. Call \`context(user_message="...", save_exchange=true, session_id="<your-session-id>")\` for task-specific context
|
|
3430
|
+
5. Use \`search(mode="hybrid")\` for code discovery (not Glob/Grep/Read)
|
|
2812
3431
|
|
|
2813
3432
|
`);
|
|
2814
3433
|
}
|
|
3434
|
+
const highImportancePrefs = ctx?.preferences?.filter((p) => p.importance === "high") || [];
|
|
3435
|
+
if (highImportancePrefs.length > 0) {
|
|
3436
|
+
parts.push(`## \u2699\uFE0F USER PREFERENCES - Always respect these`);
|
|
3437
|
+
for (const pref of highImportancePrefs.slice(0, 5)) {
|
|
3438
|
+
parts.push(`- **${pref.title}**: ${pref.content}`);
|
|
3439
|
+
}
|
|
3440
|
+
parts.push("");
|
|
3441
|
+
}
|
|
2815
3442
|
if (ctx?.lessons && ctx.lessons.length > 0) {
|
|
2816
3443
|
parts.push(`## \u26A0\uFE0F LESSONS FROM PAST MISTAKES`);
|
|
2817
3444
|
for (const lesson of ctx.lessons.slice(0, 3)) {
|
|
@@ -2929,20 +3556,26 @@ async function runUserPromptSubmitHook() {
|
|
|
2929
3556
|
}
|
|
2930
3557
|
const editorFormat = detectEditorFormat2(input);
|
|
2931
3558
|
const cwd = input.cwd || process.cwd();
|
|
3559
|
+
loadConfigFromMcpJson(cwd);
|
|
3560
|
+
const versionNoticePromise = getUpdateNotice();
|
|
3561
|
+
const lastExchange = extractLastExchange(input, editorFormat);
|
|
3562
|
+
const clientName = editorFormat === "claude" ? "claude-code" : editorFormat;
|
|
3563
|
+
const saveExchangePromise = lastExchange ? saveLastExchange(lastExchange, cwd, clientName) : Promise.resolve();
|
|
2932
3564
|
if (editorFormat === "claude") {
|
|
3565
|
+
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
3566
|
+
const claudeReminder = buildClaudeReminder(ctx, versionNotice);
|
|
2933
3567
|
console.log(
|
|
2934
3568
|
JSON.stringify({
|
|
2935
3569
|
hookSpecificOutput: {
|
|
2936
3570
|
hookEventName: "UserPromptSubmit",
|
|
2937
|
-
additionalContext:
|
|
3571
|
+
additionalContext: claudeReminder
|
|
2938
3572
|
}
|
|
2939
3573
|
})
|
|
2940
3574
|
);
|
|
2941
3575
|
} else if (editorFormat === "cline") {
|
|
2942
|
-
loadConfigFromMcpJson(cwd);
|
|
2943
3576
|
const newSession = isNewSession(input, editorFormat);
|
|
2944
|
-
const ctx = await fetchSessionContext();
|
|
2945
|
-
const enhancedReminder = buildEnhancedReminder(ctx, newSession);
|
|
3577
|
+
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
3578
|
+
const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
|
|
2946
3579
|
console.log(
|
|
2947
3580
|
JSON.stringify({
|
|
2948
3581
|
cancel: false,
|
|
@@ -2950,10 +3583,12 @@ async function runUserPromptSubmitHook() {
|
|
|
2950
3583
|
})
|
|
2951
3584
|
);
|
|
2952
3585
|
} else if (editorFormat === "cursor") {
|
|
2953
|
-
loadConfigFromMcpJson(cwd);
|
|
2954
3586
|
const newSession = isNewSession(input, editorFormat);
|
|
2955
|
-
const ctx = await fetchSessionContext();
|
|
2956
|
-
|
|
3587
|
+
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
3588
|
+
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").`;
|
|
3589
|
+
if (versionNotice?.behind) {
|
|
3590
|
+
cursorReminder += ` [UPDATE v${versionNotice.current}\u2192${versionNotice.latest}]`;
|
|
3591
|
+
}
|
|
2957
3592
|
console.log(
|
|
2958
3593
|
JSON.stringify({
|
|
2959
3594
|
continue: true,
|
|
@@ -2961,10 +3596,9 @@ async function runUserPromptSubmitHook() {
|
|
|
2961
3596
|
})
|
|
2962
3597
|
);
|
|
2963
3598
|
} else if (editorFormat === "antigravity") {
|
|
2964
|
-
loadConfigFromMcpJson(cwd);
|
|
2965
3599
|
const newSession = isNewSession(input, editorFormat);
|
|
2966
|
-
const ctx = await fetchSessionContext();
|
|
2967
|
-
const enhancedReminder = buildEnhancedReminder(ctx, newSession);
|
|
3600
|
+
const [ctx, versionNotice] = await Promise.all([fetchSessionContext(), versionNoticePromise, saveExchangePromise]);
|
|
3601
|
+
const enhancedReminder = buildEnhancedReminder(ctx, newSession, versionNotice);
|
|
2968
3602
|
console.log(
|
|
2969
3603
|
JSON.stringify({
|
|
2970
3604
|
cancel: false,
|
|
@@ -2978,6 +3612,7 @@ var ENABLED3, API_URL2, API_KEY2, WORKSPACE_ID, PROJECT_ID, REMINDER, ENHANCED_R
|
|
|
2978
3612
|
var init_user_prompt_submit = __esm({
|
|
2979
3613
|
"src/hooks/user-prompt-submit.ts"() {
|
|
2980
3614
|
"use strict";
|
|
3615
|
+
init_version();
|
|
2981
3616
|
ENABLED3 = process.env.CONTEXTSTREAM_REMINDER_ENABLED !== "false";
|
|
2982
3617
|
API_URL2 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
2983
3618
|
API_KEY2 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
@@ -2985,9 +3620,11 @@ var init_user_prompt_submit = __esm({
|
|
|
2985
3620
|
PROJECT_ID = null;
|
|
2986
3621
|
REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
|
|
2987
3622
|
|
|
2988
|
-
1. FIRST: Call mcp__contextstream__context(user_message="...") before ANY other tool
|
|
3623
|
+
1. FIRST: Call mcp__contextstream__context(user_message="...", save_exchange=true, session_id="<session-id>") before ANY other tool
|
|
2989
3624
|
- Returns: dynamic rules, lessons from past mistakes, relevant context
|
|
2990
3625
|
- Check response for: [LESSONS_WARNING], [RULES_NOTICE], preferences
|
|
3626
|
+
- save_exchange=true saves each conversation turn for later retrieval
|
|
3627
|
+
- Use a consistent session_id for the entire conversation (generate once on first message)
|
|
2991
3628
|
|
|
2992
3629
|
2. FOR CODE SEARCH: Check index status, then search appropriately
|
|
2993
3630
|
\u26A0\uFE0F BEFORE searching: mcp__contextstream__project(action="index_status")
|
|
@@ -3014,7 +3651,7 @@ var init_user_prompt_submit = __esm({
|
|
|
3014
3651
|
|
|
3015
3652
|
6. SKIP CONTEXTSTREAM: If user preference says "skip contextstream", use local tools instead
|
|
3016
3653
|
[END]`;
|
|
3017
|
-
ENHANCED_REMINDER_HEADER =
|
|
3654
|
+
ENHANCED_REMINDER_HEADER = `\u2B21 ContextStream \u2014 Smart Context & Memory
|
|
3018
3655
|
|
|
3019
3656
|
`;
|
|
3020
3657
|
isDirectRun3 = process.argv[1]?.includes("user-prompt-submit") || process.argv[2] === "user-prompt-submit";
|
|
@@ -4559,13 +5196,44 @@ async function fetchSessionContext2() {
|
|
|
4559
5196
|
return null;
|
|
4560
5197
|
}
|
|
4561
5198
|
}
|
|
4562
|
-
function formatContext(ctx) {
|
|
5199
|
+
function formatContext(ctx, options = {}) {
|
|
5200
|
+
const parts = ["\u2B21 ContextStream \u2014 Smart Context & Memory", ""];
|
|
5201
|
+
if (options.updateMarker) {
|
|
5202
|
+
parts.push(`
|
|
5203
|
+
## \u{1F389} UPDATE COMPLETE - RESTART CHAT SESSION`);
|
|
5204
|
+
parts.push(`ContextStream was auto-updated from v${options.updateMarker.previousVersion} to v${options.updateMarker.newVersion}.`);
|
|
5205
|
+
parts.push(`**Tell the user:** "ContextStream has been updated! Please start a new chat session (or restart your AI tool) to use the new version with the latest features and fixes."`);
|
|
5206
|
+
parts.push("");
|
|
5207
|
+
} else if (options.autoUpdateResult?.attempted) {
|
|
5208
|
+
if (options.autoUpdateResult.success) {
|
|
5209
|
+
parts.push(`
|
|
5210
|
+
## \u{1F504} AUTO-UPDATE INITIATED`);
|
|
5211
|
+
parts.push(`ContextStream is updating from v${options.autoUpdateResult.previousVersion} to v${options.autoUpdateResult.newVersion}.`);
|
|
5212
|
+
parts.push(`**Tell the user:** "ContextStream is updating in the background. Please start a new chat session (or restart your AI tool) in a moment to use the new version."`);
|
|
5213
|
+
parts.push("");
|
|
5214
|
+
} else if (options.autoUpdateResult.error) {
|
|
5215
|
+
parts.push(`
|
|
5216
|
+
## \u26A0\uFE0F AUTO-UPDATE FAILED`);
|
|
5217
|
+
parts.push(`Automatic update failed: ${options.autoUpdateResult.error}`);
|
|
5218
|
+
const versionInfo = getVersionNoticeForHook(options.versionNotice || null);
|
|
5219
|
+
if (versionInfo) {
|
|
5220
|
+
parts.push(versionInfo);
|
|
5221
|
+
}
|
|
5222
|
+
parts.push("");
|
|
5223
|
+
}
|
|
5224
|
+
} else if (options.versionNotice?.behind && !isAutoUpdateEnabled()) {
|
|
5225
|
+
const versionInfo = getVersionNoticeForHook(options.versionNotice);
|
|
5226
|
+
if (versionInfo) {
|
|
5227
|
+
parts.push(`
|
|
5228
|
+
## \u{1F504} UPDATE AVAILABLE (auto-update disabled)`);
|
|
5229
|
+
parts.push(versionInfo);
|
|
5230
|
+
parts.push("");
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
4563
5233
|
if (!ctx) {
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
No stored context found. Call \`mcp__contextstream__context(user_message="starting new session")\` to initialize.`;
|
|
5234
|
+
parts.push('\nNo stored context found. Call `mcp__contextstream__context(user_message="starting new session")` to initialize.');
|
|
5235
|
+
return parts.join("\n");
|
|
4567
5236
|
}
|
|
4568
|
-
const parts = ["[ContextStream Session Start]"];
|
|
4569
5237
|
if (ctx.lessons && ctx.lessons.length > 0) {
|
|
4570
5238
|
parts.push("\n## \u26A0\uFE0F Lessons from Past Mistakes");
|
|
4571
5239
|
for (const lesson of ctx.lessons.slice(0, 3)) {
|
|
@@ -4613,8 +5281,21 @@ async function runSessionInitHook() {
|
|
|
4613
5281
|
}
|
|
4614
5282
|
const cwd = input.cwd || process.cwd();
|
|
4615
5283
|
loadConfigFromMcpJson8(cwd);
|
|
4616
|
-
const
|
|
4617
|
-
|
|
5284
|
+
const updateMarker = checkUpdateMarker();
|
|
5285
|
+
if (updateMarker) {
|
|
5286
|
+
clearUpdateMarker();
|
|
5287
|
+
}
|
|
5288
|
+
const [context, autoUpdateResult, versionNotice] = await Promise.all([
|
|
5289
|
+
fetchSessionContext2(),
|
|
5290
|
+
updateMarker ? Promise.resolve(null) : attemptAutoUpdate(),
|
|
5291
|
+
// Skip if already updated
|
|
5292
|
+
getUpdateNotice()
|
|
5293
|
+
]);
|
|
5294
|
+
const formattedContext = formatContext(context, {
|
|
5295
|
+
autoUpdateResult,
|
|
5296
|
+
versionNotice,
|
|
5297
|
+
updateMarker
|
|
5298
|
+
});
|
|
4618
5299
|
console.log(
|
|
4619
5300
|
JSON.stringify({
|
|
4620
5301
|
hookSpecificOutput: {
|
|
@@ -4629,6 +5310,7 @@ var ENABLED12, API_URL10, API_KEY10, WORKSPACE_ID8, PROJECT_ID2, isDirectRun12;
|
|
|
4629
5310
|
var init_session_init = __esm({
|
|
4630
5311
|
"src/hooks/session-init.ts"() {
|
|
4631
5312
|
"use strict";
|
|
5313
|
+
init_version();
|
|
4632
5314
|
ENABLED12 = process.env.CONTEXTSTREAM_SESSION_INIT_ENABLED !== "false";
|
|
4633
5315
|
API_URL10 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4634
5316
|
API_KEY10 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
@@ -4669,15 +5351,18 @@ function loadConfigFromMcpJson9(cwd) {
|
|
|
4669
5351
|
}
|
|
4670
5352
|
}
|
|
4671
5353
|
}
|
|
4672
|
-
if (!WORKSPACE_ID9) {
|
|
5354
|
+
if (!WORKSPACE_ID9 || !PROJECT_ID3) {
|
|
4673
5355
|
const csConfigPath = path20.join(searchDir, ".contextstream", "config.json");
|
|
4674
5356
|
if (fs19.existsSync(csConfigPath)) {
|
|
4675
5357
|
try {
|
|
4676
5358
|
const content = fs19.readFileSync(csConfigPath, "utf-8");
|
|
4677
5359
|
const csConfig = JSON.parse(content);
|
|
4678
|
-
if (csConfig.workspace_id) {
|
|
5360
|
+
if (csConfig.workspace_id && !WORKSPACE_ID9) {
|
|
4679
5361
|
WORKSPACE_ID9 = csConfig.workspace_id;
|
|
4680
5362
|
}
|
|
5363
|
+
if (csConfig.project_id && !PROJECT_ID3) {
|
|
5364
|
+
PROJECT_ID3 = csConfig.project_id;
|
|
5365
|
+
}
|
|
4681
5366
|
} catch {
|
|
4682
5367
|
}
|
|
4683
5368
|
}
|
|
@@ -4709,7 +5394,9 @@ function parseTranscriptStats(transcriptPath) {
|
|
|
4709
5394
|
messageCount: 0,
|
|
4710
5395
|
toolCallCount: 0,
|
|
4711
5396
|
duration: 0,
|
|
4712
|
-
filesModified: []
|
|
5397
|
+
filesModified: [],
|
|
5398
|
+
messages: [],
|
|
5399
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4713
5400
|
};
|
|
4714
5401
|
if (!transcriptPath || !fs19.existsSync(transcriptPath)) {
|
|
4715
5402
|
return stats;
|
|
@@ -4724,26 +5411,63 @@ function parseTranscriptStats(transcriptPath) {
|
|
|
4724
5411
|
if (!line.trim()) continue;
|
|
4725
5412
|
try {
|
|
4726
5413
|
const entry = JSON.parse(line);
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
} else if (entry.type === "tool_use") {
|
|
4730
|
-
stats.toolCallCount++;
|
|
4731
|
-
if (["Write", "Edit", "NotebookEdit"].includes(entry.name || "")) {
|
|
4732
|
-
const filePath = entry.input?.file_path;
|
|
4733
|
-
if (filePath) {
|
|
4734
|
-
modifiedFiles.add(filePath);
|
|
4735
|
-
}
|
|
4736
|
-
}
|
|
4737
|
-
}
|
|
5414
|
+
const msgType = entry.type || "";
|
|
5415
|
+
const timestamp = entry.timestamp || (/* @__PURE__ */ new Date()).toISOString();
|
|
4738
5416
|
if (entry.timestamp) {
|
|
4739
5417
|
const ts = new Date(entry.timestamp);
|
|
4740
5418
|
if (!firstTimestamp || ts < firstTimestamp) {
|
|
4741
5419
|
firstTimestamp = ts;
|
|
5420
|
+
stats.startedAt = entry.timestamp;
|
|
4742
5421
|
}
|
|
4743
5422
|
if (!lastTimestamp || ts > lastTimestamp) {
|
|
4744
5423
|
lastTimestamp = ts;
|
|
4745
5424
|
}
|
|
4746
5425
|
}
|
|
5426
|
+
if (msgType === "user" || entry.role === "user") {
|
|
5427
|
+
stats.messageCount++;
|
|
5428
|
+
const userContent = typeof entry.content === "string" ? entry.content : "";
|
|
5429
|
+
if (userContent) {
|
|
5430
|
+
stats.messages.push({
|
|
5431
|
+
role: "user",
|
|
5432
|
+
content: userContent,
|
|
5433
|
+
timestamp
|
|
5434
|
+
});
|
|
5435
|
+
}
|
|
5436
|
+
} else if (msgType === "assistant" || entry.role === "assistant") {
|
|
5437
|
+
stats.messageCount++;
|
|
5438
|
+
const assistantContent = typeof entry.content === "string" ? entry.content : "";
|
|
5439
|
+
if (assistantContent) {
|
|
5440
|
+
stats.messages.push({
|
|
5441
|
+
role: "assistant",
|
|
5442
|
+
content: assistantContent,
|
|
5443
|
+
timestamp
|
|
5444
|
+
});
|
|
5445
|
+
}
|
|
5446
|
+
} else if (msgType === "tool_use") {
|
|
5447
|
+
stats.toolCallCount++;
|
|
5448
|
+
const toolName = entry.name || "";
|
|
5449
|
+
const toolInput = entry.input || {};
|
|
5450
|
+
if (["Write", "Edit", "NotebookEdit"].includes(toolName)) {
|
|
5451
|
+
const filePath = toolInput.file_path || toolInput.notebook_path;
|
|
5452
|
+
if (filePath) {
|
|
5453
|
+
modifiedFiles.add(filePath);
|
|
5454
|
+
}
|
|
5455
|
+
}
|
|
5456
|
+
stats.messages.push({
|
|
5457
|
+
role: "assistant",
|
|
5458
|
+
content: `[Tool: ${toolName}]`,
|
|
5459
|
+
timestamp,
|
|
5460
|
+
tool_calls: { name: toolName, input: toolInput }
|
|
5461
|
+
});
|
|
5462
|
+
} else if (msgType === "tool_result") {
|
|
5463
|
+
const resultContent = typeof entry.content === "string" ? entry.content.slice(0, 2e3) : JSON.stringify(entry.content || {}).slice(0, 2e3);
|
|
5464
|
+
stats.messages.push({
|
|
5465
|
+
role: "tool",
|
|
5466
|
+
content: resultContent,
|
|
5467
|
+
timestamp,
|
|
5468
|
+
tool_results: { name: entry.name }
|
|
5469
|
+
});
|
|
5470
|
+
}
|
|
4747
5471
|
} catch {
|
|
4748
5472
|
continue;
|
|
4749
5473
|
}
|
|
@@ -4751,15 +5475,66 @@ function parseTranscriptStats(transcriptPath) {
|
|
|
4751
5475
|
if (firstTimestamp && lastTimestamp) {
|
|
4752
5476
|
stats.duration = Math.round((lastTimestamp.getTime() - firstTimestamp.getTime()) / 1e3);
|
|
4753
5477
|
}
|
|
4754
|
-
stats.filesModified = Array.from(modifiedFiles);
|
|
4755
|
-
} catch {
|
|
5478
|
+
stats.filesModified = Array.from(modifiedFiles);
|
|
5479
|
+
} catch {
|
|
5480
|
+
}
|
|
5481
|
+
return stats;
|
|
5482
|
+
}
|
|
5483
|
+
async function saveFullTranscript2(sessionId, stats, reason) {
|
|
5484
|
+
if (!API_KEY11) {
|
|
5485
|
+
return { success: false, message: "No API key configured" };
|
|
5486
|
+
}
|
|
5487
|
+
if (stats.messages.length === 0) {
|
|
5488
|
+
return { success: false, message: "No messages to save" };
|
|
5489
|
+
}
|
|
5490
|
+
const payload = {
|
|
5491
|
+
session_id: sessionId,
|
|
5492
|
+
messages: stats.messages,
|
|
5493
|
+
started_at: stats.startedAt,
|
|
5494
|
+
source_type: "session_end",
|
|
5495
|
+
title: `Session transcript (${reason})`,
|
|
5496
|
+
metadata: {
|
|
5497
|
+
reason,
|
|
5498
|
+
tool_call_count: stats.toolCallCount,
|
|
5499
|
+
files_modified: stats.filesModified.slice(0, 20),
|
|
5500
|
+
duration_seconds: stats.duration
|
|
5501
|
+
},
|
|
5502
|
+
tags: ["session_end", reason]
|
|
5503
|
+
};
|
|
5504
|
+
if (WORKSPACE_ID9) {
|
|
5505
|
+
payload.workspace_id = WORKSPACE_ID9;
|
|
5506
|
+
}
|
|
5507
|
+
if (PROJECT_ID3) {
|
|
5508
|
+
payload.project_id = PROJECT_ID3;
|
|
5509
|
+
}
|
|
5510
|
+
try {
|
|
5511
|
+
const controller = new AbortController();
|
|
5512
|
+
const timeoutId = setTimeout(() => controller.abort(), 15e3);
|
|
5513
|
+
const response = await fetch(`${API_URL11}/api/v1/transcripts`, {
|
|
5514
|
+
method: "POST",
|
|
5515
|
+
headers: {
|
|
5516
|
+
"Content-Type": "application/json",
|
|
5517
|
+
"X-API-Key": API_KEY11
|
|
5518
|
+
},
|
|
5519
|
+
body: JSON.stringify(payload),
|
|
5520
|
+
signal: controller.signal
|
|
5521
|
+
});
|
|
5522
|
+
clearTimeout(timeoutId);
|
|
5523
|
+
if (response.ok) {
|
|
5524
|
+
return { success: true, message: `Transcript saved (${stats.messages.length} messages)` };
|
|
5525
|
+
}
|
|
5526
|
+
return { success: false, message: `API error: ${response.status}` };
|
|
5527
|
+
} catch (error) {
|
|
5528
|
+
return { success: false, message: String(error) };
|
|
4756
5529
|
}
|
|
4757
|
-
return stats;
|
|
4758
5530
|
}
|
|
4759
5531
|
async function finalizeSession(sessionId, stats, reason) {
|
|
4760
5532
|
if (!API_KEY11) return;
|
|
5533
|
+
if (SAVE_TRANSCRIPT && stats.messages.length > 0) {
|
|
5534
|
+
await saveFullTranscript2(sessionId, stats, reason);
|
|
5535
|
+
}
|
|
4761
5536
|
const payload = {
|
|
4762
|
-
event_type: "
|
|
5537
|
+
event_type: "manual_note",
|
|
4763
5538
|
title: `Session Ended: ${reason}`,
|
|
4764
5539
|
content: JSON.stringify({
|
|
4765
5540
|
session_id: sessionId,
|
|
@@ -4775,8 +5550,7 @@ async function finalizeSession(sessionId, stats, reason) {
|
|
|
4775
5550
|
}),
|
|
4776
5551
|
importance: "low",
|
|
4777
5552
|
tags: ["session", "end", reason],
|
|
4778
|
-
source_type: "hook"
|
|
4779
|
-
session_id: sessionId
|
|
5553
|
+
source_type: "hook"
|
|
4780
5554
|
};
|
|
4781
5555
|
if (WORKSPACE_ID9) {
|
|
4782
5556
|
payload.workspace_id = WORKSPACE_ID9;
|
|
@@ -4823,14 +5597,16 @@ async function runSessionEndHook() {
|
|
|
4823
5597
|
await finalizeSession(sessionId, stats, reason);
|
|
4824
5598
|
process.exit(0);
|
|
4825
5599
|
}
|
|
4826
|
-
var ENABLED13, API_URL11, API_KEY11, WORKSPACE_ID9, isDirectRun13;
|
|
5600
|
+
var ENABLED13, SAVE_TRANSCRIPT, API_URL11, API_KEY11, WORKSPACE_ID9, PROJECT_ID3, isDirectRun13;
|
|
4827
5601
|
var init_session_end = __esm({
|
|
4828
5602
|
"src/hooks/session-end.ts"() {
|
|
4829
5603
|
"use strict";
|
|
4830
5604
|
ENABLED13 = process.env.CONTEXTSTREAM_SESSION_END_ENABLED !== "false";
|
|
5605
|
+
SAVE_TRANSCRIPT = process.env.CONTEXTSTREAM_SESSION_END_SAVE_TRANSCRIPT !== "false";
|
|
4831
5606
|
API_URL11 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4832
5607
|
API_KEY11 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4833
5608
|
WORKSPACE_ID9 = null;
|
|
5609
|
+
PROJECT_ID3 = null;
|
|
4834
5610
|
isDirectRun13 = process.argv[1]?.includes("session-end") || process.argv[2] === "session-end";
|
|
4835
5611
|
if (isDirectRun13) {
|
|
4836
5612
|
runSessionEndHook().catch(() => process.exit(0));
|
|
@@ -4988,10 +5764,11 @@ import * as fs20 from "node:fs";
|
|
|
4988
5764
|
import * as path21 from "node:path";
|
|
4989
5765
|
import { homedir as homedir18 } from "node:os";
|
|
4990
5766
|
function maskApiKey2(key) {
|
|
4991
|
-
if (!key || key.length <
|
|
4992
|
-
const
|
|
4993
|
-
const
|
|
4994
|
-
|
|
5767
|
+
if (!key || key.length < 8) return "***";
|
|
5768
|
+
const prefixMatch = key.match(/^([a-z]{2,3}_)/i);
|
|
5769
|
+
const prefix = prefixMatch ? prefixMatch[1] : "";
|
|
5770
|
+
const suffix = key.slice(-3);
|
|
5771
|
+
return `${prefix}***...${suffix}`;
|
|
4995
5772
|
}
|
|
4996
5773
|
function extractFromMcpConfig(config) {
|
|
4997
5774
|
if (!config.mcpServers) return {};
|
|
@@ -5016,10 +5793,10 @@ function extractFromMcpConfig(config) {
|
|
|
5016
5793
|
return {};
|
|
5017
5794
|
}
|
|
5018
5795
|
function getClaudeDesktopConfigPath() {
|
|
5019
|
-
const
|
|
5020
|
-
if (
|
|
5796
|
+
const platform2 = process.platform;
|
|
5797
|
+
if (platform2 === "darwin") {
|
|
5021
5798
|
return path21.join(homedir18(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
5022
|
-
} else if (
|
|
5799
|
+
} else if (platform2 === "win32") {
|
|
5023
5800
|
return path21.join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
|
|
5024
5801
|
} else {
|
|
5025
5802
|
return path21.join(homedir18(), ".config", "Claude", "claude_desktop_config.json");
|
|
@@ -5174,6 +5951,7 @@ async function validateApiKey(apiKey, apiUrl) {
|
|
|
5174
5951
|
return {
|
|
5175
5952
|
valid: true,
|
|
5176
5953
|
masked_key: maskApiKey2(apiKey),
|
|
5954
|
+
// lgtm[js/clear-text-logging]
|
|
5177
5955
|
email: data.email,
|
|
5178
5956
|
name: data.name || data.full_name,
|
|
5179
5957
|
plan: data.plan_name || data.plan || "free",
|
|
@@ -5183,12 +5961,14 @@ async function validateApiKey(apiKey, apiUrl) {
|
|
|
5183
5961
|
return {
|
|
5184
5962
|
valid: false,
|
|
5185
5963
|
masked_key: maskApiKey2(apiKey),
|
|
5964
|
+
// lgtm[js/clear-text-logging]
|
|
5186
5965
|
error: "Invalid or expired API key"
|
|
5187
5966
|
};
|
|
5188
5967
|
} else {
|
|
5189
5968
|
return {
|
|
5190
5969
|
valid: false,
|
|
5191
5970
|
masked_key: maskApiKey2(apiKey),
|
|
5971
|
+
// lgtm[js/clear-text-logging]
|
|
5192
5972
|
error: `API error: ${response.status}`
|
|
5193
5973
|
};
|
|
5194
5974
|
}
|
|
@@ -8918,561 +9698,390 @@ var ZodEffects = class extends ZodType {
|
|
|
8918
9698
|
const result = effect.transform(base.value, checkCtx);
|
|
8919
9699
|
if (result instanceof Promise) {
|
|
8920
9700
|
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
|
|
8921
|
-
}
|
|
8922
|
-
return { status: status.value, value: result };
|
|
8923
|
-
} else {
|
|
8924
|
-
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
|
|
8925
|
-
if (!isValid(base))
|
|
8926
|
-
return INVALID;
|
|
8927
|
-
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
8928
|
-
status: status.value,
|
|
8929
|
-
value: result
|
|
8930
|
-
}));
|
|
8931
|
-
});
|
|
8932
|
-
}
|
|
8933
|
-
}
|
|
8934
|
-
util.assertNever(effect);
|
|
8935
|
-
}
|
|
8936
|
-
};
|
|
8937
|
-
ZodEffects.create = (schema, effect, params) => {
|
|
8938
|
-
return new ZodEffects({
|
|
8939
|
-
schema,
|
|
8940
|
-
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
|
8941
|
-
effect,
|
|
8942
|
-
...processCreateParams(params)
|
|
8943
|
-
});
|
|
8944
|
-
};
|
|
8945
|
-
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
|
|
8946
|
-
return new ZodEffects({
|
|
8947
|
-
schema,
|
|
8948
|
-
effect: { type: "preprocess", transform: preprocess },
|
|
8949
|
-
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
|
8950
|
-
...processCreateParams(params)
|
|
8951
|
-
});
|
|
8952
|
-
};
|
|
8953
|
-
var ZodOptional = class extends ZodType {
|
|
8954
|
-
_parse(input) {
|
|
8955
|
-
const parsedType = this._getType(input);
|
|
8956
|
-
if (parsedType === ZodParsedType.undefined) {
|
|
8957
|
-
return OK(void 0);
|
|
8958
|
-
}
|
|
8959
|
-
return this._def.innerType._parse(input);
|
|
8960
|
-
}
|
|
8961
|
-
unwrap() {
|
|
8962
|
-
return this._def.innerType;
|
|
8963
|
-
}
|
|
8964
|
-
};
|
|
8965
|
-
ZodOptional.create = (type, params) => {
|
|
8966
|
-
return new ZodOptional({
|
|
8967
|
-
innerType: type,
|
|
8968
|
-
typeName: ZodFirstPartyTypeKind.ZodOptional,
|
|
8969
|
-
...processCreateParams(params)
|
|
8970
|
-
});
|
|
8971
|
-
};
|
|
8972
|
-
var ZodNullable = class extends ZodType {
|
|
8973
|
-
_parse(input) {
|
|
8974
|
-
const parsedType = this._getType(input);
|
|
8975
|
-
if (parsedType === ZodParsedType.null) {
|
|
8976
|
-
return OK(null);
|
|
8977
|
-
}
|
|
8978
|
-
return this._def.innerType._parse(input);
|
|
8979
|
-
}
|
|
8980
|
-
unwrap() {
|
|
8981
|
-
return this._def.innerType;
|
|
8982
|
-
}
|
|
8983
|
-
};
|
|
8984
|
-
ZodNullable.create = (type, params) => {
|
|
8985
|
-
return new ZodNullable({
|
|
8986
|
-
innerType: type,
|
|
8987
|
-
typeName: ZodFirstPartyTypeKind.ZodNullable,
|
|
8988
|
-
...processCreateParams(params)
|
|
8989
|
-
});
|
|
8990
|
-
};
|
|
8991
|
-
var ZodDefault = class extends ZodType {
|
|
8992
|
-
_parse(input) {
|
|
8993
|
-
const { ctx } = this._processInputParams(input);
|
|
8994
|
-
let data = ctx.data;
|
|
8995
|
-
if (ctx.parsedType === ZodParsedType.undefined) {
|
|
8996
|
-
data = this._def.defaultValue();
|
|
8997
|
-
}
|
|
8998
|
-
return this._def.innerType._parse({
|
|
8999
|
-
data,
|
|
9000
|
-
path: ctx.path,
|
|
9001
|
-
parent: ctx
|
|
9002
|
-
});
|
|
9003
|
-
}
|
|
9004
|
-
removeDefault() {
|
|
9005
|
-
return this._def.innerType;
|
|
9006
|
-
}
|
|
9007
|
-
};
|
|
9008
|
-
ZodDefault.create = (type, params) => {
|
|
9009
|
-
return new ZodDefault({
|
|
9010
|
-
innerType: type,
|
|
9011
|
-
typeName: ZodFirstPartyTypeKind.ZodDefault,
|
|
9012
|
-
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
|
|
9013
|
-
...processCreateParams(params)
|
|
9014
|
-
});
|
|
9015
|
-
};
|
|
9016
|
-
var ZodCatch = class extends ZodType {
|
|
9017
|
-
_parse(input) {
|
|
9018
|
-
const { ctx } = this._processInputParams(input);
|
|
9019
|
-
const newCtx = {
|
|
9020
|
-
...ctx,
|
|
9021
|
-
common: {
|
|
9022
|
-
...ctx.common,
|
|
9023
|
-
issues: []
|
|
9024
|
-
}
|
|
9025
|
-
};
|
|
9026
|
-
const result = this._def.innerType._parse({
|
|
9027
|
-
data: newCtx.data,
|
|
9028
|
-
path: newCtx.path,
|
|
9029
|
-
parent: {
|
|
9030
|
-
...newCtx
|
|
9031
|
-
}
|
|
9032
|
-
});
|
|
9033
|
-
if (isAsync(result)) {
|
|
9034
|
-
return result.then((result2) => {
|
|
9035
|
-
return {
|
|
9036
|
-
status: "valid",
|
|
9037
|
-
value: result2.status === "valid" ? result2.value : this._def.catchValue({
|
|
9038
|
-
get error() {
|
|
9039
|
-
return new ZodError(newCtx.common.issues);
|
|
9040
|
-
},
|
|
9041
|
-
input: newCtx.data
|
|
9042
|
-
})
|
|
9043
|
-
};
|
|
9044
|
-
});
|
|
9045
|
-
} else {
|
|
9046
|
-
return {
|
|
9047
|
-
status: "valid",
|
|
9048
|
-
value: result.status === "valid" ? result.value : this._def.catchValue({
|
|
9049
|
-
get error() {
|
|
9050
|
-
return new ZodError(newCtx.common.issues);
|
|
9051
|
-
},
|
|
9052
|
-
input: newCtx.data
|
|
9053
|
-
})
|
|
9054
|
-
};
|
|
9055
|
-
}
|
|
9056
|
-
}
|
|
9057
|
-
removeCatch() {
|
|
9058
|
-
return this._def.innerType;
|
|
9059
|
-
}
|
|
9060
|
-
};
|
|
9061
|
-
ZodCatch.create = (type, params) => {
|
|
9062
|
-
return new ZodCatch({
|
|
9063
|
-
innerType: type,
|
|
9064
|
-
typeName: ZodFirstPartyTypeKind.ZodCatch,
|
|
9065
|
-
catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
|
|
9066
|
-
...processCreateParams(params)
|
|
9067
|
-
});
|
|
9068
|
-
};
|
|
9069
|
-
var ZodNaN = class extends ZodType {
|
|
9070
|
-
_parse(input) {
|
|
9071
|
-
const parsedType = this._getType(input);
|
|
9072
|
-
if (parsedType !== ZodParsedType.nan) {
|
|
9073
|
-
const ctx = this._getOrReturnCtx(input);
|
|
9074
|
-
addIssueToContext(ctx, {
|
|
9075
|
-
code: ZodIssueCode.invalid_type,
|
|
9076
|
-
expected: ZodParsedType.nan,
|
|
9077
|
-
received: ctx.parsedType
|
|
9078
|
-
});
|
|
9079
|
-
return INVALID;
|
|
9080
|
-
}
|
|
9081
|
-
return { status: "valid", value: input.data };
|
|
9082
|
-
}
|
|
9083
|
-
};
|
|
9084
|
-
ZodNaN.create = (params) => {
|
|
9085
|
-
return new ZodNaN({
|
|
9086
|
-
typeName: ZodFirstPartyTypeKind.ZodNaN,
|
|
9087
|
-
...processCreateParams(params)
|
|
9088
|
-
});
|
|
9089
|
-
};
|
|
9090
|
-
var BRAND = /* @__PURE__ */ Symbol("zod_brand");
|
|
9091
|
-
var ZodBranded = class extends ZodType {
|
|
9092
|
-
_parse(input) {
|
|
9093
|
-
const { ctx } = this._processInputParams(input);
|
|
9094
|
-
const data = ctx.data;
|
|
9095
|
-
return this._def.type._parse({
|
|
9096
|
-
data,
|
|
9097
|
-
path: ctx.path,
|
|
9098
|
-
parent: ctx
|
|
9099
|
-
});
|
|
9100
|
-
}
|
|
9101
|
-
unwrap() {
|
|
9102
|
-
return this._def.type;
|
|
9103
|
-
}
|
|
9104
|
-
};
|
|
9105
|
-
var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
9106
|
-
_parse(input) {
|
|
9107
|
-
const { status, ctx } = this._processInputParams(input);
|
|
9108
|
-
if (ctx.common.async) {
|
|
9109
|
-
const handleAsync = async () => {
|
|
9110
|
-
const inResult = await this._def.in._parseAsync({
|
|
9111
|
-
data: ctx.data,
|
|
9112
|
-
path: ctx.path,
|
|
9113
|
-
parent: ctx
|
|
9114
|
-
});
|
|
9115
|
-
if (inResult.status === "aborted")
|
|
9116
|
-
return INVALID;
|
|
9117
|
-
if (inResult.status === "dirty") {
|
|
9118
|
-
status.dirty();
|
|
9119
|
-
return DIRTY(inResult.value);
|
|
9120
|
-
} else {
|
|
9121
|
-
return this._def.out._parseAsync({
|
|
9122
|
-
data: inResult.value,
|
|
9123
|
-
path: ctx.path,
|
|
9124
|
-
parent: ctx
|
|
9125
|
-
});
|
|
9126
|
-
}
|
|
9127
|
-
};
|
|
9128
|
-
return handleAsync();
|
|
9129
|
-
} else {
|
|
9130
|
-
const inResult = this._def.in._parseSync({
|
|
9131
|
-
data: ctx.data,
|
|
9132
|
-
path: ctx.path,
|
|
9133
|
-
parent: ctx
|
|
9134
|
-
});
|
|
9135
|
-
if (inResult.status === "aborted")
|
|
9136
|
-
return INVALID;
|
|
9137
|
-
if (inResult.status === "dirty") {
|
|
9138
|
-
status.dirty();
|
|
9139
|
-
return {
|
|
9140
|
-
status: "dirty",
|
|
9141
|
-
value: inResult.value
|
|
9142
|
-
};
|
|
9701
|
+
}
|
|
9702
|
+
return { status: status.value, value: result };
|
|
9143
9703
|
} else {
|
|
9144
|
-
return this._def.
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9704
|
+
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
|
|
9705
|
+
if (!isValid(base))
|
|
9706
|
+
return INVALID;
|
|
9707
|
+
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
|
|
9708
|
+
status: status.value,
|
|
9709
|
+
value: result
|
|
9710
|
+
}));
|
|
9148
9711
|
});
|
|
9149
9712
|
}
|
|
9150
9713
|
}
|
|
9151
|
-
|
|
9152
|
-
static create(a, b) {
|
|
9153
|
-
return new _ZodPipeline({
|
|
9154
|
-
in: a,
|
|
9155
|
-
out: b,
|
|
9156
|
-
typeName: ZodFirstPartyTypeKind.ZodPipeline
|
|
9157
|
-
});
|
|
9714
|
+
util.assertNever(effect);
|
|
9158
9715
|
}
|
|
9159
9716
|
};
|
|
9160
|
-
|
|
9717
|
+
ZodEffects.create = (schema, effect, params) => {
|
|
9718
|
+
return new ZodEffects({
|
|
9719
|
+
schema,
|
|
9720
|
+
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
|
9721
|
+
effect,
|
|
9722
|
+
...processCreateParams(params)
|
|
9723
|
+
});
|
|
9724
|
+
};
|
|
9725
|
+
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
|
|
9726
|
+
return new ZodEffects({
|
|
9727
|
+
schema,
|
|
9728
|
+
effect: { type: "preprocess", transform: preprocess },
|
|
9729
|
+
typeName: ZodFirstPartyTypeKind.ZodEffects,
|
|
9730
|
+
...processCreateParams(params)
|
|
9731
|
+
});
|
|
9732
|
+
};
|
|
9733
|
+
var ZodOptional = class extends ZodType {
|
|
9161
9734
|
_parse(input) {
|
|
9162
|
-
const
|
|
9163
|
-
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
return data;
|
|
9168
|
-
};
|
|
9169
|
-
return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
|
|
9735
|
+
const parsedType = this._getType(input);
|
|
9736
|
+
if (parsedType === ZodParsedType.undefined) {
|
|
9737
|
+
return OK(void 0);
|
|
9738
|
+
}
|
|
9739
|
+
return this._def.innerType._parse(input);
|
|
9170
9740
|
}
|
|
9171
9741
|
unwrap() {
|
|
9172
9742
|
return this._def.innerType;
|
|
9173
9743
|
}
|
|
9174
9744
|
};
|
|
9175
|
-
|
|
9176
|
-
return new
|
|
9745
|
+
ZodOptional.create = (type, params) => {
|
|
9746
|
+
return new ZodOptional({
|
|
9177
9747
|
innerType: type,
|
|
9178
|
-
typeName: ZodFirstPartyTypeKind.
|
|
9748
|
+
typeName: ZodFirstPartyTypeKind.ZodOptional,
|
|
9179
9749
|
...processCreateParams(params)
|
|
9180
9750
|
});
|
|
9181
9751
|
};
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
function custom(check, _params = {}, fatal) {
|
|
9188
|
-
if (check)
|
|
9189
|
-
return ZodAny.create().superRefine((data, ctx) => {
|
|
9190
|
-
const r = check(data);
|
|
9191
|
-
if (r instanceof Promise) {
|
|
9192
|
-
return r.then((r2) => {
|
|
9193
|
-
if (!r2) {
|
|
9194
|
-
const params = cleanParams(_params, data);
|
|
9195
|
-
const _fatal = params.fatal ?? fatal ?? true;
|
|
9196
|
-
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
9197
|
-
}
|
|
9198
|
-
});
|
|
9199
|
-
}
|
|
9200
|
-
if (!r) {
|
|
9201
|
-
const params = cleanParams(_params, data);
|
|
9202
|
-
const _fatal = params.fatal ?? fatal ?? true;
|
|
9203
|
-
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
9204
|
-
}
|
|
9205
|
-
return;
|
|
9206
|
-
});
|
|
9207
|
-
return ZodAny.create();
|
|
9208
|
-
}
|
|
9209
|
-
var late = {
|
|
9210
|
-
object: ZodObject.lazycreate
|
|
9211
|
-
};
|
|
9212
|
-
var ZodFirstPartyTypeKind;
|
|
9213
|
-
(function(ZodFirstPartyTypeKind2) {
|
|
9214
|
-
ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
|
|
9215
|
-
ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
|
|
9216
|
-
ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
|
|
9217
|
-
ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
|
|
9218
|
-
ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
|
|
9219
|
-
ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
|
|
9220
|
-
ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
|
|
9221
|
-
ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
|
|
9222
|
-
ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
|
|
9223
|
-
ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
|
|
9224
|
-
ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
|
|
9225
|
-
ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
|
|
9226
|
-
ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
|
|
9227
|
-
ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
|
|
9228
|
-
ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
|
|
9229
|
-
ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
|
|
9230
|
-
ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
|
|
9231
|
-
ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
|
|
9232
|
-
ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
|
|
9233
|
-
ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
|
|
9234
|
-
ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
|
|
9235
|
-
ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
|
|
9236
|
-
ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
|
|
9237
|
-
ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
|
|
9238
|
-
ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
|
|
9239
|
-
ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
|
|
9240
|
-
ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
|
|
9241
|
-
ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
|
|
9242
|
-
ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
|
|
9243
|
-
ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
|
|
9244
|
-
ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
|
|
9245
|
-
ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
|
|
9246
|
-
ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
|
|
9247
|
-
ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
|
|
9248
|
-
ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
|
|
9249
|
-
ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
|
|
9250
|
-
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
|
9251
|
-
var instanceOfType = (cls, params = {
|
|
9252
|
-
message: `Input not instance of ${cls.name}`
|
|
9253
|
-
}) => custom((data) => data instanceof cls, params);
|
|
9254
|
-
var stringType = ZodString.create;
|
|
9255
|
-
var numberType = ZodNumber.create;
|
|
9256
|
-
var nanType = ZodNaN.create;
|
|
9257
|
-
var bigIntType = ZodBigInt.create;
|
|
9258
|
-
var booleanType = ZodBoolean.create;
|
|
9259
|
-
var dateType = ZodDate.create;
|
|
9260
|
-
var symbolType = ZodSymbol.create;
|
|
9261
|
-
var undefinedType = ZodUndefined.create;
|
|
9262
|
-
var nullType = ZodNull.create;
|
|
9263
|
-
var anyType = ZodAny.create;
|
|
9264
|
-
var unknownType = ZodUnknown.create;
|
|
9265
|
-
var neverType = ZodNever.create;
|
|
9266
|
-
var voidType = ZodVoid.create;
|
|
9267
|
-
var arrayType = ZodArray.create;
|
|
9268
|
-
var objectType = ZodObject.create;
|
|
9269
|
-
var strictObjectType = ZodObject.strictCreate;
|
|
9270
|
-
var unionType = ZodUnion.create;
|
|
9271
|
-
var discriminatedUnionType = ZodDiscriminatedUnion.create;
|
|
9272
|
-
var intersectionType = ZodIntersection.create;
|
|
9273
|
-
var tupleType = ZodTuple.create;
|
|
9274
|
-
var recordType = ZodRecord.create;
|
|
9275
|
-
var mapType = ZodMap.create;
|
|
9276
|
-
var setType = ZodSet.create;
|
|
9277
|
-
var functionType = ZodFunction.create;
|
|
9278
|
-
var lazyType = ZodLazy.create;
|
|
9279
|
-
var literalType = ZodLiteral.create;
|
|
9280
|
-
var enumType = ZodEnum.create;
|
|
9281
|
-
var nativeEnumType = ZodNativeEnum.create;
|
|
9282
|
-
var promiseType = ZodPromise.create;
|
|
9283
|
-
var effectsType = ZodEffects.create;
|
|
9284
|
-
var optionalType = ZodOptional.create;
|
|
9285
|
-
var nullableType = ZodNullable.create;
|
|
9286
|
-
var preprocessType = ZodEffects.createWithPreprocess;
|
|
9287
|
-
var pipelineType = ZodPipeline.create;
|
|
9288
|
-
var ostring = () => stringType().optional();
|
|
9289
|
-
var onumber = () => numberType().optional();
|
|
9290
|
-
var oboolean = () => booleanType().optional();
|
|
9291
|
-
var coerce = {
|
|
9292
|
-
string: ((arg) => ZodString.create({ ...arg, coerce: true })),
|
|
9293
|
-
number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
|
|
9294
|
-
boolean: ((arg) => ZodBoolean.create({
|
|
9295
|
-
...arg,
|
|
9296
|
-
coerce: true
|
|
9297
|
-
})),
|
|
9298
|
-
bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
|
|
9299
|
-
date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
|
|
9300
|
-
};
|
|
9301
|
-
var NEVER = INVALID;
|
|
9302
|
-
|
|
9303
|
-
// src/version.ts
|
|
9304
|
-
import { createRequire } from "module";
|
|
9305
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9306
|
-
import { homedir } from "os";
|
|
9307
|
-
import { join } from "path";
|
|
9308
|
-
var UPGRADE_COMMAND = "npm install -g @contextstream/mcp-server@latest";
|
|
9309
|
-
var NPM_LATEST_URL = "https://registry.npmjs.org/@contextstream/mcp-server/latest";
|
|
9310
|
-
function getVersion() {
|
|
9311
|
-
if (typeof __CONTEXTSTREAM_VERSION__ !== "undefined" && __CONTEXTSTREAM_VERSION__) {
|
|
9312
|
-
return __CONTEXTSTREAM_VERSION__;
|
|
9313
|
-
}
|
|
9314
|
-
try {
|
|
9315
|
-
const require2 = createRequire(import.meta.url);
|
|
9316
|
-
const pkg = require2("../package.json");
|
|
9317
|
-
const version = pkg?.version;
|
|
9318
|
-
if (typeof version === "string" && version.trim()) return version.trim();
|
|
9319
|
-
} catch {
|
|
9320
|
-
}
|
|
9321
|
-
return "unknown";
|
|
9322
|
-
}
|
|
9323
|
-
var VERSION = getVersion();
|
|
9324
|
-
function compareVersions(v1, v2) {
|
|
9325
|
-
const parts1 = v1.split(".").map(Number);
|
|
9326
|
-
const parts2 = v2.split(".").map(Number);
|
|
9327
|
-
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
|
9328
|
-
const p1 = parts1[i] ?? 0;
|
|
9329
|
-
const p2 = parts2[i] ?? 0;
|
|
9330
|
-
if (p1 < p2) return -1;
|
|
9331
|
-
if (p1 > p2) return 1;
|
|
9332
|
-
}
|
|
9333
|
-
return 0;
|
|
9334
|
-
}
|
|
9335
|
-
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
9336
|
-
var latestVersionPromise = null;
|
|
9337
|
-
function getCacheFilePath() {
|
|
9338
|
-
return join(homedir(), ".contextstream", "version-cache.json");
|
|
9339
|
-
}
|
|
9340
|
-
function readCache() {
|
|
9341
|
-
try {
|
|
9342
|
-
const cacheFile = getCacheFilePath();
|
|
9343
|
-
if (!existsSync(cacheFile)) return null;
|
|
9344
|
-
const data = JSON.parse(readFileSync(cacheFile, "utf-8"));
|
|
9345
|
-
if (Date.now() - data.checkedAt > CACHE_TTL_MS) return null;
|
|
9346
|
-
return data;
|
|
9347
|
-
} catch {
|
|
9348
|
-
return null;
|
|
9349
|
-
}
|
|
9350
|
-
}
|
|
9351
|
-
function writeCache(latestVersion) {
|
|
9352
|
-
try {
|
|
9353
|
-
const configDir = join(homedir(), ".contextstream");
|
|
9354
|
-
if (!existsSync(configDir)) {
|
|
9355
|
-
mkdirSync(configDir, { recursive: true });
|
|
9752
|
+
var ZodNullable = class extends ZodType {
|
|
9753
|
+
_parse(input) {
|
|
9754
|
+
const parsedType = this._getType(input);
|
|
9755
|
+
if (parsedType === ZodParsedType.null) {
|
|
9756
|
+
return OK(null);
|
|
9356
9757
|
}
|
|
9357
|
-
|
|
9358
|
-
writeFileSync(
|
|
9359
|
-
cacheFile,
|
|
9360
|
-
JSON.stringify({
|
|
9361
|
-
latestVersion,
|
|
9362
|
-
checkedAt: Date.now()
|
|
9363
|
-
})
|
|
9364
|
-
);
|
|
9365
|
-
} catch {
|
|
9758
|
+
return this._def.innerType._parse(input);
|
|
9366
9759
|
}
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
try {
|
|
9370
|
-
const controller = new AbortController();
|
|
9371
|
-
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
9372
|
-
const response = await fetch(NPM_LATEST_URL, {
|
|
9373
|
-
signal: controller.signal,
|
|
9374
|
-
headers: { Accept: "application/json" }
|
|
9375
|
-
});
|
|
9376
|
-
clearTimeout(timeout);
|
|
9377
|
-
if (!response.ok) return null;
|
|
9378
|
-
const data = await response.json();
|
|
9379
|
-
return typeof data.version === "string" ? data.version : null;
|
|
9380
|
-
} catch {
|
|
9381
|
-
return null;
|
|
9760
|
+
unwrap() {
|
|
9761
|
+
return this._def.innerType;
|
|
9382
9762
|
}
|
|
9383
|
-
}
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9763
|
+
};
|
|
9764
|
+
ZodNullable.create = (type, params) => {
|
|
9765
|
+
return new ZodNullable({
|
|
9766
|
+
innerType: type,
|
|
9767
|
+
typeName: ZodFirstPartyTypeKind.ZodNullable,
|
|
9768
|
+
...processCreateParams(params)
|
|
9769
|
+
});
|
|
9770
|
+
};
|
|
9771
|
+
var ZodDefault = class extends ZodType {
|
|
9772
|
+
_parse(input) {
|
|
9773
|
+
const { ctx } = this._processInputParams(input);
|
|
9774
|
+
let data = ctx.data;
|
|
9775
|
+
if (ctx.parsedType === ZodParsedType.undefined) {
|
|
9776
|
+
data = this._def.defaultValue();
|
|
9777
|
+
}
|
|
9778
|
+
return this._def.innerType._parse({
|
|
9779
|
+
data,
|
|
9780
|
+
path: ctx.path,
|
|
9781
|
+
parent: ctx
|
|
9390
9782
|
});
|
|
9391
9783
|
}
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
writeCache(latestVersion);
|
|
9395
|
-
}
|
|
9396
|
-
return latestVersion;
|
|
9397
|
-
}
|
|
9398
|
-
async function checkForUpdates() {
|
|
9399
|
-
const notice = await getUpdateNotice();
|
|
9400
|
-
if (notice?.behind) {
|
|
9401
|
-
showUpdateWarning(notice.current, notice.latest);
|
|
9784
|
+
removeDefault() {
|
|
9785
|
+
return this._def.innerType;
|
|
9402
9786
|
}
|
|
9403
|
-
}
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
}
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9787
|
+
};
|
|
9788
|
+
ZodDefault.create = (type, params) => {
|
|
9789
|
+
return new ZodDefault({
|
|
9790
|
+
innerType: type,
|
|
9791
|
+
typeName: ZodFirstPartyTypeKind.ZodDefault,
|
|
9792
|
+
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
|
|
9793
|
+
...processCreateParams(params)
|
|
9794
|
+
});
|
|
9795
|
+
};
|
|
9796
|
+
var ZodCatch = class extends ZodType {
|
|
9797
|
+
_parse(input) {
|
|
9798
|
+
const { ctx } = this._processInputParams(input);
|
|
9799
|
+
const newCtx = {
|
|
9800
|
+
...ctx,
|
|
9801
|
+
common: {
|
|
9802
|
+
...ctx.common,
|
|
9803
|
+
issues: []
|
|
9804
|
+
}
|
|
9805
|
+
};
|
|
9806
|
+
const result = this._def.innerType._parse({
|
|
9807
|
+
data: newCtx.data,
|
|
9808
|
+
path: newCtx.path,
|
|
9809
|
+
parent: {
|
|
9810
|
+
...newCtx
|
|
9811
|
+
}
|
|
9812
|
+
});
|
|
9813
|
+
if (isAsync(result)) {
|
|
9814
|
+
return result.then((result2) => {
|
|
9815
|
+
return {
|
|
9816
|
+
status: "valid",
|
|
9817
|
+
value: result2.status === "valid" ? result2.value : this._def.catchValue({
|
|
9818
|
+
get error() {
|
|
9819
|
+
return new ZodError(newCtx.common.issues);
|
|
9820
|
+
},
|
|
9821
|
+
input: newCtx.data
|
|
9822
|
+
})
|
|
9823
|
+
};
|
|
9824
|
+
});
|
|
9825
|
+
} else {
|
|
9422
9826
|
return {
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9827
|
+
status: "valid",
|
|
9828
|
+
value: result.status === "valid" ? result.value : this._def.catchValue({
|
|
9829
|
+
get error() {
|
|
9830
|
+
return new ZodError(newCtx.common.issues);
|
|
9831
|
+
},
|
|
9832
|
+
input: newCtx.data
|
|
9833
|
+
})
|
|
9427
9834
|
};
|
|
9428
9835
|
}
|
|
9429
|
-
} catch {
|
|
9430
9836
|
}
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9837
|
+
removeCatch() {
|
|
9838
|
+
return this._def.innerType;
|
|
9839
|
+
}
|
|
9840
|
+
};
|
|
9841
|
+
ZodCatch.create = (type, params) => {
|
|
9842
|
+
return new ZodCatch({
|
|
9843
|
+
innerType: type,
|
|
9844
|
+
typeName: ZodFirstPartyTypeKind.ZodCatch,
|
|
9845
|
+
catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
|
|
9846
|
+
...processCreateParams(params)
|
|
9847
|
+
});
|
|
9848
|
+
};
|
|
9849
|
+
var ZodNaN = class extends ZodType {
|
|
9850
|
+
_parse(input) {
|
|
9851
|
+
const parsedType = this._getType(input);
|
|
9852
|
+
if (parsedType !== ZodParsedType.nan) {
|
|
9853
|
+
const ctx = this._getOrReturnCtx(input);
|
|
9854
|
+
addIssueToContext(ctx, {
|
|
9855
|
+
code: ZodIssueCode.invalid_type,
|
|
9856
|
+
expected: ZodParsedType.nan,
|
|
9857
|
+
received: ctx.parsedType
|
|
9858
|
+
});
|
|
9859
|
+
return INVALID;
|
|
9439
9860
|
}
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9861
|
+
return { status: "valid", value: input.data };
|
|
9862
|
+
}
|
|
9863
|
+
};
|
|
9864
|
+
ZodNaN.create = (params) => {
|
|
9865
|
+
return new ZodNaN({
|
|
9866
|
+
typeName: ZodFirstPartyTypeKind.ZodNaN,
|
|
9867
|
+
...processCreateParams(params)
|
|
9868
|
+
});
|
|
9869
|
+
};
|
|
9870
|
+
var BRAND = /* @__PURE__ */ Symbol("zod_brand");
|
|
9871
|
+
var ZodBranded = class extends ZodType {
|
|
9872
|
+
_parse(input) {
|
|
9873
|
+
const { ctx } = this._processInputParams(input);
|
|
9874
|
+
const data = ctx.data;
|
|
9875
|
+
return this._def.type._parse({
|
|
9876
|
+
data,
|
|
9877
|
+
path: ctx.path,
|
|
9878
|
+
parent: ctx
|
|
9879
|
+
});
|
|
9880
|
+
}
|
|
9881
|
+
unwrap() {
|
|
9882
|
+
return this._def.type;
|
|
9883
|
+
}
|
|
9884
|
+
};
|
|
9885
|
+
var ZodPipeline = class _ZodPipeline extends ZodType {
|
|
9886
|
+
_parse(input) {
|
|
9887
|
+
const { status, ctx } = this._processInputParams(input);
|
|
9888
|
+
if (ctx.common.async) {
|
|
9889
|
+
const handleAsync = async () => {
|
|
9890
|
+
const inResult = await this._def.in._parseAsync({
|
|
9891
|
+
data: ctx.data,
|
|
9892
|
+
path: ctx.path,
|
|
9893
|
+
parent: ctx
|
|
9894
|
+
});
|
|
9895
|
+
if (inResult.status === "aborted")
|
|
9896
|
+
return INVALID;
|
|
9897
|
+
if (inResult.status === "dirty") {
|
|
9898
|
+
status.dirty();
|
|
9899
|
+
return DIRTY(inResult.value);
|
|
9900
|
+
} else {
|
|
9901
|
+
return this._def.out._parseAsync({
|
|
9902
|
+
data: inResult.value,
|
|
9903
|
+
path: ctx.path,
|
|
9904
|
+
parent: ctx
|
|
9905
|
+
});
|
|
9906
|
+
}
|
|
9907
|
+
};
|
|
9908
|
+
return handleAsync();
|
|
9909
|
+
} else {
|
|
9910
|
+
const inResult = this._def.in._parseSync({
|
|
9911
|
+
data: ctx.data,
|
|
9912
|
+
path: ctx.path,
|
|
9913
|
+
parent: ctx
|
|
9914
|
+
});
|
|
9915
|
+
if (inResult.status === "aborted")
|
|
9916
|
+
return INVALID;
|
|
9917
|
+
if (inResult.status === "dirty") {
|
|
9918
|
+
status.dirty();
|
|
9919
|
+
return {
|
|
9920
|
+
status: "dirty",
|
|
9921
|
+
value: inResult.value
|
|
9922
|
+
};
|
|
9923
|
+
} else {
|
|
9924
|
+
return this._def.out._parseSync({
|
|
9925
|
+
data: inResult.value,
|
|
9926
|
+
path: ctx.path,
|
|
9927
|
+
parent: ctx
|
|
9928
|
+
});
|
|
9929
|
+
}
|
|
9446
9930
|
}
|
|
9447
|
-
return 0;
|
|
9448
|
-
} catch {
|
|
9449
|
-
return 0;
|
|
9450
9931
|
}
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
} else if (versionsBehind >= 1) {
|
|
9458
|
-
return `[VERSION_NOTICE] MCP server update available (${notice.current} \u2192 ${notice.latest}). Run: ${notice.upgrade_command}`;
|
|
9932
|
+
static create(a, b) {
|
|
9933
|
+
return new _ZodPipeline({
|
|
9934
|
+
in: a,
|
|
9935
|
+
out: b,
|
|
9936
|
+
typeName: ZodFirstPartyTypeKind.ZodPipeline
|
|
9937
|
+
});
|
|
9459
9938
|
}
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
return
|
|
9939
|
+
};
|
|
9940
|
+
var ZodReadonly = class extends ZodType {
|
|
9941
|
+
_parse(input) {
|
|
9942
|
+
const result = this._def.innerType._parse(input);
|
|
9943
|
+
const freeze = (data) => {
|
|
9944
|
+
if (isValid(data)) {
|
|
9945
|
+
data.value = Object.freeze(data.value);
|
|
9946
|
+
}
|
|
9947
|
+
return data;
|
|
9948
|
+
};
|
|
9949
|
+
return isAsync(result) ? result.then((data) => freeze(data)) : freeze(result);
|
|
9950
|
+
}
|
|
9951
|
+
unwrap() {
|
|
9952
|
+
return this._def.innerType;
|
|
9471
9953
|
}
|
|
9472
|
-
|
|
9954
|
+
};
|
|
9955
|
+
ZodReadonly.create = (type, params) => {
|
|
9956
|
+
return new ZodReadonly({
|
|
9957
|
+
innerType: type,
|
|
9958
|
+
typeName: ZodFirstPartyTypeKind.ZodReadonly,
|
|
9959
|
+
...processCreateParams(params)
|
|
9960
|
+
});
|
|
9961
|
+
};
|
|
9962
|
+
function cleanParams(params, data) {
|
|
9963
|
+
const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
|
|
9964
|
+
const p2 = typeof p === "string" ? { message: p } : p;
|
|
9965
|
+
return p2;
|
|
9966
|
+
}
|
|
9967
|
+
function custom(check, _params = {}, fatal) {
|
|
9968
|
+
if (check)
|
|
9969
|
+
return ZodAny.create().superRefine((data, ctx) => {
|
|
9970
|
+
const r = check(data);
|
|
9971
|
+
if (r instanceof Promise) {
|
|
9972
|
+
return r.then((r2) => {
|
|
9973
|
+
if (!r2) {
|
|
9974
|
+
const params = cleanParams(_params, data);
|
|
9975
|
+
const _fatal = params.fatal ?? fatal ?? true;
|
|
9976
|
+
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
9977
|
+
}
|
|
9978
|
+
});
|
|
9979
|
+
}
|
|
9980
|
+
if (!r) {
|
|
9981
|
+
const params = cleanParams(_params, data);
|
|
9982
|
+
const _fatal = params.fatal ?? fatal ?? true;
|
|
9983
|
+
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
|
|
9984
|
+
}
|
|
9985
|
+
return;
|
|
9986
|
+
});
|
|
9987
|
+
return ZodAny.create();
|
|
9473
9988
|
}
|
|
9989
|
+
var late = {
|
|
9990
|
+
object: ZodObject.lazycreate
|
|
9991
|
+
};
|
|
9992
|
+
var ZodFirstPartyTypeKind;
|
|
9993
|
+
(function(ZodFirstPartyTypeKind2) {
|
|
9994
|
+
ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
|
|
9995
|
+
ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
|
|
9996
|
+
ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
|
|
9997
|
+
ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
|
|
9998
|
+
ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
|
|
9999
|
+
ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
|
|
10000
|
+
ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
|
|
10001
|
+
ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
|
|
10002
|
+
ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
|
|
10003
|
+
ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
|
|
10004
|
+
ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
|
|
10005
|
+
ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
|
|
10006
|
+
ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
|
|
10007
|
+
ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
|
|
10008
|
+
ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
|
|
10009
|
+
ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
|
|
10010
|
+
ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
|
|
10011
|
+
ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
|
|
10012
|
+
ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
|
|
10013
|
+
ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
|
|
10014
|
+
ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
|
|
10015
|
+
ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
|
|
10016
|
+
ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
|
|
10017
|
+
ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
|
|
10018
|
+
ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
|
|
10019
|
+
ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
|
|
10020
|
+
ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
|
|
10021
|
+
ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
|
|
10022
|
+
ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
|
|
10023
|
+
ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
|
|
10024
|
+
ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
|
|
10025
|
+
ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
|
|
10026
|
+
ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
|
|
10027
|
+
ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
|
|
10028
|
+
ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
|
|
10029
|
+
ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
|
|
10030
|
+
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
|
|
10031
|
+
var instanceOfType = (cls, params = {
|
|
10032
|
+
message: `Input not instance of ${cls.name}`
|
|
10033
|
+
}) => custom((data) => data instanceof cls, params);
|
|
10034
|
+
var stringType = ZodString.create;
|
|
10035
|
+
var numberType = ZodNumber.create;
|
|
10036
|
+
var nanType = ZodNaN.create;
|
|
10037
|
+
var bigIntType = ZodBigInt.create;
|
|
10038
|
+
var booleanType = ZodBoolean.create;
|
|
10039
|
+
var dateType = ZodDate.create;
|
|
10040
|
+
var symbolType = ZodSymbol.create;
|
|
10041
|
+
var undefinedType = ZodUndefined.create;
|
|
10042
|
+
var nullType = ZodNull.create;
|
|
10043
|
+
var anyType = ZodAny.create;
|
|
10044
|
+
var unknownType = ZodUnknown.create;
|
|
10045
|
+
var neverType = ZodNever.create;
|
|
10046
|
+
var voidType = ZodVoid.create;
|
|
10047
|
+
var arrayType = ZodArray.create;
|
|
10048
|
+
var objectType = ZodObject.create;
|
|
10049
|
+
var strictObjectType = ZodObject.strictCreate;
|
|
10050
|
+
var unionType = ZodUnion.create;
|
|
10051
|
+
var discriminatedUnionType = ZodDiscriminatedUnion.create;
|
|
10052
|
+
var intersectionType = ZodIntersection.create;
|
|
10053
|
+
var tupleType = ZodTuple.create;
|
|
10054
|
+
var recordType = ZodRecord.create;
|
|
10055
|
+
var mapType = ZodMap.create;
|
|
10056
|
+
var setType = ZodSet.create;
|
|
10057
|
+
var functionType = ZodFunction.create;
|
|
10058
|
+
var lazyType = ZodLazy.create;
|
|
10059
|
+
var literalType = ZodLiteral.create;
|
|
10060
|
+
var enumType = ZodEnum.create;
|
|
10061
|
+
var nativeEnumType = ZodNativeEnum.create;
|
|
10062
|
+
var promiseType = ZodPromise.create;
|
|
10063
|
+
var effectsType = ZodEffects.create;
|
|
10064
|
+
var optionalType = ZodOptional.create;
|
|
10065
|
+
var nullableType = ZodNullable.create;
|
|
10066
|
+
var preprocessType = ZodEffects.createWithPreprocess;
|
|
10067
|
+
var pipelineType = ZodPipeline.create;
|
|
10068
|
+
var ostring = () => stringType().optional();
|
|
10069
|
+
var onumber = () => numberType().optional();
|
|
10070
|
+
var oboolean = () => booleanType().optional();
|
|
10071
|
+
var coerce = {
|
|
10072
|
+
string: ((arg) => ZodString.create({ ...arg, coerce: true })),
|
|
10073
|
+
number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
|
|
10074
|
+
boolean: ((arg) => ZodBoolean.create({
|
|
10075
|
+
...arg,
|
|
10076
|
+
coerce: true
|
|
10077
|
+
})),
|
|
10078
|
+
bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
|
|
10079
|
+
date: ((arg) => ZodDate.create({ ...arg, coerce: true }))
|
|
10080
|
+
};
|
|
10081
|
+
var NEVER = INVALID;
|
|
9474
10082
|
|
|
9475
10083
|
// src/config.ts
|
|
10084
|
+
init_version();
|
|
9476
10085
|
var DEFAULT_API_URL = "https://api.contextstream.io";
|
|
9477
10086
|
function parseBooleanEnv(value) {
|
|
9478
10087
|
if (value === void 0) return void 0;
|
|
@@ -9764,6 +10373,10 @@ function rewriteNotFoundMessage(input) {
|
|
|
9764
10373
|
// src/files.ts
|
|
9765
10374
|
import * as fs2 from "fs";
|
|
9766
10375
|
import * as path2 from "path";
|
|
10376
|
+
import { exec } from "child_process";
|
|
10377
|
+
import { promisify } from "util";
|
|
10378
|
+
import * as os from "os";
|
|
10379
|
+
import * as crypto from "crypto";
|
|
9767
10380
|
|
|
9768
10381
|
// src/ignore.ts
|
|
9769
10382
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
@@ -9837,6 +10450,7 @@ async function loadIgnorePatterns(projectRoot) {
|
|
|
9837
10450
|
}
|
|
9838
10451
|
|
|
9839
10452
|
// src/files.ts
|
|
10453
|
+
var execAsync = promisify(exec);
|
|
9840
10454
|
var CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
9841
10455
|
// Rust
|
|
9842
10456
|
"rs",
|
|
@@ -9944,12 +10558,116 @@ var MAX_FILE_SIZE = 1024 * 1024;
|
|
|
9944
10558
|
var MAX_BATCH_BYTES = 10 * 1024 * 1024;
|
|
9945
10559
|
var LARGE_FILE_THRESHOLD = 2 * 1024 * 1024;
|
|
9946
10560
|
var MAX_FILES_PER_BATCH = 200;
|
|
10561
|
+
var gitContextCache = /* @__PURE__ */ new Map();
|
|
10562
|
+
function getMachineId() {
|
|
10563
|
+
const hostname2 = os.hostname();
|
|
10564
|
+
const hash = crypto.createHash("sha256").update(hostname2).digest("hex");
|
|
10565
|
+
return hash.substring(0, 12);
|
|
10566
|
+
}
|
|
10567
|
+
async function isGitRepo(rootPath) {
|
|
10568
|
+
try {
|
|
10569
|
+
await execAsync("git rev-parse --is-inside-work-tree", {
|
|
10570
|
+
cwd: rootPath,
|
|
10571
|
+
timeout: 5e3
|
|
10572
|
+
});
|
|
10573
|
+
return true;
|
|
10574
|
+
} catch {
|
|
10575
|
+
return false;
|
|
10576
|
+
}
|
|
10577
|
+
}
|
|
10578
|
+
async function getGitBranch(rootPath) {
|
|
10579
|
+
try {
|
|
10580
|
+
const { stdout: stdout2 } = await execAsync("git branch --show-current", {
|
|
10581
|
+
cwd: rootPath,
|
|
10582
|
+
timeout: 5e3
|
|
10583
|
+
});
|
|
10584
|
+
const branch = stdout2.trim();
|
|
10585
|
+
return branch || void 0;
|
|
10586
|
+
} catch {
|
|
10587
|
+
return void 0;
|
|
10588
|
+
}
|
|
10589
|
+
}
|
|
10590
|
+
async function getGitDefaultBranch(rootPath) {
|
|
10591
|
+
try {
|
|
10592
|
+
const { stdout: stdout2 } = await execAsync(
|
|
10593
|
+
"git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null",
|
|
10594
|
+
{ cwd: rootPath, timeout: 5e3 }
|
|
10595
|
+
);
|
|
10596
|
+
const match = stdout2.trim().match(/refs\/remotes\/origin\/(.+)/);
|
|
10597
|
+
if (match) return match[1];
|
|
10598
|
+
} catch {
|
|
10599
|
+
}
|
|
10600
|
+
try {
|
|
10601
|
+
const { stdout: stdout2 } = await execAsync(
|
|
10602
|
+
"git config --get init.defaultBranch 2>/dev/null",
|
|
10603
|
+
{ cwd: rootPath, timeout: 5e3 }
|
|
10604
|
+
);
|
|
10605
|
+
const branch = stdout2.trim();
|
|
10606
|
+
if (branch) return branch;
|
|
10607
|
+
} catch {
|
|
10608
|
+
}
|
|
10609
|
+
try {
|
|
10610
|
+
const { stdout: stdout2 } = await execAsync("git branch --list main master", {
|
|
10611
|
+
cwd: rootPath,
|
|
10612
|
+
timeout: 5e3
|
|
10613
|
+
});
|
|
10614
|
+
const branches = stdout2.trim().split("\n").map((b) => b.replace(/^\*?\s*/, "").trim()).filter(Boolean);
|
|
10615
|
+
if (branches.includes("main")) return "main";
|
|
10616
|
+
if (branches.includes("master")) return "master";
|
|
10617
|
+
} catch {
|
|
10618
|
+
}
|
|
10619
|
+
return void 0;
|
|
10620
|
+
}
|
|
10621
|
+
async function getFileGitInfo(rootPath, relativePath) {
|
|
10622
|
+
try {
|
|
10623
|
+
const { stdout: stdout2 } = await execAsync(
|
|
10624
|
+
`git log -1 --format="%H %ct" -- "${relativePath}"`,
|
|
10625
|
+
{ cwd: rootPath, timeout: 5e3 }
|
|
10626
|
+
);
|
|
10627
|
+
const parts = stdout2.trim().split(" ");
|
|
10628
|
+
if (parts.length >= 2) {
|
|
10629
|
+
const sha = parts[0];
|
|
10630
|
+
const unixTimestamp = parseInt(parts[1], 10);
|
|
10631
|
+
if (sha && !isNaN(unixTimestamp)) {
|
|
10632
|
+
const timestamp = new Date(unixTimestamp * 1e3).toISOString();
|
|
10633
|
+
return { sha, timestamp };
|
|
10634
|
+
}
|
|
10635
|
+
}
|
|
10636
|
+
} catch {
|
|
10637
|
+
}
|
|
10638
|
+
return void 0;
|
|
10639
|
+
}
|
|
10640
|
+
async function getGitContext(rootPath) {
|
|
10641
|
+
const cached = gitContextCache.get(rootPath);
|
|
10642
|
+
if (cached) return cached;
|
|
10643
|
+
const machineId = getMachineId();
|
|
10644
|
+
const isRepo = await isGitRepo(rootPath);
|
|
10645
|
+
if (!isRepo) {
|
|
10646
|
+
const context2 = { isGitRepo: false, machineId };
|
|
10647
|
+
gitContextCache.set(rootPath, context2);
|
|
10648
|
+
return context2;
|
|
10649
|
+
}
|
|
10650
|
+
const [branch, defaultBranch] = await Promise.all([
|
|
10651
|
+
getGitBranch(rootPath),
|
|
10652
|
+
getGitDefaultBranch(rootPath)
|
|
10653
|
+
]);
|
|
10654
|
+
const context = {
|
|
10655
|
+
isGitRepo: true,
|
|
10656
|
+
branch,
|
|
10657
|
+
defaultBranch,
|
|
10658
|
+
isDefaultBranch: branch !== void 0 && branch === defaultBranch,
|
|
10659
|
+
machineId
|
|
10660
|
+
};
|
|
10661
|
+
gitContextCache.set(rootPath, context);
|
|
10662
|
+
return context;
|
|
10663
|
+
}
|
|
9947
10664
|
async function* readAllFilesInBatches(rootPath, options = {}) {
|
|
9948
10665
|
const maxBatchBytes = options.maxBatchBytes ?? MAX_BATCH_BYTES;
|
|
9949
10666
|
const largeFileThreshold = options.largeFileThreshold ?? LARGE_FILE_THRESHOLD;
|
|
9950
10667
|
const maxFilesPerBatch = options.maxFilesPerBatch ?? options.batchSize ?? MAX_FILES_PER_BATCH;
|
|
9951
10668
|
const maxFileSize = options.maxFileSize ?? MAX_FILE_SIZE;
|
|
9952
10669
|
const ig = options.ignoreInstance ?? await loadIgnorePatterns(rootPath);
|
|
10670
|
+
const gitCtx = await getGitContext(rootPath);
|
|
9953
10671
|
let batch = [];
|
|
9954
10672
|
let currentBatchBytes = 0;
|
|
9955
10673
|
async function* walkDir(dir, relativePath = "") {
|
|
@@ -9975,7 +10693,25 @@ async function* readAllFilesInBatches(rootPath, options = {}) {
|
|
|
9975
10693
|
const stat2 = await fs2.promises.stat(fullPath);
|
|
9976
10694
|
if (stat2.size > maxFileSize) continue;
|
|
9977
10695
|
const content = await fs2.promises.readFile(fullPath, "utf-8");
|
|
9978
|
-
|
|
10696
|
+
const file = {
|
|
10697
|
+
path: relPath,
|
|
10698
|
+
content,
|
|
10699
|
+
sizeBytes: stat2.size,
|
|
10700
|
+
// Always include machine_id and source_modified_at
|
|
10701
|
+
machine_id: gitCtx.machineId,
|
|
10702
|
+
source_modified_at: stat2.mtime.toISOString()
|
|
10703
|
+
};
|
|
10704
|
+
if (gitCtx.isGitRepo) {
|
|
10705
|
+
file.git_branch = gitCtx.branch;
|
|
10706
|
+
file.git_default_branch = gitCtx.defaultBranch;
|
|
10707
|
+
file.is_default_branch = gitCtx.isDefaultBranch;
|
|
10708
|
+
const gitInfo = await getFileGitInfo(rootPath, relPath);
|
|
10709
|
+
if (gitInfo) {
|
|
10710
|
+
file.git_commit_sha = gitInfo.sha;
|
|
10711
|
+
file.git_commit_timestamp = gitInfo.timestamp;
|
|
10712
|
+
}
|
|
10713
|
+
}
|
|
10714
|
+
yield file;
|
|
9979
10715
|
} catch {
|
|
9980
10716
|
}
|
|
9981
10717
|
}
|
|
@@ -9984,11 +10720,12 @@ async function* readAllFilesInBatches(rootPath, options = {}) {
|
|
|
9984
10720
|
for await (const file of walkDir(rootPath)) {
|
|
9985
10721
|
if (file.sizeBytes > largeFileThreshold) {
|
|
9986
10722
|
if (batch.length > 0) {
|
|
9987
|
-
yield batch.map(({ sizeBytes, ...rest }) => rest);
|
|
10723
|
+
yield batch.map(({ sizeBytes: sizeBytes2, ...rest }) => rest);
|
|
9988
10724
|
batch = [];
|
|
9989
10725
|
currentBatchBytes = 0;
|
|
9990
10726
|
}
|
|
9991
|
-
|
|
10727
|
+
const { sizeBytes, ...fileData } = file;
|
|
10728
|
+
yield [fileData];
|
|
9992
10729
|
continue;
|
|
9993
10730
|
}
|
|
9994
10731
|
const wouldExceedBytes = currentBatchBytes + file.sizeBytes > maxBatchBytes;
|
|
@@ -10014,6 +10751,7 @@ async function* readChangedFilesInBatches(rootPath, sinceTimestamp, options = {}
|
|
|
10014
10751
|
const maxFileSize = options.maxFileSize ?? MAX_FILE_SIZE;
|
|
10015
10752
|
const sinceMs = sinceTimestamp.getTime();
|
|
10016
10753
|
const ig = options.ignoreInstance ?? await loadIgnorePatterns(rootPath);
|
|
10754
|
+
const gitCtx = await getGitContext(rootPath);
|
|
10017
10755
|
let batch = [];
|
|
10018
10756
|
let currentBatchBytes = 0;
|
|
10019
10757
|
let filesScanned = 0;
|
|
@@ -10044,7 +10782,25 @@ async function* readChangedFilesInBatches(rootPath, sinceTimestamp, options = {}
|
|
|
10044
10782
|
if (stat2.size > maxFileSize) continue;
|
|
10045
10783
|
const content = await fs2.promises.readFile(fullPath, "utf-8");
|
|
10046
10784
|
filesChanged++;
|
|
10047
|
-
|
|
10785
|
+
const file = {
|
|
10786
|
+
path: relPath,
|
|
10787
|
+
content,
|
|
10788
|
+
sizeBytes: stat2.size,
|
|
10789
|
+
// Always include machine_id and source_modified_at
|
|
10790
|
+
machine_id: gitCtx.machineId,
|
|
10791
|
+
source_modified_at: stat2.mtime.toISOString()
|
|
10792
|
+
};
|
|
10793
|
+
if (gitCtx.isGitRepo) {
|
|
10794
|
+
file.git_branch = gitCtx.branch;
|
|
10795
|
+
file.git_default_branch = gitCtx.defaultBranch;
|
|
10796
|
+
file.is_default_branch = gitCtx.isDefaultBranch;
|
|
10797
|
+
const gitInfo = await getFileGitInfo(rootPath, relPath);
|
|
10798
|
+
if (gitInfo) {
|
|
10799
|
+
file.git_commit_sha = gitInfo.sha;
|
|
10800
|
+
file.git_commit_timestamp = gitInfo.timestamp;
|
|
10801
|
+
}
|
|
10802
|
+
}
|
|
10803
|
+
yield file;
|
|
10048
10804
|
} catch {
|
|
10049
10805
|
}
|
|
10050
10806
|
}
|
|
@@ -10053,11 +10809,12 @@ async function* readChangedFilesInBatches(rootPath, sinceTimestamp, options = {}
|
|
|
10053
10809
|
for await (const file of walkDir(rootPath)) {
|
|
10054
10810
|
if (file.sizeBytes > largeFileThreshold) {
|
|
10055
10811
|
if (batch.length > 0) {
|
|
10056
|
-
yield batch.map(({ sizeBytes, ...rest }) => rest);
|
|
10812
|
+
yield batch.map(({ sizeBytes: sizeBytes2, ...rest }) => rest);
|
|
10057
10813
|
batch = [];
|
|
10058
10814
|
currentBatchBytes = 0;
|
|
10059
10815
|
}
|
|
10060
|
-
|
|
10816
|
+
const { sizeBytes, ...fileData } = file;
|
|
10817
|
+
yield [fileData];
|
|
10061
10818
|
continue;
|
|
10062
10819
|
}
|
|
10063
10820
|
const wouldExceedBytes = currentBatchBytes + file.sizeBytes > maxBatchBytes;
|
|
@@ -10331,6 +11088,7 @@ var CacheKeys = {
|
|
|
10331
11088
|
var globalCache = new MemoryCache();
|
|
10332
11089
|
|
|
10333
11090
|
// src/client.ts
|
|
11091
|
+
init_version();
|
|
10334
11092
|
var uuidSchema = external_exports.string().uuid();
|
|
10335
11093
|
function unwrapApiResponse(result) {
|
|
10336
11094
|
if (!result || typeof result !== "object") return result;
|
|
@@ -11153,6 +11911,26 @@ var ContextStreamClient = class {
|
|
|
11153
11911
|
uuidSchema.parse(projectId);
|
|
11154
11912
|
return request(this.config, `/projects/${projectId}/index/status`, { method: "GET" });
|
|
11155
11913
|
}
|
|
11914
|
+
/**
|
|
11915
|
+
* Get index history for audit trail
|
|
11916
|
+
* Shows which files were indexed, when, by which machine, and from which branch
|
|
11917
|
+
*/
|
|
11918
|
+
projectIndexHistory(projectId, params) {
|
|
11919
|
+
uuidSchema.parse(projectId);
|
|
11920
|
+
const queryParams = new URLSearchParams();
|
|
11921
|
+
if (params?.machine_id) queryParams.set("machine_id", params.machine_id);
|
|
11922
|
+
if (params?.branch) queryParams.set("branch", params.branch);
|
|
11923
|
+
if (params?.since) queryParams.set("since", params.since);
|
|
11924
|
+
if (params?.until) queryParams.set("until", params.until);
|
|
11925
|
+
if (params?.path_pattern) queryParams.set("path_pattern", params.path_pattern);
|
|
11926
|
+
if (params?.sort_by) queryParams.set("sort_by", params.sort_by);
|
|
11927
|
+
if (params?.sort_order) queryParams.set("sort_order", params.sort_order);
|
|
11928
|
+
if (params?.page) queryParams.set("page", params.page.toString());
|
|
11929
|
+
if (params?.limit) queryParams.set("limit", params.limit.toString());
|
|
11930
|
+
const queryString = queryParams.toString();
|
|
11931
|
+
const url = `/projects/${projectId}/index/history${queryString ? `?${queryString}` : ""}`;
|
|
11932
|
+
return request(this.config, url, { method: "GET" });
|
|
11933
|
+
}
|
|
11156
11934
|
/**
|
|
11157
11935
|
* Check if project ingestion is recommended and return a recommendation.
|
|
11158
11936
|
* This is used by session_init to inform the AI about the project's index status.
|
|
@@ -11227,10 +12005,11 @@ var ContextStreamClient = class {
|
|
|
11227
12005
|
* Ingest files for indexing
|
|
11228
12006
|
* This uploads files to the API for indexing
|
|
11229
12007
|
* @param projectId - Project UUID
|
|
11230
|
-
* @param files - Array of files to ingest
|
|
12008
|
+
* @param files - Array of files to ingest (with optional version metadata)
|
|
11231
12009
|
* @param options - Optional ingest options
|
|
11232
12010
|
* @param options.write_to_disk - When true, write files to disk under QA_FILE_WRITE_ROOT before indexing
|
|
11233
12011
|
* @param options.overwrite - Allow overwriting existing files when write_to_disk is enabled
|
|
12012
|
+
* @param options.force - When true, bypass version checking and force re-index all files
|
|
11234
12013
|
*/
|
|
11235
12014
|
ingestFiles(projectId, files, options) {
|
|
11236
12015
|
uuidSchema.parse(projectId);
|
|
@@ -11238,7 +12017,8 @@ var ContextStreamClient = class {
|
|
|
11238
12017
|
body: {
|
|
11239
12018
|
files,
|
|
11240
12019
|
...options?.write_to_disk !== void 0 && { write_to_disk: options.write_to_disk },
|
|
11241
|
-
...options?.overwrite !== void 0 && { overwrite: options.overwrite }
|
|
12020
|
+
...options?.overwrite !== void 0 && { overwrite: options.overwrite },
|
|
12021
|
+
...options?.force !== void 0 && { force: options.force }
|
|
11242
12022
|
}
|
|
11243
12023
|
});
|
|
11244
12024
|
}
|
|
@@ -11336,6 +12116,23 @@ var ContextStreamClient = class {
|
|
|
11336
12116
|
uuidSchema.parse(workspaceId);
|
|
11337
12117
|
return request(this.config, `/workspaces/${workspaceId}/content`, { method: "GET" });
|
|
11338
12118
|
}
|
|
12119
|
+
/**
|
|
12120
|
+
* Get workspace index settings for multi-machine sync configuration
|
|
12121
|
+
*/
|
|
12122
|
+
getWorkspaceIndexSettings(workspaceId) {
|
|
12123
|
+
uuidSchema.parse(workspaceId);
|
|
12124
|
+
return request(this.config, `/workspaces/${workspaceId}/index-settings`, { method: "GET" });
|
|
12125
|
+
}
|
|
12126
|
+
/**
|
|
12127
|
+
* Update workspace index settings (admin only)
|
|
12128
|
+
*/
|
|
12129
|
+
updateWorkspaceIndexSettings(workspaceId, settings) {
|
|
12130
|
+
uuidSchema.parse(workspaceId);
|
|
12131
|
+
return request(this.config, `/workspaces/${workspaceId}/index-settings`, {
|
|
12132
|
+
method: "PUT",
|
|
12133
|
+
body: settings
|
|
12134
|
+
});
|
|
12135
|
+
}
|
|
11339
12136
|
// Memory extended operations
|
|
11340
12137
|
getMemoryEvent(eventId) {
|
|
11341
12138
|
uuidSchema.parse(eventId);
|
|
@@ -12647,7 +13444,8 @@ var ContextStreamClient = class {
|
|
|
12647
13444
|
// Transcript save parameters
|
|
12648
13445
|
...params.save_exchange !== void 0 && { save_exchange: params.save_exchange },
|
|
12649
13446
|
...params.session_id !== void 0 && { session_id: params.session_id },
|
|
12650
|
-
...params.client_name !== void 0 && { client_name: params.client_name }
|
|
13447
|
+
...params.client_name !== void 0 && { client_name: params.client_name },
|
|
13448
|
+
...params.assistant_message !== void 0 && { assistant_message: params.assistant_message }
|
|
12651
13449
|
}
|
|
12652
13450
|
});
|
|
12653
13451
|
const data = unwrapApiResponse(apiResult);
|
|
@@ -12664,10 +13462,17 @@ var ContextStreamClient = class {
|
|
|
12664
13462
|
if (versionWarning2) {
|
|
12665
13463
|
warnings2.push(versionWarning2);
|
|
12666
13464
|
}
|
|
13465
|
+
const CS_HEADER2 = "\u2B21 ContextStream \u2014 Smart Context & Memory";
|
|
12667
13466
|
let context2 = String(data?.context ?? "");
|
|
12668
13467
|
const versionInstructions = getVersionInstructions(versionNotice2);
|
|
12669
13468
|
if (versionInstructions) {
|
|
12670
|
-
context2 = `${
|
|
13469
|
+
context2 = `${CS_HEADER2}
|
|
13470
|
+
|
|
13471
|
+
${versionInstructions}
|
|
13472
|
+
|
|
13473
|
+
${context2}`;
|
|
13474
|
+
} else {
|
|
13475
|
+
context2 = `${CS_HEADER2}
|
|
12671
13476
|
|
|
12672
13477
|
${context2}`;
|
|
12673
13478
|
}
|
|
@@ -12825,11 +13630,13 @@ ${context2}`;
|
|
|
12825
13630
|
let charsUsed = 0;
|
|
12826
13631
|
const maxChars = maxTokens * 4;
|
|
12827
13632
|
let candidateContext;
|
|
13633
|
+
const CS_HEADER = "\u2B21 ContextStream \u2014 Smart Context & Memory";
|
|
13634
|
+
const CS_HEADER_MINIFIED = "CS:active";
|
|
12828
13635
|
const CS_FIRST_RULE = "\u26A0\uFE0F STOP: Before Glob/Grep/Read \u2192 search(mode=hybrid) FIRST. Local tools ONLY if 0 results.";
|
|
12829
13636
|
const CS_FIRST_RULE_MINIFIED = "R:CS-first|Idx:project.index_status->ingest|NoLocalScanUnlessCSempty";
|
|
12830
13637
|
if (format === "minified") {
|
|
12831
|
-
const parts = [CS_FIRST_RULE_MINIFIED];
|
|
12832
|
-
charsUsed = CS_FIRST_RULE_MINIFIED.length +
|
|
13638
|
+
const parts = [CS_HEADER_MINIFIED, CS_FIRST_RULE_MINIFIED];
|
|
13639
|
+
charsUsed = CS_HEADER_MINIFIED.length + CS_FIRST_RULE_MINIFIED.length + 2;
|
|
12833
13640
|
for (const item of items) {
|
|
12834
13641
|
const entry = `${item.type}:${item.value}`;
|
|
12835
13642
|
if (charsUsed + entry.length + 1 > maxChars) break;
|
|
@@ -12837,12 +13644,12 @@ ${context2}`;
|
|
|
12837
13644
|
charsUsed += entry.length + 1;
|
|
12838
13645
|
}
|
|
12839
13646
|
context = parts.join("|");
|
|
12840
|
-
candidateContext = [CS_FIRST_RULE_MINIFIED, ...items.map((i) => `${i.type}:${i.value}`)].join(
|
|
13647
|
+
candidateContext = [CS_HEADER_MINIFIED, CS_FIRST_RULE_MINIFIED, ...items.map((i) => `${i.type}:${i.value}`)].join(
|
|
12841
13648
|
"|"
|
|
12842
13649
|
);
|
|
12843
13650
|
} else if (format === "structured") {
|
|
12844
|
-
const grouped = { R: [CS_FIRST_RULE] };
|
|
12845
|
-
charsUsed = CS_FIRST_RULE.length +
|
|
13651
|
+
const grouped = { _: [CS_HEADER], R: [CS_FIRST_RULE] };
|
|
13652
|
+
charsUsed = CS_HEADER.length + CS_FIRST_RULE.length + 15;
|
|
12846
13653
|
for (const item of items) {
|
|
12847
13654
|
if (charsUsed > maxChars) break;
|
|
12848
13655
|
if (!grouped[item.type]) grouped[item.type] = [];
|
|
@@ -12850,15 +13657,15 @@ ${context2}`;
|
|
|
12850
13657
|
charsUsed += item.value.length + 5;
|
|
12851
13658
|
}
|
|
12852
13659
|
context = JSON.stringify(grouped);
|
|
12853
|
-
const candidateGrouped = { R: [CS_FIRST_RULE] };
|
|
13660
|
+
const candidateGrouped = { _: [CS_HEADER], R: [CS_FIRST_RULE] };
|
|
12854
13661
|
for (const item of items) {
|
|
12855
13662
|
if (!candidateGrouped[item.type]) candidateGrouped[item.type] = [];
|
|
12856
13663
|
candidateGrouped[item.type].push(item.value);
|
|
12857
13664
|
}
|
|
12858
13665
|
candidateContext = JSON.stringify(candidateGrouped);
|
|
12859
13666
|
} else {
|
|
12860
|
-
const lines = [CS_FIRST_RULE, "", "[CTX]"];
|
|
12861
|
-
charsUsed = CS_FIRST_RULE.length +
|
|
13667
|
+
const lines = [CS_HEADER, "", CS_FIRST_RULE, "", "[CTX]"];
|
|
13668
|
+
charsUsed = CS_HEADER.length + CS_FIRST_RULE.length + 15;
|
|
12862
13669
|
for (const item of items) {
|
|
12863
13670
|
const line = `${item.type}:${item.value}`;
|
|
12864
13671
|
if (charsUsed + line.length + 1 > maxChars) break;
|
|
@@ -12867,7 +13674,7 @@ ${context2}`;
|
|
|
12867
13674
|
}
|
|
12868
13675
|
lines.push("[/CTX]");
|
|
12869
13676
|
context = lines.join("\n");
|
|
12870
|
-
const candidateLines = [CS_FIRST_RULE, "", "[CTX]"];
|
|
13677
|
+
const candidateLines = [CS_HEADER, "", CS_FIRST_RULE, "", "[CTX]"];
|
|
12871
13678
|
for (const item of items) {
|
|
12872
13679
|
candidateLines.push(`${item.type}:${item.value}`);
|
|
12873
13680
|
}
|
|
@@ -12876,7 +13683,9 @@ ${context2}`;
|
|
|
12876
13683
|
}
|
|
12877
13684
|
if (context.length === 0 && withDefaults.workspace_id) {
|
|
12878
13685
|
const wsHint = items.find((i) => i.type === "W")?.value || withDefaults.workspace_id;
|
|
12879
|
-
context = format === "minified" ? `${CS_FIRST_RULE_MINIFIED}|W:${wsHint}|[NO_MATCHES]` : `${
|
|
13686
|
+
context = format === "minified" ? `${CS_HEADER_MINIFIED}|${CS_FIRST_RULE_MINIFIED}|W:${wsHint}|[NO_MATCHES]` : `${CS_HEADER}
|
|
13687
|
+
|
|
13688
|
+
${CS_FIRST_RULE}
|
|
12880
13689
|
|
|
12881
13690
|
[CTX]
|
|
12882
13691
|
W:${wsHint}
|
|
@@ -14306,6 +15115,7 @@ import * as path6 from "node:path";
|
|
|
14306
15115
|
import { homedir as homedir3 } from "node:os";
|
|
14307
15116
|
|
|
14308
15117
|
// src/rules-templates.ts
|
|
15118
|
+
init_version();
|
|
14309
15119
|
var DEFAULT_CLAUDE_MCP_SERVER_NAME = "contextstream";
|
|
14310
15120
|
var RULES_VERSION = VERSION === "unknown" ? "0.0.0" : VERSION;
|
|
14311
15121
|
var CONTEXTSTREAM_TOOL_NAMES = [
|
|
@@ -14354,7 +15164,7 @@ var CONTEXTSTREAM_RULES_BOOTSTRAP = `
|
|
|
14354
15164
|
|
|
14355
15165
|
**Hooks:** \`<system-reminder>\` tags contain injected instructions \u2014 follow them exactly.
|
|
14356
15166
|
|
|
14357
|
-
**Notices:** [LESSONS_WARNING] \u2192
|
|
15167
|
+
**Notices:** [LESSONS_WARNING] \u2192 apply lessons | [PREFERENCE] \u2192 follow user preferences | [RULES_NOTICE] \u2192 run \`generate_rules()\` | [VERSION_NOTICE/CRITICAL] \u2192 tell user about update
|
|
14358
15168
|
|
|
14359
15169
|
v${RULES_VERSION}
|
|
14360
15170
|
`.trim();
|
|
@@ -14395,6 +15205,7 @@ var CONTEXTSTREAM_RULES_FULL = `
|
|
|
14395
15205
|
## Handle Notices from context()
|
|
14396
15206
|
|
|
14397
15207
|
- **[LESSONS_WARNING]** \u2192 Tell user about past mistakes BEFORE proceeding
|
|
15208
|
+
- **[PREFERENCE]** \u2192 Follow user preferences (high-priority user memories)
|
|
14398
15209
|
- **[RULES_NOTICE]** \u2192 Run \`generate_rules()\` to update
|
|
14399
15210
|
- **[VERSION_NOTICE]** \u2192 Tell user to update MCP
|
|
14400
15211
|
|
|
@@ -14621,11 +15432,14 @@ If context still feels missing, use \`session(action="recall", query="...")\` fo
|
|
|
14621
15432
|
|
|
14622
15433
|
**[RULES_NOTICE]** - Update rules via \`generate_rules()\` (or rerun setup).
|
|
14623
15434
|
|
|
14624
|
-
**[VERSION_NOTICE]** - You **MUST
|
|
14625
|
-
1. A new MCP server version is available
|
|
14626
|
-
2.
|
|
14627
|
-
|
|
14628
|
-
|
|
15435
|
+
**[VERSION_NOTICE]** or **[VERSION_CRITICAL]** - You **MUST** tell the user (be helpful, not annoying):
|
|
15436
|
+
1. A new MCP server version is available with improvements
|
|
15437
|
+
2. Provide update commands (user chooses preferred method):
|
|
15438
|
+
- macOS/Linux: \`curl -fsSL https://contextstream.io/scripts/setup.sh | bash\`
|
|
15439
|
+
- Windows: \`irm https://contextstream.io/scripts/setup.ps1 | iex\`
|
|
15440
|
+
- npm: \`npm install -g @contextstream/mcp-server@latest\`
|
|
15441
|
+
3. Restart AI tool after updating
|
|
15442
|
+
**Mention once** - don't nag. Users often miss stderr warnings so this helps.
|
|
14629
15443
|
|
|
14630
15444
|
**[LESSONS_WARNING]** - You **MUST** before proceeding:
|
|
14631
15445
|
1. Read all lessons listed
|
|
@@ -14637,9 +15451,17 @@ If context still feels missing, use \`session(action="recall", query="...")\` fo
|
|
|
14637
15451
|
|
|
14638
15452
|
### Preferences & Lessons (Use Early)
|
|
14639
15453
|
|
|
14640
|
-
|
|
15454
|
+
**Preferences ([PREFERENCE] in context response):**
|
|
15455
|
+
- High-priority user memories that should guide your behavior
|
|
15456
|
+
- Surfaced automatically via \`context()\` warnings field
|
|
15457
|
+
- To save: \`session(action="remember", content="...")\`
|
|
15458
|
+
- To retrieve explicitly: \`session(action="user_context")\`
|
|
15459
|
+
|
|
15460
|
+
**Lessons ([LESSONS_WARNING] in context response):**
|
|
15461
|
+
- Past mistakes to avoid - apply prevention steps
|
|
15462
|
+
- Surfaced automatically via \`context()\` warnings field
|
|
14641
15463
|
- Before risky changes: \`session(action="get_lessons", query="<topic>")\`
|
|
14642
|
-
- On
|
|
15464
|
+
- On mistakes: \`session(action="capture_lesson", title="...", trigger="...", impact="...", prevention="...")\`
|
|
14643
15465
|
|
|
14644
15466
|
---
|
|
14645
15467
|
|
|
@@ -14933,6 +15755,7 @@ Rules Version: ${RULES_VERSION}
|
|
|
14933
15755
|
## Handle Notices from context()
|
|
14934
15756
|
|
|
14935
15757
|
- **[LESSONS_WARNING]** \u2192 Tell user about past mistakes BEFORE proceeding
|
|
15758
|
+
- **[PREFERENCE]** \u2192 Follow user preferences (high-priority user memories)
|
|
14936
15759
|
- **[RULES_NOTICE]** \u2192 Run \`generate_rules()\`
|
|
14937
15760
|
- **[VERSION_NOTICE]** \u2192 Tell user to update MCP
|
|
14938
15761
|
|
|
@@ -14974,9 +15797,13 @@ To disable automatic restoration:
|
|
|
14974
15797
|
|
|
14975
15798
|
### Notices - MUST HANDLE IMMEDIATELY
|
|
14976
15799
|
|
|
14977
|
-
- **[VERSION_NOTICE]**: Tell
|
|
15800
|
+
- **[VERSION_NOTICE]** or **[VERSION_CRITICAL]**: Tell user about the update in a helpful, non-annoying way. Provide update commands:
|
|
15801
|
+
- macOS/Linux: \`curl -fsSL https://contextstream.io/scripts/setup.sh | bash\`
|
|
15802
|
+
- Windows: \`irm https://contextstream.io/scripts/setup.ps1 | iex\`
|
|
15803
|
+
- npm: \`npm install -g @contextstream/mcp-server@latest\`
|
|
14978
15804
|
- **[RULES_NOTICE]**: Run \`generate_rules(overwrite_existing=true)\` to update
|
|
14979
15805
|
- **[LESSONS_WARNING]**: Read lessons, tell user about them, explain how you'll avoid past mistakes
|
|
15806
|
+
- **[PREFERENCE]**: Follow user preferences - these are high-priority user memories that should guide your behavior
|
|
14980
15807
|
|
|
14981
15808
|
### Plans & Tasks
|
|
14982
15809
|
|
|
@@ -15015,12 +15842,42 @@ You MUST follow these rules manually - there is no automatic enforcement.
|
|
|
15015
15842
|
- Check response for \`indexing_status\`
|
|
15016
15843
|
- If \`"started"\` or \`"refreshing"\`: wait before searching
|
|
15017
15844
|
|
|
15018
|
-
2. **
|
|
15019
|
-
-
|
|
15845
|
+
2. **Generate a unique session_id** (e.g., \`"session-" + timestamp\` or a UUID)
|
|
15846
|
+
- Use this SAME session_id for ALL context() calls in this conversation
|
|
15847
|
+
- This groups all turns together in the transcript
|
|
15848
|
+
|
|
15849
|
+
3. **Call \`context(user_message="<first_message>", save_exchange=true, session_id="<your-session-id>")\`**
|
|
15850
|
+
- Gets task-specific rules, lessons, and preferences
|
|
15020
15851
|
- Check for [LESSONS_WARNING] - past mistakes to avoid
|
|
15852
|
+
- Check for [PREFERENCE] - user preferences to follow
|
|
15021
15853
|
- Check for [RULES_NOTICE] - update rules if needed
|
|
15854
|
+
- **save_exchange=true** saves each conversation turn for later retrieval
|
|
15855
|
+
|
|
15856
|
+
4. **NEVER skip init/context** - you will miss critical context
|
|
15857
|
+
|
|
15858
|
+
---
|
|
15859
|
+
|
|
15860
|
+
## \u{1F4BE} AUTOMATIC TRANSCRIPT SAVING (CRITICAL)
|
|
15861
|
+
|
|
15862
|
+
**This editor does NOT have hooks to auto-save transcripts.**
|
|
15863
|
+
You MUST save each conversation turn manually:
|
|
15864
|
+
|
|
15865
|
+
### On EVERY message (including the first):
|
|
15866
|
+
\`\`\`
|
|
15867
|
+
context(user_message="<user's message>", save_exchange=true, session_id="<session-id>")
|
|
15868
|
+
\`\`\`
|
|
15022
15869
|
|
|
15023
|
-
|
|
15870
|
+
### Why save_exchange matters:
|
|
15871
|
+
- Transcripts enable searching past conversations
|
|
15872
|
+
- Allows context restoration after compaction
|
|
15873
|
+
- Provides conversation history for debugging
|
|
15874
|
+
- Required for the Transcripts page in the dashboard
|
|
15875
|
+
|
|
15876
|
+
### Session ID Guidelines:
|
|
15877
|
+
- Generate ONCE at the start of the conversation
|
|
15878
|
+
- Use a unique identifier: \`"session-" + Date.now()\` or a UUID
|
|
15879
|
+
- Keep the SAME session_id for ALL context() calls in this session
|
|
15880
|
+
- Different sessions = different transcripts
|
|
15024
15881
|
|
|
15025
15882
|
---
|
|
15026
15883
|
|
|
@@ -15130,6 +15987,39 @@ memory(action="create_task", title="...", plan_id="...")
|
|
|
15130
15987
|
|
|
15131
15988
|
\u274C DO NOT use built-in plan mode or write plans to markdown files.
|
|
15132
15989
|
|
|
15990
|
+
---
|
|
15991
|
+
|
|
15992
|
+
## \u{1F504} VERSION UPDATES (Check Periodically)
|
|
15993
|
+
|
|
15994
|
+
**This editor does NOT have hooks to check for updates automatically.**
|
|
15995
|
+
You should check for updates using \`help(action="version")\` periodically (e.g., at session start).
|
|
15996
|
+
|
|
15997
|
+
### If the response includes [VERSION_NOTICE] or [VERSION_CRITICAL]:
|
|
15998
|
+
|
|
15999
|
+
**Tell the user** about the available update in a helpful, non-annoying way:
|
|
16000
|
+
- Frame it as "new features and improvements available"
|
|
16001
|
+
- Provide the update commands (user can choose their preferred method)
|
|
16002
|
+
- Don't nag repeatedly - mention once, then only if user asks
|
|
16003
|
+
|
|
16004
|
+
### Update Commands (provide all options):
|
|
16005
|
+
|
|
16006
|
+
**macOS/Linux:**
|
|
16007
|
+
\`\`\`bash
|
|
16008
|
+
curl -fsSL https://contextstream.io/scripts/setup.sh | bash
|
|
16009
|
+
\`\`\`
|
|
16010
|
+
|
|
16011
|
+
**Windows (PowerShell):**
|
|
16012
|
+
\`\`\`powershell
|
|
16013
|
+
irm https://contextstream.io/scripts/setup.ps1 | iex
|
|
16014
|
+
\`\`\`
|
|
16015
|
+
|
|
16016
|
+
**npm (requires Node.js 18+):**
|
|
16017
|
+
\`\`\`bash
|
|
16018
|
+
npm install -g @contextstream/mcp-server@latest
|
|
16019
|
+
\`\`\`
|
|
16020
|
+
|
|
16021
|
+
After updating, user should restart their AI tool.
|
|
16022
|
+
|
|
15133
16023
|
---
|
|
15134
16024
|
`;
|
|
15135
16025
|
var NO_HOOKS_EDITORS = ["codex", "aider", "antigravity"];
|
|
@@ -15238,6 +16128,9 @@ function generateAllRuleFiles(options) {
|
|
|
15238
16128
|
}).filter((r) => r !== null);
|
|
15239
16129
|
}
|
|
15240
16130
|
|
|
16131
|
+
// src/tools.ts
|
|
16132
|
+
init_version();
|
|
16133
|
+
|
|
15241
16134
|
// src/tool-catalog.ts
|
|
15242
16135
|
var TOOL_CATALOG = [
|
|
15243
16136
|
{
|
|
@@ -17241,12 +18134,6 @@ function registerTools(server, client, sessionManager) {
|
|
|
17241
18134
|
function getToolAccessTier(toolName) {
|
|
17242
18135
|
return proTools.has(toolName) ? "pro" : "free";
|
|
17243
18136
|
}
|
|
17244
|
-
function getToolAccessLabel(toolName) {
|
|
17245
|
-
const graphTier = graphToolTiers.get(toolName);
|
|
17246
|
-
if (graphTier === "lite") return "Pro (Graph-Lite)";
|
|
17247
|
-
if (graphTier === "full") return "Elite/Team (Full Graph)";
|
|
17248
|
-
return getToolAccessTier(toolName) === "pro" ? "PRO" : "Free";
|
|
17249
|
-
}
|
|
17250
18137
|
async function gateIfProTool(toolName) {
|
|
17251
18138
|
if (getToolAccessTier(toolName) !== "pro") return null;
|
|
17252
18139
|
const planName = await client.getPlanName();
|
|
@@ -17542,22 +18429,18 @@ function registerTools(server, client, sessionManager) {
|
|
|
17542
18429
|
};
|
|
17543
18430
|
}
|
|
17544
18431
|
function actuallyRegisterTool(name, config, handler) {
|
|
17545
|
-
const accessLabel = getToolAccessLabel(name);
|
|
17546
|
-
const showUpgrade = accessLabel !== "Free";
|
|
17547
18432
|
let finalDescription;
|
|
17548
18433
|
let finalSchema;
|
|
17549
18434
|
if (COMPACT_SCHEMA_ENABLED) {
|
|
17550
18435
|
finalDescription = compactifyDescription(config.description);
|
|
17551
18436
|
finalSchema = config.inputSchema ? applyCompactParamDescriptions(config.inputSchema) : void 0;
|
|
17552
18437
|
} else {
|
|
17553
|
-
finalDescription =
|
|
17554
|
-
|
|
17555
|
-
Access: ${accessLabel}${showUpgrade ? ` (upgrade: ${upgradeUrl2})` : ""}`;
|
|
18438
|
+
finalDescription = config.description;
|
|
17556
18439
|
finalSchema = config.inputSchema ? applyParamDescriptions(config.inputSchema) : void 0;
|
|
17557
18440
|
}
|
|
17558
18441
|
const labeledConfig = {
|
|
17559
18442
|
...config,
|
|
17560
|
-
title:
|
|
18443
|
+
title: config.title,
|
|
17561
18444
|
description: finalDescription
|
|
17562
18445
|
};
|
|
17563
18446
|
const annotatedConfig = {
|
|
@@ -20935,7 +21818,8 @@ This saves ~80% tokens compared to including full chat history.`,
|
|
|
20935
21818
|
context_threshold: external_exports.number().optional().describe("Custom context window threshold (defaults to 70k)"),
|
|
20936
21819
|
save_exchange: external_exports.boolean().optional().describe("Save this exchange to the transcript for later search (background task)"),
|
|
20937
21820
|
session_id: external_exports.string().optional().describe("Session ID for transcript association (required if save_exchange is true)"),
|
|
20938
|
-
client_name: external_exports.string().optional().describe("Client name for transcript metadata (e.g., 'claude', 'cursor')")
|
|
21821
|
+
client_name: external_exports.string().optional().describe("Client name for transcript metadata (e.g., 'claude', 'cursor')"),
|
|
21822
|
+
assistant_message: external_exports.string().optional().describe("Previous assistant response to save along with user message (for complete exchange capture)")
|
|
20939
21823
|
})
|
|
20940
21824
|
},
|
|
20941
21825
|
async (input) => {
|
|
@@ -21031,7 +21915,8 @@ This saves ~80% tokens compared to including full chat history.`,
|
|
|
21031
21915
|
context_threshold: contextThreshold,
|
|
21032
21916
|
save_exchange: input.save_exchange,
|
|
21033
21917
|
session_id: sessionId,
|
|
21034
|
-
client_name: clientName
|
|
21918
|
+
client_name: clientName,
|
|
21919
|
+
assistant_message: input.assistant_message
|
|
21035
21920
|
});
|
|
21036
21921
|
if (sessionManager && result.token_estimate) {
|
|
21037
21922
|
sessionManager.addTokens(result.token_estimate);
|
|
@@ -24293,7 +25178,7 @@ ${formatContent(result)}`
|
|
|
24293
25178
|
"project",
|
|
24294
25179
|
{
|
|
24295
25180
|
title: "Project",
|
|
24296
|
-
description: `Project management. Actions: list, get, create, update, index (trigger indexing), overview, statistics, files, index_status, ingest_local (index local folder), team_projects (list all team projects - team plans only).`,
|
|
25181
|
+
description: `Project management. Actions: list, get, create, update, index (trigger indexing), overview, statistics, files, index_status, index_history (audit trail of indexed files), ingest_local (index local folder), team_projects (list all team projects - team plans only).`,
|
|
24297
25182
|
inputSchema: external_exports.object({
|
|
24298
25183
|
action: external_exports.enum([
|
|
24299
25184
|
"list",
|
|
@@ -24305,6 +25190,7 @@ ${formatContent(result)}`
|
|
|
24305
25190
|
"statistics",
|
|
24306
25191
|
"files",
|
|
24307
25192
|
"index_status",
|
|
25193
|
+
"index_history",
|
|
24308
25194
|
"ingest_local",
|
|
24309
25195
|
"team_projects"
|
|
24310
25196
|
]).describe("Action to perform"),
|
|
@@ -24319,6 +25205,15 @@ ${formatContent(result)}`
|
|
|
24319
25205
|
path: external_exports.string().optional().describe("Local path to ingest"),
|
|
24320
25206
|
overwrite: external_exports.boolean().optional(),
|
|
24321
25207
|
write_to_disk: external_exports.boolean().optional(),
|
|
25208
|
+
force: external_exports.boolean().optional().describe("Force re-index all files, bypassing version check logic"),
|
|
25209
|
+
// Index history filters
|
|
25210
|
+
machine_id: external_exports.string().optional().describe("Filter by machine ID that indexed the files"),
|
|
25211
|
+
branch: external_exports.string().optional().describe("Filter by git branch"),
|
|
25212
|
+
since: external_exports.string().optional().describe("Filter files indexed after this timestamp (ISO 8601)"),
|
|
25213
|
+
until: external_exports.string().optional().describe("Filter files indexed before this timestamp (ISO 8601)"),
|
|
25214
|
+
path_pattern: external_exports.string().optional().describe("Filter by file path pattern (partial match)"),
|
|
25215
|
+
sort_by: external_exports.enum(["path", "indexed", "size"]).optional().describe("Sort field (default: indexed)"),
|
|
25216
|
+
sort_order: external_exports.enum(["asc", "desc"]).optional().describe("Sort order (default: desc)"),
|
|
24322
25217
|
// Pagination
|
|
24323
25218
|
page: external_exports.number().optional(),
|
|
24324
25219
|
page_size: external_exports.number().optional()
|
|
@@ -24417,6 +25312,25 @@ ${formatContent(result)}`
|
|
|
24417
25312
|
content: [{ type: "text", text: formatContent(result) }]
|
|
24418
25313
|
};
|
|
24419
25314
|
}
|
|
25315
|
+
case "index_history": {
|
|
25316
|
+
if (!projectId) {
|
|
25317
|
+
return errorResult("index_history requires: project_id");
|
|
25318
|
+
}
|
|
25319
|
+
const result = await client.projectIndexHistory(projectId, {
|
|
25320
|
+
machine_id: input.machine_id,
|
|
25321
|
+
branch: input.branch,
|
|
25322
|
+
since: input.since,
|
|
25323
|
+
until: input.until,
|
|
25324
|
+
path_pattern: input.path_pattern,
|
|
25325
|
+
sort_by: input.sort_by,
|
|
25326
|
+
sort_order: input.sort_order,
|
|
25327
|
+
page: input.page,
|
|
25328
|
+
limit: input.page_size
|
|
25329
|
+
});
|
|
25330
|
+
return {
|
|
25331
|
+
content: [{ type: "text", text: formatContent(result) }]
|
|
25332
|
+
};
|
|
25333
|
+
}
|
|
24420
25334
|
case "ingest_local": {
|
|
24421
25335
|
if (!input.path) {
|
|
24422
25336
|
return errorResult("ingest_local requires: path");
|
|
@@ -24430,23 +25344,26 @@ ${formatContent(result)}`
|
|
|
24430
25344
|
}
|
|
24431
25345
|
const ingestOptions = {
|
|
24432
25346
|
...input.write_to_disk !== void 0 && { write_to_disk: input.write_to_disk },
|
|
24433
|
-
...input.overwrite !== void 0 && { overwrite: input.overwrite }
|
|
25347
|
+
...input.overwrite !== void 0 && { overwrite: input.overwrite },
|
|
25348
|
+
...input.force !== void 0 && { force: input.force }
|
|
24434
25349
|
};
|
|
24435
25350
|
startBackgroundIngest(projectId, validPath.resolvedPath, ingestOptions);
|
|
25351
|
+
const forceNote = input.force ? " (force mode - version checks bypassed)" : "";
|
|
24436
25352
|
const result = {
|
|
24437
25353
|
status: "started",
|
|
24438
|
-
message:
|
|
25354
|
+
message: `Ingestion running in background${forceNote}`,
|
|
24439
25355
|
project_id: projectId,
|
|
24440
25356
|
path: validPath.resolvedPath,
|
|
24441
25357
|
...input.write_to_disk !== void 0 && { write_to_disk: input.write_to_disk },
|
|
24442
25358
|
...input.overwrite !== void 0 && { overwrite: input.overwrite },
|
|
25359
|
+
...input.force !== void 0 && { force: input.force },
|
|
24443
25360
|
note: "Use 'project' with action 'index_status' to monitor progress."
|
|
24444
25361
|
};
|
|
24445
25362
|
return {
|
|
24446
25363
|
content: [
|
|
24447
25364
|
{
|
|
24448
25365
|
type: "text",
|
|
24449
|
-
text: `Ingestion started in background for directory: ${validPath.resolvedPath}. Use 'project' with action 'index_status' to monitor progress.`
|
|
25366
|
+
text: `Ingestion started in background${forceNote} for directory: ${validPath.resolvedPath}. Use 'project' with action 'index_status' to monitor progress.`
|
|
24450
25367
|
}
|
|
24451
25368
|
]
|
|
24452
25369
|
};
|
|
@@ -24480,9 +25397,9 @@ ${formatContent(result)}`
|
|
|
24480
25397
|
"workspace",
|
|
24481
25398
|
{
|
|
24482
25399
|
title: "Workspace",
|
|
24483
|
-
description: `Workspace management. Actions: list, get, associate (link folder to workspace), bootstrap (create workspace and initialize), team_members (list members with access - team plans only).`,
|
|
25400
|
+
description: `Workspace management. Actions: list, get, associate (link folder to workspace), bootstrap (create workspace and initialize), team_members (list members with access - team plans only), index_settings (get/update multi-machine sync settings - admin only).`,
|
|
24484
25401
|
inputSchema: external_exports.object({
|
|
24485
|
-
action: external_exports.enum(["list", "get", "associate", "bootstrap", "team_members"]).describe("Action to perform"),
|
|
25402
|
+
action: external_exports.enum(["list", "get", "associate", "bootstrap", "team_members", "index_settings"]).describe("Action to perform"),
|
|
24486
25403
|
workspace_id: external_exports.string().uuid().optional(),
|
|
24487
25404
|
// Associate/bootstrap params
|
|
24488
25405
|
folder_path: external_exports.string().optional(),
|
|
@@ -24494,6 +25411,12 @@ ${formatContent(result)}`
|
|
|
24494
25411
|
visibility: external_exports.enum(["private", "public"]).optional(),
|
|
24495
25412
|
auto_index: external_exports.boolean().optional(),
|
|
24496
25413
|
context_hint: external_exports.string().optional(),
|
|
25414
|
+
// Index settings params (for update)
|
|
25415
|
+
branch_policy: external_exports.enum(["default_branch_wins", "newest_wins", "feature_branch_wins"]).optional().describe("Which branch takes priority: default_branch_wins (default), newest_wins, feature_branch_wins"),
|
|
25416
|
+
conflict_resolution: external_exports.enum(["newest_timestamp", "default_branch", "manual"]).optional().describe("How to resolve conflicts: newest_timestamp (default), default_branch, manual"),
|
|
25417
|
+
allowed_machines: external_exports.array(external_exports.string()).optional().describe("List of allowed machine IDs (empty = all allowed)"),
|
|
25418
|
+
auto_sync_enabled: external_exports.boolean().optional().describe("Whether to auto-sync from all machines (default: true)"),
|
|
25419
|
+
max_machines: external_exports.number().optional().describe("Maximum machines allowed to index (0 = unlimited)"),
|
|
24497
25420
|
// Pagination
|
|
24498
25421
|
page: external_exports.number().optional(),
|
|
24499
25422
|
page_size: external_exports.number().optional()
|
|
@@ -24597,6 +25520,29 @@ ${formatContent(result)}`
|
|
|
24597
25520
|
content: [{ type: "text", text: formatContent(teamMembers) }]
|
|
24598
25521
|
};
|
|
24599
25522
|
}
|
|
25523
|
+
case "index_settings": {
|
|
25524
|
+
if (!input.workspace_id) {
|
|
25525
|
+
return errorResult("index_settings requires: workspace_id");
|
|
25526
|
+
}
|
|
25527
|
+
const hasUpdateParams = input.branch_policy !== void 0 || input.conflict_resolution !== void 0 || input.allowed_machines !== void 0 || input.auto_sync_enabled !== void 0 || input.max_machines !== void 0;
|
|
25528
|
+
if (hasUpdateParams) {
|
|
25529
|
+
const result = await client.updateWorkspaceIndexSettings(input.workspace_id, {
|
|
25530
|
+
branch_policy: input.branch_policy,
|
|
25531
|
+
conflict_resolution: input.conflict_resolution,
|
|
25532
|
+
allowed_machines: input.allowed_machines,
|
|
25533
|
+
auto_sync_enabled: input.auto_sync_enabled,
|
|
25534
|
+
max_machines: input.max_machines
|
|
25535
|
+
});
|
|
25536
|
+
return {
|
|
25537
|
+
content: [{ type: "text", text: formatContent(result) }]
|
|
25538
|
+
};
|
|
25539
|
+
} else {
|
|
25540
|
+
const result = await client.getWorkspaceIndexSettings(input.workspace_id);
|
|
25541
|
+
return {
|
|
25542
|
+
content: [{ type: "text", text: formatContent(result) }]
|
|
25543
|
+
};
|
|
25544
|
+
}
|
|
25545
|
+
}
|
|
24600
25546
|
default:
|
|
24601
25547
|
return errorResult(`Unknown action: ${input.action}`);
|
|
24602
25548
|
}
|
|
@@ -27117,7 +28063,7 @@ var SessionManager = class _SessionManager {
|
|
|
27117
28063
|
buildContextSummary(context) {
|
|
27118
28064
|
const parts = [];
|
|
27119
28065
|
parts.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
27120
|
-
parts.push("\u2B21
|
|
28066
|
+
parts.push("\u2B21 ContextStream \u2014 Smart Context & Memory");
|
|
27121
28067
|
parts.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
27122
28068
|
if (context.status === "requires_workspace_name") {
|
|
27123
28069
|
parts.push("");
|
|
@@ -27345,6 +28291,7 @@ import { createServer } from "node:http";
|
|
|
27345
28291
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
27346
28292
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
27347
28293
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
28294
|
+
init_version();
|
|
27348
28295
|
var HOST = process.env.MCP_HTTP_HOST || "0.0.0.0";
|
|
27349
28296
|
var PORT = Number.parseInt(process.env.MCP_HTTP_PORT || "8787", 10);
|
|
27350
28297
|
var MCP_PATH = process.env.MCP_HTTP_PATH || "/mcp";
|
|
@@ -27623,6 +28570,7 @@ async function runHttpGateway() {
|
|
|
27623
28570
|
}
|
|
27624
28571
|
|
|
27625
28572
|
// src/index.ts
|
|
28573
|
+
init_version();
|
|
27626
28574
|
import { existsSync as existsSync17, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
27627
28575
|
import { homedir as homedir19 } from "os";
|
|
27628
28576
|
import { join as join23 } from "path";
|
|
@@ -27633,6 +28581,7 @@ import * as path8 from "node:path";
|
|
|
27633
28581
|
import { homedir as homedir5 } from "node:os";
|
|
27634
28582
|
import { stdin, stdout } from "node:process";
|
|
27635
28583
|
import { createInterface } from "node:readline/promises";
|
|
28584
|
+
init_version();
|
|
27636
28585
|
|
|
27637
28586
|
// src/credentials.ts
|
|
27638
28587
|
import * as fs6 from "node:fs/promises";
|
|
@@ -27783,7 +28732,8 @@ var CONTEXTSTREAM_PREAMBLE_PATTERNS2 = [
|
|
|
27783
28732
|
/^#\s+cline rules$/i,
|
|
27784
28733
|
/^#\s+kilo code rules$/i,
|
|
27785
28734
|
/^#\s+roo code rules$/i,
|
|
27786
|
-
/^#\s+aider configuration$/i
|
|
28735
|
+
/^#\s+aider configuration$/i,
|
|
28736
|
+
/^#\s+antigravity agent rules$/i
|
|
27787
28737
|
];
|
|
27788
28738
|
function wrapWithMarkers2(content) {
|
|
27789
28739
|
return `${CONTEXTSTREAM_START_MARKER2}
|
|
@@ -28191,6 +29141,9 @@ function claudeDesktopConfigPath() {
|
|
|
28191
29141
|
const appData = process.env.APPDATA || path8.join(home, "AppData", "Roaming");
|
|
28192
29142
|
return path8.join(appData, "Claude", "claude_desktop_config.json");
|
|
28193
29143
|
}
|
|
29144
|
+
if (process.platform === "linux") {
|
|
29145
|
+
return path8.join(home, ".config", "Claude", "claude_desktop_config.json");
|
|
29146
|
+
}
|
|
28194
29147
|
return null;
|
|
28195
29148
|
}
|
|
28196
29149
|
async function upsertCodexTomlConfig(filePath, params) {
|
|
@@ -28576,6 +29529,20 @@ Detected plan: ${planLabel} (graph: ${graphTierLabel})`);
|
|
|
28576
29529
|
const contextPackEnabled = isPro;
|
|
28577
29530
|
const showTiming = false;
|
|
28578
29531
|
const restoreContextEnabled = true;
|
|
29532
|
+
console.log("\nAuto-Update:");
|
|
29533
|
+
console.log(" When enabled, ContextStream will automatically update to the latest version");
|
|
29534
|
+
console.log(" on new sessions (checks daily). You can disable this if you prefer manual updates.");
|
|
29535
|
+
const currentAutoUpdate = isAutoUpdateEnabled();
|
|
29536
|
+
const autoUpdateChoice = normalizeInput(
|
|
29537
|
+
await rl.question(`Enable auto-update? [${currentAutoUpdate ? "Y/n" : "y/N"}]: `)
|
|
29538
|
+
).toLowerCase();
|
|
29539
|
+
const autoUpdateEnabled = autoUpdateChoice === "" ? currentAutoUpdate : autoUpdateChoice === "y" || autoUpdateChoice === "yes";
|
|
29540
|
+
setAutoUpdatePreference(autoUpdateEnabled);
|
|
29541
|
+
if (autoUpdateEnabled) {
|
|
29542
|
+
console.log(" \u2713 Auto-update enabled (disable anytime with CONTEXTSTREAM_AUTO_UPDATE=false)");
|
|
29543
|
+
} else {
|
|
29544
|
+
console.log(" \u2717 Auto-update disabled");
|
|
29545
|
+
}
|
|
28579
29546
|
const editors = [
|
|
28580
29547
|
"codex",
|
|
28581
29548
|
"claude",
|