@contextstream/mcp-server 0.4.51 → 0.4.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/auto-rules.js +5 -1
- package/dist/hooks/pre-compact.js +3 -1
- package/dist/hooks/pre-tool-use.js +29 -4
- package/dist/hooks/runner.js +439 -167
- package/dist/hooks/user-prompt-submit.js +250 -9
- package/dist/index.js +824 -412
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -335,7 +335,7 @@ var require_ignore = __commonJS({
|
|
|
335
335
|
// path matching.
|
|
336
336
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
337
337
|
// @returns {TestResult} true if a file is ignored
|
|
338
|
-
test(
|
|
338
|
+
test(path22, checkUnignored, mode) {
|
|
339
339
|
let ignored = false;
|
|
340
340
|
let unignored = false;
|
|
341
341
|
let matchedRule;
|
|
@@ -344,7 +344,7 @@ var require_ignore = __commonJS({
|
|
|
344
344
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
345
345
|
return;
|
|
346
346
|
}
|
|
347
|
-
const matched = rule[mode].test(
|
|
347
|
+
const matched = rule[mode].test(path22);
|
|
348
348
|
if (!matched) {
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
@@ -365,17 +365,17 @@ var require_ignore = __commonJS({
|
|
|
365
365
|
var throwError = (message, Ctor) => {
|
|
366
366
|
throw new Ctor(message);
|
|
367
367
|
};
|
|
368
|
-
var checkPath = (
|
|
369
|
-
if (!isString(
|
|
368
|
+
var checkPath = (path22, originalPath, doThrow) => {
|
|
369
|
+
if (!isString(path22)) {
|
|
370
370
|
return doThrow(
|
|
371
371
|
`path must be a string, but got \`${originalPath}\``,
|
|
372
372
|
TypeError
|
|
373
373
|
);
|
|
374
374
|
}
|
|
375
|
-
if (!
|
|
375
|
+
if (!path22) {
|
|
376
376
|
return doThrow(`path must not be empty`, TypeError);
|
|
377
377
|
}
|
|
378
|
-
if (checkPath.isNotRelative(
|
|
378
|
+
if (checkPath.isNotRelative(path22)) {
|
|
379
379
|
const r = "`path.relative()`d";
|
|
380
380
|
return doThrow(
|
|
381
381
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -384,7 +384,7 @@ var require_ignore = __commonJS({
|
|
|
384
384
|
}
|
|
385
385
|
return true;
|
|
386
386
|
};
|
|
387
|
-
var isNotRelative = (
|
|
387
|
+
var isNotRelative = (path22) => REGEX_TEST_INVALID_PATH.test(path22);
|
|
388
388
|
checkPath.isNotRelative = isNotRelative;
|
|
389
389
|
checkPath.convert = (p) => p;
|
|
390
390
|
var Ignore2 = class {
|
|
@@ -414,19 +414,19 @@ var require_ignore = __commonJS({
|
|
|
414
414
|
}
|
|
415
415
|
// @returns {TestResult}
|
|
416
416
|
_test(originalPath, cache, checkUnignored, slices) {
|
|
417
|
-
const
|
|
417
|
+
const path22 = originalPath && checkPath.convert(originalPath);
|
|
418
418
|
checkPath(
|
|
419
|
-
|
|
419
|
+
path22,
|
|
420
420
|
originalPath,
|
|
421
421
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
422
422
|
);
|
|
423
|
-
return this._t(
|
|
423
|
+
return this._t(path22, cache, checkUnignored, slices);
|
|
424
424
|
}
|
|
425
|
-
checkIgnore(
|
|
426
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
427
|
-
return this.test(
|
|
425
|
+
checkIgnore(path22) {
|
|
426
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path22)) {
|
|
427
|
+
return this.test(path22);
|
|
428
428
|
}
|
|
429
|
-
const slices =
|
|
429
|
+
const slices = path22.split(SLASH).filter(Boolean);
|
|
430
430
|
slices.pop();
|
|
431
431
|
if (slices.length) {
|
|
432
432
|
const parent = this._t(
|
|
@@ -439,18 +439,18 @@ var require_ignore = __commonJS({
|
|
|
439
439
|
return parent;
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
|
-
return this._rules.test(
|
|
442
|
+
return this._rules.test(path22, false, MODE_CHECK_IGNORE);
|
|
443
443
|
}
|
|
444
|
-
_t(
|
|
445
|
-
if (
|
|
446
|
-
return cache[
|
|
444
|
+
_t(path22, cache, checkUnignored, slices) {
|
|
445
|
+
if (path22 in cache) {
|
|
446
|
+
return cache[path22];
|
|
447
447
|
}
|
|
448
448
|
if (!slices) {
|
|
449
|
-
slices =
|
|
449
|
+
slices = path22.split(SLASH).filter(Boolean);
|
|
450
450
|
}
|
|
451
451
|
slices.pop();
|
|
452
452
|
if (!slices.length) {
|
|
453
|
-
return cache[
|
|
453
|
+
return cache[path22] = this._rules.test(path22, checkUnignored, MODE_IGNORE);
|
|
454
454
|
}
|
|
455
455
|
const parent = this._t(
|
|
456
456
|
slices.join(SLASH) + SLASH,
|
|
@@ -458,29 +458,29 @@ var require_ignore = __commonJS({
|
|
|
458
458
|
checkUnignored,
|
|
459
459
|
slices
|
|
460
460
|
);
|
|
461
|
-
return cache[
|
|
461
|
+
return cache[path22] = parent.ignored ? parent : this._rules.test(path22, checkUnignored, MODE_IGNORE);
|
|
462
462
|
}
|
|
463
|
-
ignores(
|
|
464
|
-
return this._test(
|
|
463
|
+
ignores(path22) {
|
|
464
|
+
return this._test(path22, this._ignoreCache, false).ignored;
|
|
465
465
|
}
|
|
466
466
|
createFilter() {
|
|
467
|
-
return (
|
|
467
|
+
return (path22) => !this.ignores(path22);
|
|
468
468
|
}
|
|
469
469
|
filter(paths) {
|
|
470
470
|
return makeArray(paths).filter(this.createFilter());
|
|
471
471
|
}
|
|
472
472
|
// @returns {TestResult}
|
|
473
|
-
test(
|
|
474
|
-
return this._test(
|
|
473
|
+
test(path22) {
|
|
474
|
+
return this._test(path22, this._testCache, true);
|
|
475
475
|
}
|
|
476
476
|
};
|
|
477
477
|
var factory = (options) => new Ignore2(options);
|
|
478
|
-
var isPathValid = (
|
|
478
|
+
var isPathValid = (path22) => checkPath(path22 && checkPath.convert(path22), path22, RETURN_FALSE);
|
|
479
479
|
var setupWindows = () => {
|
|
480
480
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
481
481
|
checkPath.convert = makePosix;
|
|
482
482
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
483
|
-
checkPath.isNotRelative = (
|
|
483
|
+
checkPath.isNotRelative = (path22) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path22) || isNotRelative(path22);
|
|
484
484
|
};
|
|
485
485
|
if (
|
|
486
486
|
// Detect `process` so that it can run in browsers.
|
|
@@ -542,11 +542,15 @@ import * as path5 from "node:path";
|
|
|
542
542
|
import { homedir as homedir2 } from "node:os";
|
|
543
543
|
import { fileURLToPath } from "node:url";
|
|
544
544
|
function getHookCommand(hookName) {
|
|
545
|
+
const fs21 = __require("node:fs");
|
|
546
|
+
const binaryPath = "/usr/local/bin/contextstream-mcp";
|
|
547
|
+
if (fs21.existsSync(binaryPath)) {
|
|
548
|
+
return `${binaryPath} hook ${hookName}`;
|
|
549
|
+
}
|
|
545
550
|
try {
|
|
546
551
|
const __dirname = path5.dirname(fileURLToPath(import.meta.url));
|
|
547
552
|
const indexPath = path5.join(__dirname, "index.js");
|
|
548
|
-
|
|
549
|
-
if (fs20.existsSync(indexPath)) {
|
|
553
|
+
if (fs21.existsSync(indexPath)) {
|
|
550
554
|
return `node ${indexPath} hook ${hookName}`;
|
|
551
555
|
}
|
|
552
556
|
} catch {
|
|
@@ -2514,8 +2518,17 @@ function extractToolInput(input) {
|
|
|
2514
2518
|
return input.tool_input || input.parameters || input.toolParameters || {};
|
|
2515
2519
|
}
|
|
2516
2520
|
function blockClaudeCode(message) {
|
|
2517
|
-
|
|
2518
|
-
|
|
2521
|
+
const response = {
|
|
2522
|
+
hookSpecificOutput: {
|
|
2523
|
+
hookEventName: "PreToolUse",
|
|
2524
|
+
// Use additionalContext instead of deny - tool runs but Claude sees the message
|
|
2525
|
+
additionalContext: `[CONTEXTSTREAM] ${message}`
|
|
2526
|
+
}
|
|
2527
|
+
};
|
|
2528
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] REDIRECT (additionalContext): ${JSON.stringify(response)}
|
|
2529
|
+
`);
|
|
2530
|
+
console.log(JSON.stringify(response));
|
|
2531
|
+
process.exit(0);
|
|
2519
2532
|
}
|
|
2520
2533
|
function outputClineBlock(errorMessage, contextMod) {
|
|
2521
2534
|
const result = {
|
|
@@ -2544,13 +2557,18 @@ function detectEditorFormat(input) {
|
|
|
2544
2557
|
if (input.hookName !== void 0 || input.toolName !== void 0) {
|
|
2545
2558
|
return "cline";
|
|
2546
2559
|
}
|
|
2547
|
-
if (input.hook_event_name !== void 0) {
|
|
2548
|
-
return "
|
|
2560
|
+
if (input.hook_event_name !== void 0 || input.tool_name !== void 0) {
|
|
2561
|
+
return "claude";
|
|
2549
2562
|
}
|
|
2550
2563
|
return "claude";
|
|
2551
2564
|
}
|
|
2552
2565
|
async function runPreToolUseHook() {
|
|
2566
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] Hook invoked at ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
2567
|
+
`);
|
|
2568
|
+
console.error("[PreToolUse] Hook invoked at", (/* @__PURE__ */ new Date()).toISOString());
|
|
2553
2569
|
if (!ENABLED2) {
|
|
2570
|
+
fs9.appendFileSync(DEBUG_FILE, "[PreToolUse] Hook disabled, exiting\n");
|
|
2571
|
+
console.error("[PreToolUse] Hook disabled, exiting");
|
|
2554
2572
|
process.exit(0);
|
|
2555
2573
|
}
|
|
2556
2574
|
let inputData = "";
|
|
@@ -2570,8 +2588,14 @@ async function runPreToolUseHook() {
|
|
|
2570
2588
|
const cwd = extractCwd2(input);
|
|
2571
2589
|
const tool = extractToolName(input);
|
|
2572
2590
|
const toolInput = extractToolInput(input);
|
|
2591
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] tool=${tool}, cwd=${cwd}, editorFormat=${editorFormat}
|
|
2592
|
+
`);
|
|
2573
2593
|
const { isIndexed } = isProjectIndexed(cwd);
|
|
2594
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] isIndexed=${isIndexed}
|
|
2595
|
+
`);
|
|
2574
2596
|
if (!isIndexed) {
|
|
2597
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] Project not indexed, allowing
|
|
2598
|
+
`);
|
|
2575
2599
|
if (editorFormat === "cline") {
|
|
2576
2600
|
outputClineAllow();
|
|
2577
2601
|
} else if (editorFormat === "cursor") {
|
|
@@ -2581,8 +2605,12 @@ async function runPreToolUseHook() {
|
|
|
2581
2605
|
}
|
|
2582
2606
|
if (tool === "Glob") {
|
|
2583
2607
|
const pattern = toolInput?.pattern || "";
|
|
2608
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] Glob pattern=${pattern}, isDiscovery=${isDiscoveryGlob(pattern)}
|
|
2609
|
+
`);
|
|
2584
2610
|
if (isDiscoveryGlob(pattern)) {
|
|
2585
2611
|
const msg = `STOP: Use mcp__contextstream__search(mode="hybrid", query="${pattern}") instead of Glob.`;
|
|
2612
|
+
fs9.appendFileSync(DEBUG_FILE, `[PreToolUse] Intercepting discovery glob: ${msg}
|
|
2613
|
+
`);
|
|
2586
2614
|
if (editorFormat === "cline") {
|
|
2587
2615
|
outputClineBlock(msg, "[CONTEXTSTREAM] Use ContextStream search for code discovery.");
|
|
2588
2616
|
} else if (editorFormat === "cursor") {
|
|
@@ -2659,12 +2687,13 @@ async function runPreToolUseHook() {
|
|
|
2659
2687
|
}
|
|
2660
2688
|
process.exit(0);
|
|
2661
2689
|
}
|
|
2662
|
-
var ENABLED2, INDEX_STATUS_FILE, STALE_THRESHOLD_DAYS, DISCOVERY_PATTERNS, isDirectRun2;
|
|
2690
|
+
var ENABLED2, INDEX_STATUS_FILE, DEBUG_FILE, STALE_THRESHOLD_DAYS, DISCOVERY_PATTERNS, isDirectRun2;
|
|
2663
2691
|
var init_pre_tool_use = __esm({
|
|
2664
2692
|
"src/hooks/pre-tool-use.ts"() {
|
|
2665
2693
|
"use strict";
|
|
2666
2694
|
ENABLED2 = process.env.CONTEXTSTREAM_HOOK_ENABLED !== "false";
|
|
2667
2695
|
INDEX_STATUS_FILE = path10.join(homedir7(), ".contextstream", "indexed-projects.json");
|
|
2696
|
+
DEBUG_FILE = "/tmp/pretooluse-hook-debug.log";
|
|
2668
2697
|
STALE_THRESHOLD_DAYS = 7;
|
|
2669
2698
|
DISCOVERY_PATTERNS = ["**/*", "**/", "src/**", "lib/**", "app/**", "components/**"];
|
|
2670
2699
|
isDirectRun2 = process.argv[1]?.includes("pre-tool-use") || process.argv[2] === "pre-tool-use";
|
|
@@ -2679,6 +2708,184 @@ var user_prompt_submit_exports = {};
|
|
|
2679
2708
|
__export(user_prompt_submit_exports, {
|
|
2680
2709
|
runUserPromptSubmitHook: () => runUserPromptSubmitHook
|
|
2681
2710
|
});
|
|
2711
|
+
import * as fs10 from "node:fs";
|
|
2712
|
+
import * as path11 from "node:path";
|
|
2713
|
+
import { homedir as homedir8 } from "node:os";
|
|
2714
|
+
function loadConfigFromMcpJson(cwd) {
|
|
2715
|
+
let searchDir = path11.resolve(cwd);
|
|
2716
|
+
for (let i = 0; i < 5; i++) {
|
|
2717
|
+
if (!API_KEY2) {
|
|
2718
|
+
const mcpPath = path11.join(searchDir, ".mcp.json");
|
|
2719
|
+
if (fs10.existsSync(mcpPath)) {
|
|
2720
|
+
try {
|
|
2721
|
+
const content = fs10.readFileSync(mcpPath, "utf-8");
|
|
2722
|
+
const config = JSON.parse(content);
|
|
2723
|
+
const csEnv = config.mcpServers?.contextstream?.env;
|
|
2724
|
+
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
2725
|
+
API_KEY2 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
2726
|
+
}
|
|
2727
|
+
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
2728
|
+
API_URL2 = csEnv.CONTEXTSTREAM_API_URL;
|
|
2729
|
+
}
|
|
2730
|
+
if (csEnv?.CONTEXTSTREAM_WORKSPACE_ID) {
|
|
2731
|
+
WORKSPACE_ID = csEnv.CONTEXTSTREAM_WORKSPACE_ID;
|
|
2732
|
+
}
|
|
2733
|
+
} catch {
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
if (!WORKSPACE_ID || !PROJECT_ID) {
|
|
2738
|
+
const csConfigPath = path11.join(searchDir, ".contextstream", "config.json");
|
|
2739
|
+
if (fs10.existsSync(csConfigPath)) {
|
|
2740
|
+
try {
|
|
2741
|
+
const content = fs10.readFileSync(csConfigPath, "utf-8");
|
|
2742
|
+
const csConfig = JSON.parse(content);
|
|
2743
|
+
if (csConfig.workspace_id && !WORKSPACE_ID) {
|
|
2744
|
+
WORKSPACE_ID = csConfig.workspace_id;
|
|
2745
|
+
}
|
|
2746
|
+
if (csConfig.project_id && !PROJECT_ID) {
|
|
2747
|
+
PROJECT_ID = csConfig.project_id;
|
|
2748
|
+
}
|
|
2749
|
+
} catch {
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
const parentDir = path11.dirname(searchDir);
|
|
2754
|
+
if (parentDir === searchDir) break;
|
|
2755
|
+
searchDir = parentDir;
|
|
2756
|
+
}
|
|
2757
|
+
if (!API_KEY2) {
|
|
2758
|
+
const homeMcpPath = path11.join(homedir8(), ".mcp.json");
|
|
2759
|
+
if (fs10.existsSync(homeMcpPath)) {
|
|
2760
|
+
try {
|
|
2761
|
+
const content = fs10.readFileSync(homeMcpPath, "utf-8");
|
|
2762
|
+
const config = JSON.parse(content);
|
|
2763
|
+
const csEnv = config.mcpServers?.contextstream?.env;
|
|
2764
|
+
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
2765
|
+
API_KEY2 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
2766
|
+
}
|
|
2767
|
+
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
2768
|
+
API_URL2 = csEnv.CONTEXTSTREAM_API_URL;
|
|
2769
|
+
}
|
|
2770
|
+
} catch {
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
async function fetchSessionContext() {
|
|
2776
|
+
if (!API_KEY2) return null;
|
|
2777
|
+
try {
|
|
2778
|
+
const controller = new AbortController();
|
|
2779
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
2780
|
+
const url = new URL(`${API_URL2}/api/v1/context`);
|
|
2781
|
+
if (WORKSPACE_ID) url.searchParams.set("workspace_id", WORKSPACE_ID);
|
|
2782
|
+
if (PROJECT_ID) url.searchParams.set("project_id", PROJECT_ID);
|
|
2783
|
+
url.searchParams.set("include_lessons", "true");
|
|
2784
|
+
url.searchParams.set("include_decisions", "true");
|
|
2785
|
+
url.searchParams.set("include_plans", "true");
|
|
2786
|
+
url.searchParams.set("include_reminders", "true");
|
|
2787
|
+
url.searchParams.set("limit", "3");
|
|
2788
|
+
const response = await fetch(url.toString(), {
|
|
2789
|
+
method: "GET",
|
|
2790
|
+
headers: {
|
|
2791
|
+
"X-API-Key": API_KEY2
|
|
2792
|
+
},
|
|
2793
|
+
signal: controller.signal
|
|
2794
|
+
});
|
|
2795
|
+
clearTimeout(timeoutId);
|
|
2796
|
+
if (response.ok) {
|
|
2797
|
+
return await response.json();
|
|
2798
|
+
}
|
|
2799
|
+
return null;
|
|
2800
|
+
} catch {
|
|
2801
|
+
return null;
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
function buildEnhancedReminder(ctx, isNewSession2) {
|
|
2805
|
+
const parts = [ENHANCED_REMINDER_HEADER];
|
|
2806
|
+
if (isNewSession2) {
|
|
2807
|
+
parts.push(`## \u{1F680} NEW SESSION DETECTED
|
|
2808
|
+
1. Call \`init(folder_path="...")\` - this triggers project indexing
|
|
2809
|
+
2. Wait for indexing: if \`init\` returns \`indexing_status: "started"\`, files are being indexed
|
|
2810
|
+
3. Then call \`context(user_message="...")\` for task-specific context
|
|
2811
|
+
4. Use \`search(mode="hybrid")\` for code discovery (not Glob/Grep/Read)
|
|
2812
|
+
|
|
2813
|
+
`);
|
|
2814
|
+
}
|
|
2815
|
+
if (ctx?.lessons && ctx.lessons.length > 0) {
|
|
2816
|
+
parts.push(`## \u26A0\uFE0F LESSONS FROM PAST MISTAKES`);
|
|
2817
|
+
for (const lesson of ctx.lessons.slice(0, 3)) {
|
|
2818
|
+
parts.push(`- **${lesson.title}**: ${lesson.prevention}`);
|
|
2819
|
+
}
|
|
2820
|
+
parts.push("");
|
|
2821
|
+
}
|
|
2822
|
+
if (ctx?.active_plans && ctx.active_plans.length > 0) {
|
|
2823
|
+
parts.push(`## \u{1F4CB} Active Plans`);
|
|
2824
|
+
for (const plan of ctx.active_plans.slice(0, 3)) {
|
|
2825
|
+
parts.push(`- ${plan.title} (${plan.status})`);
|
|
2826
|
+
}
|
|
2827
|
+
parts.push("");
|
|
2828
|
+
}
|
|
2829
|
+
if (ctx?.pending_tasks && ctx.pending_tasks.length > 0) {
|
|
2830
|
+
parts.push(`## \u2705 Pending Tasks`);
|
|
2831
|
+
for (const task of ctx.pending_tasks.slice(0, 5)) {
|
|
2832
|
+
parts.push(`- ${task.title}`);
|
|
2833
|
+
}
|
|
2834
|
+
parts.push("");
|
|
2835
|
+
}
|
|
2836
|
+
if (ctx?.reminders && ctx.reminders.length > 0) {
|
|
2837
|
+
parts.push(`## \u{1F514} Reminders`);
|
|
2838
|
+
for (const reminder of ctx.reminders.slice(0, 3)) {
|
|
2839
|
+
parts.push(`- ${reminder.title}`);
|
|
2840
|
+
}
|
|
2841
|
+
parts.push("");
|
|
2842
|
+
}
|
|
2843
|
+
parts.push("---\n");
|
|
2844
|
+
parts.push(REMINDER);
|
|
2845
|
+
parts.push(`
|
|
2846
|
+
|
|
2847
|
+
---
|
|
2848
|
+
## \u{1F6A8} FILE INDEXING & SEARCH - CRITICAL (No PostToolUse Hook) \u{1F6A8}
|
|
2849
|
+
|
|
2850
|
+
**This editor does NOT have automatic file indexing after Edit/Write.**
|
|
2851
|
+
|
|
2852
|
+
### \u26A0\uFE0F BEFORE ANY SEARCH - Check Index Status:
|
|
2853
|
+
\`\`\`
|
|
2854
|
+
project(action="index_status")
|
|
2855
|
+
\`\`\`
|
|
2856
|
+
Returns: \`indexed\` (true/false), \`last_indexed_at\`, \`file_count\`
|
|
2857
|
+
|
|
2858
|
+
### \u{1F50D} Search Decision Tree:
|
|
2859
|
+
|
|
2860
|
+
**IF indexed=true AND last_indexed_at is recent:**
|
|
2861
|
+
\u2192 Use \`search(mode="hybrid", query="...")\`
|
|
2862
|
+
|
|
2863
|
+
**IF indexed=false OR last_indexed_at is stale (>7 days):**
|
|
2864
|
+
\u2192 Use local tools (Glob/Grep/Read) directly
|
|
2865
|
+
\u2192 OR run \`project(action="index")\` first, then search
|
|
2866
|
+
|
|
2867
|
+
**IF search returns 0 results or errors:**
|
|
2868
|
+
\u2192 Fallback to local tools (Glob/Grep/Read)
|
|
2869
|
+
|
|
2870
|
+
### \u2705 When Local Tools (Glob/Grep/Read) Are OK:
|
|
2871
|
+
- Project is NOT indexed
|
|
2872
|
+
- Index is stale/outdated (>7 days)
|
|
2873
|
+
- ContextStream search returns 0 results
|
|
2874
|
+
- ContextStream returns errors
|
|
2875
|
+
- User explicitly requests local tools
|
|
2876
|
+
|
|
2877
|
+
### On Session Start:
|
|
2878
|
+
1. Call \`init(folder_path="...")\` - triggers initial indexing
|
|
2879
|
+
2. Check \`project(action="index_status")\` before searching
|
|
2880
|
+
3. If not indexed: use local tools OR wait for indexing
|
|
2881
|
+
|
|
2882
|
+
### After File Changes (Edit/Write/Create):
|
|
2883
|
+
Files are NOT auto-indexed. You MUST:
|
|
2884
|
+
1. After significant edits: \`project(action="index")\`
|
|
2885
|
+
2. For single file: \`project(action="ingest_local", path="<file>")\`
|
|
2886
|
+
3. Then search will find your changes`);
|
|
2887
|
+
return parts.join("\n");
|
|
2888
|
+
}
|
|
2682
2889
|
function detectEditorFormat2(input) {
|
|
2683
2890
|
if (input.hookName !== void 0) {
|
|
2684
2891
|
return "cline";
|
|
@@ -2686,8 +2893,23 @@ function detectEditorFormat2(input) {
|
|
|
2686
2893
|
if (input.hook_event_name === "beforeSubmitPrompt") {
|
|
2687
2894
|
return "cursor";
|
|
2688
2895
|
}
|
|
2896
|
+
if (input.hook_event_name === "beforeAgentAction" || input.hook_event_name === "onPromptSubmit") {
|
|
2897
|
+
return "antigravity";
|
|
2898
|
+
}
|
|
2689
2899
|
return "claude";
|
|
2690
2900
|
}
|
|
2901
|
+
function isNewSession(input, editorFormat) {
|
|
2902
|
+
if (editorFormat === "claude" && input.session?.messages) {
|
|
2903
|
+
return input.session.messages.length <= 1;
|
|
2904
|
+
}
|
|
2905
|
+
if (editorFormat === "cursor" && input.history !== void 0) {
|
|
2906
|
+
return input.history.length === 0;
|
|
2907
|
+
}
|
|
2908
|
+
if (editorFormat === "antigravity" && input.history !== void 0) {
|
|
2909
|
+
return input.history.length === 0;
|
|
2910
|
+
}
|
|
2911
|
+
return false;
|
|
2912
|
+
}
|
|
2691
2913
|
async function runUserPromptSubmitHook() {
|
|
2692
2914
|
if (!ENABLED3) {
|
|
2693
2915
|
process.exit(0);
|
|
@@ -2706,6 +2928,7 @@ async function runUserPromptSubmitHook() {
|
|
|
2706
2928
|
process.exit(0);
|
|
2707
2929
|
}
|
|
2708
2930
|
const editorFormat = detectEditorFormat2(input);
|
|
2931
|
+
const cwd = input.cwd || process.cwd();
|
|
2709
2932
|
if (editorFormat === "claude") {
|
|
2710
2933
|
console.log(
|
|
2711
2934
|
JSON.stringify({
|
|
@@ -2716,37 +2939,84 @@ async function runUserPromptSubmitHook() {
|
|
|
2716
2939
|
})
|
|
2717
2940
|
);
|
|
2718
2941
|
} else if (editorFormat === "cline") {
|
|
2942
|
+
loadConfigFromMcpJson(cwd);
|
|
2943
|
+
const newSession = isNewSession(input, editorFormat);
|
|
2944
|
+
const ctx = await fetchSessionContext();
|
|
2945
|
+
const enhancedReminder = buildEnhancedReminder(ctx, newSession);
|
|
2719
2946
|
console.log(
|
|
2720
2947
|
JSON.stringify({
|
|
2721
2948
|
cancel: false,
|
|
2722
|
-
contextModification:
|
|
2949
|
+
contextModification: enhancedReminder
|
|
2723
2950
|
})
|
|
2724
2951
|
);
|
|
2725
2952
|
} else if (editorFormat === "cursor") {
|
|
2953
|
+
loadConfigFromMcpJson(cwd);
|
|
2954
|
+
const newSession = isNewSession(input, editorFormat);
|
|
2955
|
+
const ctx = await fetchSessionContext();
|
|
2956
|
+
const cursorReminder = ctx?.lessons?.length ? `[CONTEXTSTREAM] \u26A0\uFE0F ${ctx.lessons.length} lessons from past mistakes. Use search(mode="hybrid") before Glob/Grep. Call context() first. After file edits: project(action="index") to re-index.` : `[CONTEXTSTREAM] Use search(mode="hybrid") before Glob/Grep/Read. Call context() first. After file edits: project(action="index") to re-index.`;
|
|
2726
2957
|
console.log(
|
|
2727
2958
|
JSON.stringify({
|
|
2728
2959
|
continue: true,
|
|
2729
|
-
user_message:
|
|
2960
|
+
user_message: cursorReminder
|
|
2961
|
+
})
|
|
2962
|
+
);
|
|
2963
|
+
} else if (editorFormat === "antigravity") {
|
|
2964
|
+
loadConfigFromMcpJson(cwd);
|
|
2965
|
+
const newSession = isNewSession(input, editorFormat);
|
|
2966
|
+
const ctx = await fetchSessionContext();
|
|
2967
|
+
const enhancedReminder = buildEnhancedReminder(ctx, newSession);
|
|
2968
|
+
console.log(
|
|
2969
|
+
JSON.stringify({
|
|
2970
|
+
cancel: false,
|
|
2971
|
+
contextModification: enhancedReminder
|
|
2730
2972
|
})
|
|
2731
2973
|
);
|
|
2732
2974
|
}
|
|
2733
2975
|
process.exit(0);
|
|
2734
2976
|
}
|
|
2735
|
-
var ENABLED3, REMINDER, isDirectRun3;
|
|
2977
|
+
var ENABLED3, API_URL2, API_KEY2, WORKSPACE_ID, PROJECT_ID, REMINDER, ENHANCED_REMINDER_HEADER, isDirectRun3;
|
|
2736
2978
|
var init_user_prompt_submit = __esm({
|
|
2737
2979
|
"src/hooks/user-prompt-submit.ts"() {
|
|
2738
2980
|
"use strict";
|
|
2739
2981
|
ENABLED3 = process.env.CONTEXTSTREAM_REMINDER_ENABLED !== "false";
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2982
|
+
API_URL2 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
2983
|
+
API_KEY2 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
2984
|
+
WORKSPACE_ID = null;
|
|
2985
|
+
PROJECT_ID = null;
|
|
2986
|
+
REMINDER = `[CONTEXTSTREAM RULES - MANDATORY]
|
|
2987
|
+
|
|
2988
|
+
1. FIRST: Call mcp__contextstream__context(user_message="...") before ANY other tool
|
|
2989
|
+
- Returns: dynamic rules, lessons from past mistakes, relevant context
|
|
2990
|
+
- Check response for: [LESSONS_WARNING], [RULES_NOTICE], preferences
|
|
2991
|
+
|
|
2992
|
+
2. FOR CODE SEARCH: Check index status, then search appropriately
|
|
2993
|
+
\u26A0\uFE0F BEFORE searching: mcp__contextstream__project(action="index_status")
|
|
2994
|
+
\u2705 IF indexed & fresh: Use mcp__contextstream__search(mode="hybrid", query="...")
|
|
2995
|
+
\u2705 IF NOT indexed OR stale: Use local tools (Glob/Grep/Read) directly
|
|
2996
|
+
\u2705 IF search returns 0 results: Fallback to local tools (Glob/Grep/Read)
|
|
2997
|
+
|
|
2998
|
+
3. WHEN LOCAL TOOLS (Glob/Grep/Read) ARE OK:
|
|
2999
|
+
\u2705 Project is NOT indexed (index_status.indexed=false)
|
|
3000
|
+
\u2705 Index is stale/outdated (>7 days old)
|
|
3001
|
+
\u2705 ContextStream search returns 0 results or errors
|
|
3002
|
+
\u2705 User explicitly requests local tools
|
|
3003
|
+
|
|
3004
|
+
4. FOR PLANS & TASKS: Use ContextStream, not file-based plans
|
|
3005
|
+
\u2705 Plans: mcp__contextstream__session(action="capture_plan", ...)
|
|
3006
|
+
\u2705 Tasks: mcp__contextstream__memory(action="create_task", ...)
|
|
3007
|
+
\u274C DO NOT use EnterPlanMode or write plans to markdown files
|
|
3008
|
+
|
|
3009
|
+
5. CHECK THESE from context() response:
|
|
3010
|
+
- Lessons: Past mistakes to avoid (shown as warnings)
|
|
3011
|
+
- Reminders: Active reminders for this project
|
|
3012
|
+
- Preferences: User's coding style and preferences
|
|
3013
|
+
- Rules: Dynamic rules matched to current task
|
|
3014
|
+
|
|
3015
|
+
6. SKIP CONTEXTSTREAM: If user preference says "skip contextstream", use local tools instead
|
|
2749
3016
|
[END]`;
|
|
3017
|
+
ENHANCED_REMINDER_HEADER = `[CONTEXTSTREAM - ENHANCED CONTEXT]
|
|
3018
|
+
|
|
3019
|
+
`;
|
|
2750
3020
|
isDirectRun3 = process.argv[1]?.includes("user-prompt-submit") || process.argv[2] === "user-prompt-submit";
|
|
2751
3021
|
if (isDirectRun3) {
|
|
2752
3022
|
runUserPromptSubmitHook().catch(() => process.exit(0));
|
|
@@ -2868,58 +3138,58 @@ var pre_compact_exports = {};
|
|
|
2868
3138
|
__export(pre_compact_exports, {
|
|
2869
3139
|
runPreCompactHook: () => runPreCompactHook
|
|
2870
3140
|
});
|
|
2871
|
-
import * as
|
|
2872
|
-
import * as
|
|
2873
|
-
import { homedir as
|
|
2874
|
-
function
|
|
2875
|
-
let searchDir =
|
|
3141
|
+
import * as fs11 from "node:fs";
|
|
3142
|
+
import * as path12 from "node:path";
|
|
3143
|
+
import { homedir as homedir9 } from "node:os";
|
|
3144
|
+
function loadConfigFromMcpJson2(cwd) {
|
|
3145
|
+
let searchDir = path12.resolve(cwd);
|
|
2876
3146
|
for (let i = 0; i < 5; i++) {
|
|
2877
|
-
if (!
|
|
2878
|
-
const mcpPath =
|
|
2879
|
-
if (
|
|
3147
|
+
if (!API_KEY3) {
|
|
3148
|
+
const mcpPath = path12.join(searchDir, ".mcp.json");
|
|
3149
|
+
if (fs11.existsSync(mcpPath)) {
|
|
2880
3150
|
try {
|
|
2881
|
-
const content =
|
|
3151
|
+
const content = fs11.readFileSync(mcpPath, "utf-8");
|
|
2882
3152
|
const config = JSON.parse(content);
|
|
2883
3153
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
2884
3154
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
2885
|
-
|
|
3155
|
+
API_KEY3 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
2886
3156
|
}
|
|
2887
3157
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
2888
|
-
|
|
3158
|
+
API_URL3 = csEnv.CONTEXTSTREAM_API_URL;
|
|
2889
3159
|
}
|
|
2890
3160
|
} catch {
|
|
2891
3161
|
}
|
|
2892
3162
|
}
|
|
2893
3163
|
}
|
|
2894
|
-
if (!
|
|
2895
|
-
const csConfigPath =
|
|
2896
|
-
if (
|
|
3164
|
+
if (!WORKSPACE_ID2) {
|
|
3165
|
+
const csConfigPath = path12.join(searchDir, ".contextstream", "config.json");
|
|
3166
|
+
if (fs11.existsSync(csConfigPath)) {
|
|
2897
3167
|
try {
|
|
2898
|
-
const content =
|
|
3168
|
+
const content = fs11.readFileSync(csConfigPath, "utf-8");
|
|
2899
3169
|
const csConfig = JSON.parse(content);
|
|
2900
3170
|
if (csConfig.workspace_id) {
|
|
2901
|
-
|
|
3171
|
+
WORKSPACE_ID2 = csConfig.workspace_id;
|
|
2902
3172
|
}
|
|
2903
3173
|
} catch {
|
|
2904
3174
|
}
|
|
2905
3175
|
}
|
|
2906
3176
|
}
|
|
2907
|
-
const parentDir =
|
|
3177
|
+
const parentDir = path12.dirname(searchDir);
|
|
2908
3178
|
if (parentDir === searchDir) break;
|
|
2909
3179
|
searchDir = parentDir;
|
|
2910
3180
|
}
|
|
2911
|
-
if (!
|
|
2912
|
-
const homeMcpPath =
|
|
2913
|
-
if (
|
|
3181
|
+
if (!API_KEY3) {
|
|
3182
|
+
const homeMcpPath = path12.join(homedir9(), ".mcp.json");
|
|
3183
|
+
if (fs11.existsSync(homeMcpPath)) {
|
|
2914
3184
|
try {
|
|
2915
|
-
const content =
|
|
3185
|
+
const content = fs11.readFileSync(homeMcpPath, "utf-8");
|
|
2916
3186
|
const config = JSON.parse(content);
|
|
2917
3187
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
2918
3188
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
2919
|
-
|
|
3189
|
+
API_KEY3 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
2920
3190
|
}
|
|
2921
3191
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
2922
|
-
|
|
3192
|
+
API_URL3 = csEnv.CONTEXTSTREAM_API_URL;
|
|
2923
3193
|
}
|
|
2924
3194
|
} catch {
|
|
2925
3195
|
}
|
|
@@ -2934,7 +3204,7 @@ function parseTranscript(transcriptPath) {
|
|
|
2934
3204
|
let startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
2935
3205
|
let firstTimestamp = true;
|
|
2936
3206
|
try {
|
|
2937
|
-
const content =
|
|
3207
|
+
const content = fs11.readFileSync(transcriptPath, "utf-8");
|
|
2938
3208
|
const lines = content.split("\n");
|
|
2939
3209
|
for (const line of lines) {
|
|
2940
3210
|
if (!line.trim()) continue;
|
|
@@ -3015,7 +3285,7 @@ function parseTranscript(transcriptPath) {
|
|
|
3015
3285
|
};
|
|
3016
3286
|
}
|
|
3017
3287
|
async function saveFullTranscript(sessionId, transcriptData, trigger) {
|
|
3018
|
-
if (!
|
|
3288
|
+
if (!API_KEY3) {
|
|
3019
3289
|
return { success: false, message: "No API key configured" };
|
|
3020
3290
|
}
|
|
3021
3291
|
if (transcriptData.messages.length === 0) {
|
|
@@ -3034,17 +3304,17 @@ async function saveFullTranscript(sessionId, transcriptData, trigger) {
|
|
|
3034
3304
|
},
|
|
3035
3305
|
tags: ["pre_compaction", trigger]
|
|
3036
3306
|
};
|
|
3037
|
-
if (
|
|
3038
|
-
payload.workspace_id =
|
|
3307
|
+
if (WORKSPACE_ID2) {
|
|
3308
|
+
payload.workspace_id = WORKSPACE_ID2;
|
|
3039
3309
|
}
|
|
3040
3310
|
try {
|
|
3041
3311
|
const controller = new AbortController();
|
|
3042
3312
|
const timeoutId = setTimeout(() => controller.abort(), 1e4);
|
|
3043
|
-
const response = await fetch(`${
|
|
3313
|
+
const response = await fetch(`${API_URL3}/api/v1/transcripts`, {
|
|
3044
3314
|
method: "POST",
|
|
3045
3315
|
headers: {
|
|
3046
3316
|
"Content-Type": "application/json",
|
|
3047
|
-
"X-API-Key":
|
|
3317
|
+
"X-API-Key": API_KEY3
|
|
3048
3318
|
},
|
|
3049
3319
|
body: JSON.stringify(payload),
|
|
3050
3320
|
signal: controller.signal
|
|
@@ -3059,7 +3329,7 @@ async function saveFullTranscript(sessionId, transcriptData, trigger) {
|
|
|
3059
3329
|
}
|
|
3060
3330
|
}
|
|
3061
3331
|
async function saveSnapshot(sessionId, transcriptData, trigger) {
|
|
3062
|
-
if (!
|
|
3332
|
+
if (!API_KEY3) {
|
|
3063
3333
|
return { success: false, message: "No API key configured" };
|
|
3064
3334
|
}
|
|
3065
3335
|
const snapshotContent = {
|
|
@@ -3080,17 +3350,17 @@ async function saveSnapshot(sessionId, transcriptData, trigger) {
|
|
|
3080
3350
|
tags: ["session_snapshot", "pre_compaction", "auto_captured"],
|
|
3081
3351
|
source_type: "hook"
|
|
3082
3352
|
};
|
|
3083
|
-
if (
|
|
3084
|
-
payload.workspace_id =
|
|
3353
|
+
if (WORKSPACE_ID2) {
|
|
3354
|
+
payload.workspace_id = WORKSPACE_ID2;
|
|
3085
3355
|
}
|
|
3086
3356
|
try {
|
|
3087
3357
|
const controller = new AbortController();
|
|
3088
3358
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
3089
|
-
const response = await fetch(`${
|
|
3359
|
+
const response = await fetch(`${API_URL3}/api/v1/memory/events`, {
|
|
3090
3360
|
method: "POST",
|
|
3091
3361
|
headers: {
|
|
3092
3362
|
"Content-Type": "application/json",
|
|
3093
|
-
"X-API-Key":
|
|
3363
|
+
"X-API-Key": API_KEY3
|
|
3094
3364
|
},
|
|
3095
3365
|
body: JSON.stringify(payload),
|
|
3096
3366
|
signal: controller.signal
|
|
@@ -3122,7 +3392,7 @@ async function runPreCompactHook() {
|
|
|
3122
3392
|
process.exit(0);
|
|
3123
3393
|
}
|
|
3124
3394
|
const cwd = input.cwd || process.cwd();
|
|
3125
|
-
|
|
3395
|
+
loadConfigFromMcpJson2(cwd);
|
|
3126
3396
|
const sessionId = input.session_id || "unknown";
|
|
3127
3397
|
const transcriptPath = input.transcript_path || "";
|
|
3128
3398
|
const trigger = input.trigger || "unknown";
|
|
@@ -3131,13 +3401,15 @@ async function runPreCompactHook() {
|
|
|
3131
3401
|
activeFiles: [],
|
|
3132
3402
|
toolCallCount: 0,
|
|
3133
3403
|
messageCount: 0,
|
|
3134
|
-
lastTools: []
|
|
3404
|
+
lastTools: [],
|
|
3405
|
+
messages: [],
|
|
3406
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3135
3407
|
};
|
|
3136
|
-
if (transcriptPath &&
|
|
3408
|
+
if (transcriptPath && fs11.existsSync(transcriptPath)) {
|
|
3137
3409
|
transcriptData = parseTranscript(transcriptPath);
|
|
3138
3410
|
}
|
|
3139
3411
|
let autoSaveStatus = "";
|
|
3140
|
-
if (AUTO_SAVE &&
|
|
3412
|
+
if (AUTO_SAVE && API_KEY3) {
|
|
3141
3413
|
const transcriptResult = await saveFullTranscript(sessionId, transcriptData, trigger);
|
|
3142
3414
|
if (transcriptResult.success) {
|
|
3143
3415
|
autoSaveStatus = `
|
|
@@ -3171,15 +3443,15 @@ User instructions: ${customInstructions}` : ""}`;
|
|
|
3171
3443
|
);
|
|
3172
3444
|
process.exit(0);
|
|
3173
3445
|
}
|
|
3174
|
-
var ENABLED5, AUTO_SAVE,
|
|
3446
|
+
var ENABLED5, AUTO_SAVE, API_URL3, API_KEY3, WORKSPACE_ID2, isDirectRun5;
|
|
3175
3447
|
var init_pre_compact = __esm({
|
|
3176
3448
|
"src/hooks/pre-compact.ts"() {
|
|
3177
3449
|
"use strict";
|
|
3178
3450
|
ENABLED5 = process.env.CONTEXTSTREAM_PRECOMPACT_ENABLED !== "false";
|
|
3179
3451
|
AUTO_SAVE = process.env.CONTEXTSTREAM_PRECOMPACT_AUTO_SAVE !== "false";
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3452
|
+
API_URL3 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
3453
|
+
API_KEY3 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
3454
|
+
WORKSPACE_ID2 = null;
|
|
3183
3455
|
isDirectRun5 = process.argv[1]?.includes("pre-compact") || process.argv[2] === "pre-compact";
|
|
3184
3456
|
if (isDirectRun5) {
|
|
3185
3457
|
runPreCompactHook().catch(() => process.exit(0));
|
|
@@ -3192,13 +3464,13 @@ var auto_rules_exports = {};
|
|
|
3192
3464
|
__export(auto_rules_exports, {
|
|
3193
3465
|
runAutoRulesHook: () => runAutoRulesHook
|
|
3194
3466
|
});
|
|
3195
|
-
import * as
|
|
3196
|
-
import * as
|
|
3197
|
-
import { homedir as
|
|
3467
|
+
import * as fs12 from "node:fs";
|
|
3468
|
+
import * as path13 from "node:path";
|
|
3469
|
+
import { homedir as homedir10 } from "node:os";
|
|
3198
3470
|
function hasRunRecently() {
|
|
3199
3471
|
try {
|
|
3200
|
-
if (!
|
|
3201
|
-
const stat2 =
|
|
3472
|
+
if (!fs12.existsSync(MARKER_FILE)) return false;
|
|
3473
|
+
const stat2 = fs12.statSync(MARKER_FILE);
|
|
3202
3474
|
const age = Date.now() - stat2.mtimeMs;
|
|
3203
3475
|
return age < COOLDOWN_MS;
|
|
3204
3476
|
} catch {
|
|
@@ -3207,11 +3479,11 @@ function hasRunRecently() {
|
|
|
3207
3479
|
}
|
|
3208
3480
|
function markAsRan() {
|
|
3209
3481
|
try {
|
|
3210
|
-
const dir =
|
|
3211
|
-
if (!
|
|
3212
|
-
|
|
3482
|
+
const dir = path13.dirname(MARKER_FILE);
|
|
3483
|
+
if (!fs12.existsSync(dir)) {
|
|
3484
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
3213
3485
|
}
|
|
3214
|
-
|
|
3486
|
+
fs12.writeFileSync(MARKER_FILE, (/* @__PURE__ */ new Date()).toISOString());
|
|
3215
3487
|
} catch {
|
|
3216
3488
|
}
|
|
3217
3489
|
}
|
|
@@ -3240,8 +3512,8 @@ function extractCwd3(input) {
|
|
|
3240
3512
|
}
|
|
3241
3513
|
function hasPythonHooks(settingsPath) {
|
|
3242
3514
|
try {
|
|
3243
|
-
if (!
|
|
3244
|
-
const content =
|
|
3515
|
+
if (!fs12.existsSync(settingsPath)) return false;
|
|
3516
|
+
const content = fs12.readFileSync(settingsPath, "utf-8");
|
|
3245
3517
|
const settings = JSON.parse(content);
|
|
3246
3518
|
const hooks = settings.hooks;
|
|
3247
3519
|
if (!hooks) return false;
|
|
@@ -3265,8 +3537,8 @@ function hasPythonHooks(settingsPath) {
|
|
|
3265
3537
|
}
|
|
3266
3538
|
}
|
|
3267
3539
|
function detectPythonHooks(cwd) {
|
|
3268
|
-
const globalSettingsPath =
|
|
3269
|
-
const projectSettingsPath =
|
|
3540
|
+
const globalSettingsPath = path13.join(homedir10(), ".claude", "settings.json");
|
|
3541
|
+
const projectSettingsPath = path13.join(cwd, ".claude", "settings.json");
|
|
3270
3542
|
return {
|
|
3271
3543
|
global: hasPythonHooks(globalSettingsPath),
|
|
3272
3544
|
project: hasPythonHooks(projectSettingsPath)
|
|
@@ -3324,14 +3596,14 @@ async function runAutoRulesHook() {
|
|
|
3324
3596
|
}
|
|
3325
3597
|
process.exit(0);
|
|
3326
3598
|
}
|
|
3327
|
-
var
|
|
3599
|
+
var API_URL4, API_KEY4, ENABLED6, MARKER_FILE, COOLDOWN_MS, isDirectRun6;
|
|
3328
3600
|
var init_auto_rules = __esm({
|
|
3329
3601
|
"src/hooks/auto-rules.ts"() {
|
|
3330
3602
|
"use strict";
|
|
3331
|
-
|
|
3332
|
-
|
|
3603
|
+
API_URL4 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
3604
|
+
API_KEY4 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
3333
3605
|
ENABLED6 = process.env.CONTEXTSTREAM_AUTO_RULES !== "false";
|
|
3334
|
-
MARKER_FILE =
|
|
3606
|
+
MARKER_FILE = path13.join(homedir10(), ".contextstream", ".auto-rules-ran");
|
|
3335
3607
|
COOLDOWN_MS = 4 * 60 * 60 * 1e3;
|
|
3336
3608
|
isDirectRun6 = process.argv[1]?.includes("auto-rules") || process.argv[2] === "auto-rules";
|
|
3337
3609
|
if (isDirectRun6) {
|
|
@@ -3345,58 +3617,58 @@ var post_compact_exports = {};
|
|
|
3345
3617
|
__export(post_compact_exports, {
|
|
3346
3618
|
runPostCompactHook: () => runPostCompactHook
|
|
3347
3619
|
});
|
|
3348
|
-
import * as
|
|
3349
|
-
import * as
|
|
3350
|
-
import { homedir as
|
|
3351
|
-
function
|
|
3352
|
-
let searchDir =
|
|
3620
|
+
import * as fs13 from "node:fs";
|
|
3621
|
+
import * as path14 from "node:path";
|
|
3622
|
+
import { homedir as homedir11 } from "node:os";
|
|
3623
|
+
function loadConfigFromMcpJson3(cwd) {
|
|
3624
|
+
let searchDir = path14.resolve(cwd);
|
|
3353
3625
|
for (let i = 0; i < 5; i++) {
|
|
3354
|
-
if (!
|
|
3355
|
-
const mcpPath =
|
|
3356
|
-
if (
|
|
3626
|
+
if (!API_KEY5) {
|
|
3627
|
+
const mcpPath = path14.join(searchDir, ".mcp.json");
|
|
3628
|
+
if (fs13.existsSync(mcpPath)) {
|
|
3357
3629
|
try {
|
|
3358
|
-
const content =
|
|
3630
|
+
const content = fs13.readFileSync(mcpPath, "utf-8");
|
|
3359
3631
|
const config = JSON.parse(content);
|
|
3360
3632
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3361
3633
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3362
|
-
|
|
3634
|
+
API_KEY5 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3363
3635
|
}
|
|
3364
3636
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3365
|
-
|
|
3637
|
+
API_URL5 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3366
3638
|
}
|
|
3367
3639
|
} catch {
|
|
3368
3640
|
}
|
|
3369
3641
|
}
|
|
3370
3642
|
}
|
|
3371
|
-
if (!
|
|
3372
|
-
const csConfigPath =
|
|
3373
|
-
if (
|
|
3643
|
+
if (!WORKSPACE_ID3) {
|
|
3644
|
+
const csConfigPath = path14.join(searchDir, ".contextstream", "config.json");
|
|
3645
|
+
if (fs13.existsSync(csConfigPath)) {
|
|
3374
3646
|
try {
|
|
3375
|
-
const content =
|
|
3647
|
+
const content = fs13.readFileSync(csConfigPath, "utf-8");
|
|
3376
3648
|
const csConfig = JSON.parse(content);
|
|
3377
3649
|
if (csConfig.workspace_id) {
|
|
3378
|
-
|
|
3650
|
+
WORKSPACE_ID3 = csConfig.workspace_id;
|
|
3379
3651
|
}
|
|
3380
3652
|
} catch {
|
|
3381
3653
|
}
|
|
3382
3654
|
}
|
|
3383
3655
|
}
|
|
3384
|
-
const parentDir =
|
|
3656
|
+
const parentDir = path14.dirname(searchDir);
|
|
3385
3657
|
if (parentDir === searchDir) break;
|
|
3386
3658
|
searchDir = parentDir;
|
|
3387
3659
|
}
|
|
3388
|
-
if (!
|
|
3389
|
-
const homeMcpPath =
|
|
3390
|
-
if (
|
|
3660
|
+
if (!API_KEY5) {
|
|
3661
|
+
const homeMcpPath = path14.join(homedir11(), ".mcp.json");
|
|
3662
|
+
if (fs13.existsSync(homeMcpPath)) {
|
|
3391
3663
|
try {
|
|
3392
|
-
const content =
|
|
3664
|
+
const content = fs13.readFileSync(homeMcpPath, "utf-8");
|
|
3393
3665
|
const config = JSON.parse(content);
|
|
3394
3666
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3395
3667
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3396
|
-
|
|
3668
|
+
API_KEY5 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3397
3669
|
}
|
|
3398
3670
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3399
|
-
|
|
3671
|
+
API_URL5 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3400
3672
|
}
|
|
3401
3673
|
} catch {
|
|
3402
3674
|
}
|
|
@@ -3404,23 +3676,23 @@ function loadConfigFromMcpJson2(cwd) {
|
|
|
3404
3676
|
}
|
|
3405
3677
|
}
|
|
3406
3678
|
async function fetchLastTranscript(sessionId) {
|
|
3407
|
-
if (!
|
|
3679
|
+
if (!API_KEY5) {
|
|
3408
3680
|
return null;
|
|
3409
3681
|
}
|
|
3410
3682
|
try {
|
|
3411
3683
|
const controller = new AbortController();
|
|
3412
3684
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
3413
|
-
const url = new URL(`${
|
|
3685
|
+
const url = new URL(`${API_URL5}/api/v1/transcripts`);
|
|
3414
3686
|
url.searchParams.set("session_id", sessionId);
|
|
3415
3687
|
url.searchParams.set("limit", "1");
|
|
3416
3688
|
url.searchParams.set("sort", "created_at:desc");
|
|
3417
|
-
if (
|
|
3418
|
-
url.searchParams.set("workspace_id",
|
|
3689
|
+
if (WORKSPACE_ID3) {
|
|
3690
|
+
url.searchParams.set("workspace_id", WORKSPACE_ID3);
|
|
3419
3691
|
}
|
|
3420
3692
|
const response = await fetch(url.toString(), {
|
|
3421
3693
|
method: "GET",
|
|
3422
3694
|
headers: {
|
|
3423
|
-
"X-API-Key":
|
|
3695
|
+
"X-API-Key": API_KEY5
|
|
3424
3696
|
},
|
|
3425
3697
|
signal: controller.signal
|
|
3426
3698
|
});
|
|
@@ -3477,10 +3749,10 @@ async function runPostCompactHook() {
|
|
|
3477
3749
|
process.exit(0);
|
|
3478
3750
|
}
|
|
3479
3751
|
const cwd = input.cwd || process.cwd();
|
|
3480
|
-
|
|
3752
|
+
loadConfigFromMcpJson3(cwd);
|
|
3481
3753
|
const sessionId = input.session_id || "";
|
|
3482
3754
|
let restoredContext = "";
|
|
3483
|
-
if (sessionId &&
|
|
3755
|
+
if (sessionId && API_KEY5) {
|
|
3484
3756
|
const transcript = await fetchLastTranscript(sessionId);
|
|
3485
3757
|
if (transcript) {
|
|
3486
3758
|
restoredContext = formatTranscriptSummary(transcript);
|
|
@@ -3503,14 +3775,14 @@ The conversation was compacted to save memory. The above summary was automatical
|
|
|
3503
3775
|
);
|
|
3504
3776
|
process.exit(0);
|
|
3505
3777
|
}
|
|
3506
|
-
var ENABLED7,
|
|
3778
|
+
var ENABLED7, API_URL5, API_KEY5, WORKSPACE_ID3, isDirectRun7;
|
|
3507
3779
|
var init_post_compact = __esm({
|
|
3508
3780
|
"src/hooks/post-compact.ts"() {
|
|
3509
3781
|
"use strict";
|
|
3510
3782
|
ENABLED7 = process.env.CONTEXTSTREAM_POSTCOMPACT_ENABLED !== "false";
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3783
|
+
API_URL5 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
3784
|
+
API_KEY5 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
3785
|
+
WORKSPACE_ID3 = null;
|
|
3514
3786
|
isDirectRun7 = process.argv[1]?.includes("post-compact") || process.argv[2] === "post-compact";
|
|
3515
3787
|
if (isDirectRun7) {
|
|
3516
3788
|
runPostCompactHook().catch(() => process.exit(0));
|
|
@@ -3523,58 +3795,58 @@ var on_bash_exports = {};
|
|
|
3523
3795
|
__export(on_bash_exports, {
|
|
3524
3796
|
runOnBashHook: () => runOnBashHook
|
|
3525
3797
|
});
|
|
3526
|
-
import * as
|
|
3527
|
-
import * as
|
|
3528
|
-
import { homedir as
|
|
3529
|
-
function
|
|
3530
|
-
let searchDir =
|
|
3798
|
+
import * as fs14 from "node:fs";
|
|
3799
|
+
import * as path15 from "node:path";
|
|
3800
|
+
import { homedir as homedir12 } from "node:os";
|
|
3801
|
+
function loadConfigFromMcpJson4(cwd) {
|
|
3802
|
+
let searchDir = path15.resolve(cwd);
|
|
3531
3803
|
for (let i = 0; i < 5; i++) {
|
|
3532
|
-
if (!
|
|
3533
|
-
const mcpPath =
|
|
3534
|
-
if (
|
|
3804
|
+
if (!API_KEY6) {
|
|
3805
|
+
const mcpPath = path15.join(searchDir, ".mcp.json");
|
|
3806
|
+
if (fs14.existsSync(mcpPath)) {
|
|
3535
3807
|
try {
|
|
3536
|
-
const content =
|
|
3808
|
+
const content = fs14.readFileSync(mcpPath, "utf-8");
|
|
3537
3809
|
const config = JSON.parse(content);
|
|
3538
3810
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3539
3811
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3540
|
-
|
|
3812
|
+
API_KEY6 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3541
3813
|
}
|
|
3542
3814
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3543
|
-
|
|
3815
|
+
API_URL6 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3544
3816
|
}
|
|
3545
3817
|
} catch {
|
|
3546
3818
|
}
|
|
3547
3819
|
}
|
|
3548
3820
|
}
|
|
3549
|
-
if (!
|
|
3550
|
-
const csConfigPath =
|
|
3551
|
-
if (
|
|
3821
|
+
if (!WORKSPACE_ID4) {
|
|
3822
|
+
const csConfigPath = path15.join(searchDir, ".contextstream", "config.json");
|
|
3823
|
+
if (fs14.existsSync(csConfigPath)) {
|
|
3552
3824
|
try {
|
|
3553
|
-
const content =
|
|
3825
|
+
const content = fs14.readFileSync(csConfigPath, "utf-8");
|
|
3554
3826
|
const csConfig = JSON.parse(content);
|
|
3555
3827
|
if (csConfig.workspace_id) {
|
|
3556
|
-
|
|
3828
|
+
WORKSPACE_ID4 = csConfig.workspace_id;
|
|
3557
3829
|
}
|
|
3558
3830
|
} catch {
|
|
3559
3831
|
}
|
|
3560
3832
|
}
|
|
3561
3833
|
}
|
|
3562
|
-
const parentDir =
|
|
3834
|
+
const parentDir = path15.dirname(searchDir);
|
|
3563
3835
|
if (parentDir === searchDir) break;
|
|
3564
3836
|
searchDir = parentDir;
|
|
3565
3837
|
}
|
|
3566
|
-
if (!
|
|
3567
|
-
const homeMcpPath =
|
|
3568
|
-
if (
|
|
3838
|
+
if (!API_KEY6) {
|
|
3839
|
+
const homeMcpPath = path15.join(homedir12(), ".mcp.json");
|
|
3840
|
+
if (fs14.existsSync(homeMcpPath)) {
|
|
3569
3841
|
try {
|
|
3570
|
-
const content =
|
|
3842
|
+
const content = fs14.readFileSync(homeMcpPath, "utf-8");
|
|
3571
3843
|
const config = JSON.parse(content);
|
|
3572
3844
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3573
3845
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3574
|
-
|
|
3846
|
+
API_KEY6 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3575
3847
|
}
|
|
3576
3848
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3577
|
-
|
|
3849
|
+
API_URL6 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3578
3850
|
}
|
|
3579
3851
|
} catch {
|
|
3580
3852
|
}
|
|
@@ -3582,7 +3854,7 @@ function loadConfigFromMcpJson3(cwd) {
|
|
|
3582
3854
|
}
|
|
3583
3855
|
}
|
|
3584
3856
|
async function captureCommand(command, output, exitCode, isError, sessionId) {
|
|
3585
|
-
if (!
|
|
3857
|
+
if (!API_KEY6) return;
|
|
3586
3858
|
const payload = {
|
|
3587
3859
|
event_type: isError ? "bash_error" : "bash_command",
|
|
3588
3860
|
title: isError ? `Bash Error: ${command.slice(0, 50)}...` : `Command: ${command.slice(0, 50)}...`,
|
|
@@ -3597,17 +3869,17 @@ async function captureCommand(command, output, exitCode, isError, sessionId) {
|
|
|
3597
3869
|
source_type: "hook",
|
|
3598
3870
|
session_id: sessionId
|
|
3599
3871
|
};
|
|
3600
|
-
if (
|
|
3601
|
-
payload.workspace_id =
|
|
3872
|
+
if (WORKSPACE_ID4) {
|
|
3873
|
+
payload.workspace_id = WORKSPACE_ID4;
|
|
3602
3874
|
}
|
|
3603
3875
|
try {
|
|
3604
3876
|
const controller = new AbortController();
|
|
3605
3877
|
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
3606
|
-
await fetch(`${
|
|
3878
|
+
await fetch(`${API_URL6}/api/v1/memory/events`, {
|
|
3607
3879
|
method: "POST",
|
|
3608
3880
|
headers: {
|
|
3609
3881
|
"Content-Type": "application/json",
|
|
3610
|
-
"X-API-Key":
|
|
3882
|
+
"X-API-Key": API_KEY6
|
|
3611
3883
|
},
|
|
3612
3884
|
body: JSON.stringify(payload),
|
|
3613
3885
|
signal: controller.signal
|
|
@@ -3675,7 +3947,7 @@ async function runOnBashHook() {
|
|
|
3675
3947
|
process.exit(0);
|
|
3676
3948
|
}
|
|
3677
3949
|
const cwd = input.cwd || process.cwd();
|
|
3678
|
-
|
|
3950
|
+
loadConfigFromMcpJson4(cwd);
|
|
3679
3951
|
const command = input.tool_input?.command || "";
|
|
3680
3952
|
const output = input.tool_result?.output || input.tool_result?.error || "";
|
|
3681
3953
|
const exitCode = input.tool_result?.exit_code ?? 0;
|
|
@@ -3699,14 +3971,14 @@ async function runOnBashHook() {
|
|
|
3699
3971
|
}
|
|
3700
3972
|
process.exit(0);
|
|
3701
3973
|
}
|
|
3702
|
-
var ENABLED8,
|
|
3974
|
+
var ENABLED8, API_URL6, API_KEY6, WORKSPACE_ID4, isDirectRun8;
|
|
3703
3975
|
var init_on_bash = __esm({
|
|
3704
3976
|
"src/hooks/on-bash.ts"() {
|
|
3705
3977
|
"use strict";
|
|
3706
3978
|
ENABLED8 = process.env.CONTEXTSTREAM_BASH_HOOK_ENABLED !== "false";
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3979
|
+
API_URL6 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
3980
|
+
API_KEY6 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
3981
|
+
WORKSPACE_ID4 = null;
|
|
3710
3982
|
isDirectRun8 = process.argv[1]?.includes("on-bash") || process.argv[2] === "on-bash";
|
|
3711
3983
|
if (isDirectRun8) {
|
|
3712
3984
|
runOnBashHook().catch(() => process.exit(0));
|
|
@@ -3719,58 +3991,58 @@ var on_task_exports = {};
|
|
|
3719
3991
|
__export(on_task_exports, {
|
|
3720
3992
|
runOnTaskHook: () => runOnTaskHook
|
|
3721
3993
|
});
|
|
3722
|
-
import * as
|
|
3723
|
-
import * as
|
|
3724
|
-
import { homedir as
|
|
3725
|
-
function
|
|
3726
|
-
let searchDir =
|
|
3994
|
+
import * as fs15 from "node:fs";
|
|
3995
|
+
import * as path16 from "node:path";
|
|
3996
|
+
import { homedir as homedir13 } from "node:os";
|
|
3997
|
+
function loadConfigFromMcpJson5(cwd) {
|
|
3998
|
+
let searchDir = path16.resolve(cwd);
|
|
3727
3999
|
for (let i = 0; i < 5; i++) {
|
|
3728
|
-
if (!
|
|
3729
|
-
const mcpPath =
|
|
3730
|
-
if (
|
|
4000
|
+
if (!API_KEY7) {
|
|
4001
|
+
const mcpPath = path16.join(searchDir, ".mcp.json");
|
|
4002
|
+
if (fs15.existsSync(mcpPath)) {
|
|
3731
4003
|
try {
|
|
3732
|
-
const content =
|
|
4004
|
+
const content = fs15.readFileSync(mcpPath, "utf-8");
|
|
3733
4005
|
const config = JSON.parse(content);
|
|
3734
4006
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3735
4007
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3736
|
-
|
|
4008
|
+
API_KEY7 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3737
4009
|
}
|
|
3738
4010
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3739
|
-
|
|
4011
|
+
API_URL7 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3740
4012
|
}
|
|
3741
4013
|
} catch {
|
|
3742
4014
|
}
|
|
3743
4015
|
}
|
|
3744
4016
|
}
|
|
3745
|
-
if (!
|
|
3746
|
-
const csConfigPath =
|
|
3747
|
-
if (
|
|
4017
|
+
if (!WORKSPACE_ID5) {
|
|
4018
|
+
const csConfigPath = path16.join(searchDir, ".contextstream", "config.json");
|
|
4019
|
+
if (fs15.existsSync(csConfigPath)) {
|
|
3748
4020
|
try {
|
|
3749
|
-
const content =
|
|
4021
|
+
const content = fs15.readFileSync(csConfigPath, "utf-8");
|
|
3750
4022
|
const csConfig = JSON.parse(content);
|
|
3751
4023
|
if (csConfig.workspace_id) {
|
|
3752
|
-
|
|
4024
|
+
WORKSPACE_ID5 = csConfig.workspace_id;
|
|
3753
4025
|
}
|
|
3754
4026
|
} catch {
|
|
3755
4027
|
}
|
|
3756
4028
|
}
|
|
3757
4029
|
}
|
|
3758
|
-
const parentDir =
|
|
4030
|
+
const parentDir = path16.dirname(searchDir);
|
|
3759
4031
|
if (parentDir === searchDir) break;
|
|
3760
4032
|
searchDir = parentDir;
|
|
3761
4033
|
}
|
|
3762
|
-
if (!
|
|
3763
|
-
const homeMcpPath =
|
|
3764
|
-
if (
|
|
4034
|
+
if (!API_KEY7) {
|
|
4035
|
+
const homeMcpPath = path16.join(homedir13(), ".mcp.json");
|
|
4036
|
+
if (fs15.existsSync(homeMcpPath)) {
|
|
3765
4037
|
try {
|
|
3766
|
-
const content =
|
|
4038
|
+
const content = fs15.readFileSync(homeMcpPath, "utf-8");
|
|
3767
4039
|
const config = JSON.parse(content);
|
|
3768
4040
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3769
4041
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3770
|
-
|
|
4042
|
+
API_KEY7 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3771
4043
|
}
|
|
3772
4044
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3773
|
-
|
|
4045
|
+
API_URL7 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3774
4046
|
}
|
|
3775
4047
|
} catch {
|
|
3776
4048
|
}
|
|
@@ -3778,7 +4050,7 @@ function loadConfigFromMcpJson4(cwd) {
|
|
|
3778
4050
|
}
|
|
3779
4051
|
}
|
|
3780
4052
|
async function captureTaskInvocation(description, prompt, agentType, result, sessionId) {
|
|
3781
|
-
if (!
|
|
4053
|
+
if (!API_KEY7) return;
|
|
3782
4054
|
const payload = {
|
|
3783
4055
|
event_type: "task_agent",
|
|
3784
4056
|
title: `Agent: ${agentType} - ${description}`,
|
|
@@ -3794,17 +4066,17 @@ async function captureTaskInvocation(description, prompt, agentType, result, ses
|
|
|
3794
4066
|
source_type: "hook",
|
|
3795
4067
|
session_id: sessionId
|
|
3796
4068
|
};
|
|
3797
|
-
if (
|
|
3798
|
-
payload.workspace_id =
|
|
4069
|
+
if (WORKSPACE_ID5) {
|
|
4070
|
+
payload.workspace_id = WORKSPACE_ID5;
|
|
3799
4071
|
}
|
|
3800
4072
|
try {
|
|
3801
4073
|
const controller = new AbortController();
|
|
3802
4074
|
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
3803
|
-
await fetch(`${
|
|
4075
|
+
await fetch(`${API_URL7}/api/v1/memory/events`, {
|
|
3804
4076
|
method: "POST",
|
|
3805
4077
|
headers: {
|
|
3806
4078
|
"Content-Type": "application/json",
|
|
3807
|
-
"X-API-Key":
|
|
4079
|
+
"X-API-Key": API_KEY7
|
|
3808
4080
|
},
|
|
3809
4081
|
body: JSON.stringify(payload),
|
|
3810
4082
|
signal: controller.signal
|
|
@@ -3834,7 +4106,7 @@ async function runOnTaskHook() {
|
|
|
3834
4106
|
process.exit(0);
|
|
3835
4107
|
}
|
|
3836
4108
|
const cwd = input.cwd || process.cwd();
|
|
3837
|
-
|
|
4109
|
+
loadConfigFromMcpJson5(cwd);
|
|
3838
4110
|
const description = input.tool_input?.description || "Unknown task";
|
|
3839
4111
|
const prompt = input.tool_input?.prompt || "";
|
|
3840
4112
|
const agentType = input.tool_input?.subagent_type || "general-purpose";
|
|
@@ -3844,14 +4116,14 @@ async function runOnTaskHook() {
|
|
|
3844
4116
|
});
|
|
3845
4117
|
process.exit(0);
|
|
3846
4118
|
}
|
|
3847
|
-
var ENABLED9,
|
|
4119
|
+
var ENABLED9, API_URL7, API_KEY7, WORKSPACE_ID5, isDirectRun9;
|
|
3848
4120
|
var init_on_task = __esm({
|
|
3849
4121
|
"src/hooks/on-task.ts"() {
|
|
3850
4122
|
"use strict";
|
|
3851
4123
|
ENABLED9 = process.env.CONTEXTSTREAM_TASK_HOOK_ENABLED !== "false";
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
4124
|
+
API_URL7 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4125
|
+
API_KEY7 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4126
|
+
WORKSPACE_ID5 = null;
|
|
3855
4127
|
isDirectRun9 = process.argv[1]?.includes("on-task") || process.argv[2] === "on-task";
|
|
3856
4128
|
if (isDirectRun9) {
|
|
3857
4129
|
runOnTaskHook().catch(() => process.exit(0));
|
|
@@ -3864,58 +4136,58 @@ var on_read_exports = {};
|
|
|
3864
4136
|
__export(on_read_exports, {
|
|
3865
4137
|
runOnReadHook: () => runOnReadHook
|
|
3866
4138
|
});
|
|
3867
|
-
import * as
|
|
3868
|
-
import * as
|
|
3869
|
-
import { homedir as
|
|
3870
|
-
function
|
|
3871
|
-
let searchDir =
|
|
4139
|
+
import * as fs16 from "node:fs";
|
|
4140
|
+
import * as path17 from "node:path";
|
|
4141
|
+
import { homedir as homedir14 } from "node:os";
|
|
4142
|
+
function loadConfigFromMcpJson6(cwd) {
|
|
4143
|
+
let searchDir = path17.resolve(cwd);
|
|
3872
4144
|
for (let i = 0; i < 5; i++) {
|
|
3873
|
-
if (!
|
|
3874
|
-
const mcpPath =
|
|
3875
|
-
if (
|
|
4145
|
+
if (!API_KEY8) {
|
|
4146
|
+
const mcpPath = path17.join(searchDir, ".mcp.json");
|
|
4147
|
+
if (fs16.existsSync(mcpPath)) {
|
|
3876
4148
|
try {
|
|
3877
|
-
const content =
|
|
4149
|
+
const content = fs16.readFileSync(mcpPath, "utf-8");
|
|
3878
4150
|
const config = JSON.parse(content);
|
|
3879
4151
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3880
4152
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3881
|
-
|
|
4153
|
+
API_KEY8 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3882
4154
|
}
|
|
3883
4155
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3884
|
-
|
|
4156
|
+
API_URL8 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3885
4157
|
}
|
|
3886
4158
|
} catch {
|
|
3887
4159
|
}
|
|
3888
4160
|
}
|
|
3889
|
-
}
|
|
3890
|
-
if (!
|
|
3891
|
-
const csConfigPath =
|
|
3892
|
-
if (
|
|
4161
|
+
}
|
|
4162
|
+
if (!WORKSPACE_ID6) {
|
|
4163
|
+
const csConfigPath = path17.join(searchDir, ".contextstream", "config.json");
|
|
4164
|
+
if (fs16.existsSync(csConfigPath)) {
|
|
3893
4165
|
try {
|
|
3894
|
-
const content =
|
|
4166
|
+
const content = fs16.readFileSync(csConfigPath, "utf-8");
|
|
3895
4167
|
const csConfig = JSON.parse(content);
|
|
3896
4168
|
if (csConfig.workspace_id) {
|
|
3897
|
-
|
|
4169
|
+
WORKSPACE_ID6 = csConfig.workspace_id;
|
|
3898
4170
|
}
|
|
3899
4171
|
} catch {
|
|
3900
4172
|
}
|
|
3901
4173
|
}
|
|
3902
4174
|
}
|
|
3903
|
-
const parentDir =
|
|
4175
|
+
const parentDir = path17.dirname(searchDir);
|
|
3904
4176
|
if (parentDir === searchDir) break;
|
|
3905
4177
|
searchDir = parentDir;
|
|
3906
4178
|
}
|
|
3907
|
-
if (!
|
|
3908
|
-
const homeMcpPath =
|
|
3909
|
-
if (
|
|
4179
|
+
if (!API_KEY8) {
|
|
4180
|
+
const homeMcpPath = path17.join(homedir14(), ".mcp.json");
|
|
4181
|
+
if (fs16.existsSync(homeMcpPath)) {
|
|
3910
4182
|
try {
|
|
3911
|
-
const content =
|
|
4183
|
+
const content = fs16.readFileSync(homeMcpPath, "utf-8");
|
|
3912
4184
|
const config = JSON.parse(content);
|
|
3913
4185
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
3914
4186
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
3915
|
-
|
|
4187
|
+
API_KEY8 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
3916
4188
|
}
|
|
3917
4189
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
3918
|
-
|
|
4190
|
+
API_URL8 = csEnv.CONTEXTSTREAM_API_URL;
|
|
3919
4191
|
}
|
|
3920
4192
|
} catch {
|
|
3921
4193
|
}
|
|
@@ -3923,7 +4195,7 @@ function loadConfigFromMcpJson5(cwd) {
|
|
|
3923
4195
|
}
|
|
3924
4196
|
}
|
|
3925
4197
|
async function captureExploration(toolName, target, resultSummary, sessionId) {
|
|
3926
|
-
if (!
|
|
4198
|
+
if (!API_KEY8) return;
|
|
3927
4199
|
const cacheKey = `${toolName}:${target}`;
|
|
3928
4200
|
if (recentCaptures.has(cacheKey)) {
|
|
3929
4201
|
return;
|
|
@@ -3944,17 +4216,17 @@ async function captureExploration(toolName, target, resultSummary, sessionId) {
|
|
|
3944
4216
|
source_type: "hook",
|
|
3945
4217
|
session_id: sessionId
|
|
3946
4218
|
};
|
|
3947
|
-
if (
|
|
3948
|
-
payload.workspace_id =
|
|
4219
|
+
if (WORKSPACE_ID6) {
|
|
4220
|
+
payload.workspace_id = WORKSPACE_ID6;
|
|
3949
4221
|
}
|
|
3950
4222
|
try {
|
|
3951
4223
|
const controller = new AbortController();
|
|
3952
4224
|
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
3953
|
-
await fetch(`${
|
|
4225
|
+
await fetch(`${API_URL8}/api/v1/memory/events`, {
|
|
3954
4226
|
method: "POST",
|
|
3955
4227
|
headers: {
|
|
3956
4228
|
"Content-Type": "application/json",
|
|
3957
|
-
"X-API-Key":
|
|
4229
|
+
"X-API-Key": API_KEY8
|
|
3958
4230
|
},
|
|
3959
4231
|
body: JSON.stringify(payload),
|
|
3960
4232
|
signal: controller.signal
|
|
@@ -3985,7 +4257,7 @@ async function runOnReadHook() {
|
|
|
3985
4257
|
process.exit(0);
|
|
3986
4258
|
}
|
|
3987
4259
|
const cwd = input.cwd || process.cwd();
|
|
3988
|
-
|
|
4260
|
+
loadConfigFromMcpJson6(cwd);
|
|
3989
4261
|
const sessionId = input.session_id || "unknown";
|
|
3990
4262
|
let target = "";
|
|
3991
4263
|
let resultSummary = "";
|
|
@@ -4011,14 +4283,14 @@ async function runOnReadHook() {
|
|
|
4011
4283
|
}
|
|
4012
4284
|
process.exit(0);
|
|
4013
4285
|
}
|
|
4014
|
-
var ENABLED10,
|
|
4286
|
+
var ENABLED10, API_URL8, API_KEY8, WORKSPACE_ID6, recentCaptures, CAPTURE_WINDOW_MS, isDirectRun10;
|
|
4015
4287
|
var init_on_read = __esm({
|
|
4016
4288
|
"src/hooks/on-read.ts"() {
|
|
4017
4289
|
"use strict";
|
|
4018
4290
|
ENABLED10 = process.env.CONTEXTSTREAM_READ_HOOK_ENABLED !== "false";
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4291
|
+
API_URL8 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4292
|
+
API_KEY8 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4293
|
+
WORKSPACE_ID6 = null;
|
|
4022
4294
|
recentCaptures = /* @__PURE__ */ new Set();
|
|
4023
4295
|
CAPTURE_WINDOW_MS = 6e4;
|
|
4024
4296
|
isDirectRun10 = process.argv[1]?.includes("on-read") || process.argv[2] === "on-read";
|
|
@@ -4033,58 +4305,58 @@ var on_web_exports = {};
|
|
|
4033
4305
|
__export(on_web_exports, {
|
|
4034
4306
|
runOnWebHook: () => runOnWebHook
|
|
4035
4307
|
});
|
|
4036
|
-
import * as
|
|
4037
|
-
import * as
|
|
4038
|
-
import { homedir as
|
|
4039
|
-
function
|
|
4040
|
-
let searchDir =
|
|
4308
|
+
import * as fs17 from "node:fs";
|
|
4309
|
+
import * as path18 from "node:path";
|
|
4310
|
+
import { homedir as homedir15 } from "node:os";
|
|
4311
|
+
function loadConfigFromMcpJson7(cwd) {
|
|
4312
|
+
let searchDir = path18.resolve(cwd);
|
|
4041
4313
|
for (let i = 0; i < 5; i++) {
|
|
4042
|
-
if (!
|
|
4043
|
-
const mcpPath =
|
|
4044
|
-
if (
|
|
4314
|
+
if (!API_KEY9) {
|
|
4315
|
+
const mcpPath = path18.join(searchDir, ".mcp.json");
|
|
4316
|
+
if (fs17.existsSync(mcpPath)) {
|
|
4045
4317
|
try {
|
|
4046
|
-
const content =
|
|
4318
|
+
const content = fs17.readFileSync(mcpPath, "utf-8");
|
|
4047
4319
|
const config = JSON.parse(content);
|
|
4048
4320
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4049
4321
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4050
|
-
|
|
4322
|
+
API_KEY9 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4051
4323
|
}
|
|
4052
4324
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4053
|
-
|
|
4325
|
+
API_URL9 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4054
4326
|
}
|
|
4055
4327
|
} catch {
|
|
4056
4328
|
}
|
|
4057
4329
|
}
|
|
4058
4330
|
}
|
|
4059
|
-
if (!
|
|
4060
|
-
const csConfigPath =
|
|
4061
|
-
if (
|
|
4331
|
+
if (!WORKSPACE_ID7) {
|
|
4332
|
+
const csConfigPath = path18.join(searchDir, ".contextstream", "config.json");
|
|
4333
|
+
if (fs17.existsSync(csConfigPath)) {
|
|
4062
4334
|
try {
|
|
4063
|
-
const content =
|
|
4335
|
+
const content = fs17.readFileSync(csConfigPath, "utf-8");
|
|
4064
4336
|
const csConfig = JSON.parse(content);
|
|
4065
4337
|
if (csConfig.workspace_id) {
|
|
4066
|
-
|
|
4338
|
+
WORKSPACE_ID7 = csConfig.workspace_id;
|
|
4067
4339
|
}
|
|
4068
4340
|
} catch {
|
|
4069
4341
|
}
|
|
4070
4342
|
}
|
|
4071
4343
|
}
|
|
4072
|
-
const parentDir =
|
|
4344
|
+
const parentDir = path18.dirname(searchDir);
|
|
4073
4345
|
if (parentDir === searchDir) break;
|
|
4074
4346
|
searchDir = parentDir;
|
|
4075
4347
|
}
|
|
4076
|
-
if (!
|
|
4077
|
-
const homeMcpPath =
|
|
4078
|
-
if (
|
|
4348
|
+
if (!API_KEY9) {
|
|
4349
|
+
const homeMcpPath = path18.join(homedir15(), ".mcp.json");
|
|
4350
|
+
if (fs17.existsSync(homeMcpPath)) {
|
|
4079
4351
|
try {
|
|
4080
|
-
const content =
|
|
4352
|
+
const content = fs17.readFileSync(homeMcpPath, "utf-8");
|
|
4081
4353
|
const config = JSON.parse(content);
|
|
4082
4354
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4083
4355
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4084
|
-
|
|
4356
|
+
API_KEY9 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4085
4357
|
}
|
|
4086
4358
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4087
|
-
|
|
4359
|
+
API_URL9 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4088
4360
|
}
|
|
4089
4361
|
} catch {
|
|
4090
4362
|
}
|
|
@@ -4092,7 +4364,7 @@ function loadConfigFromMcpJson6(cwd) {
|
|
|
4092
4364
|
}
|
|
4093
4365
|
}
|
|
4094
4366
|
async function captureWebResearch(toolName, target, summary, sessionId) {
|
|
4095
|
-
if (!
|
|
4367
|
+
if (!API_KEY9) return;
|
|
4096
4368
|
const payload = {
|
|
4097
4369
|
event_type: "web_research",
|
|
4098
4370
|
title: `${toolName}: ${target.slice(0, 60)}`,
|
|
@@ -4107,17 +4379,17 @@ async function captureWebResearch(toolName, target, summary, sessionId) {
|
|
|
4107
4379
|
source_type: "hook",
|
|
4108
4380
|
session_id: sessionId
|
|
4109
4381
|
};
|
|
4110
|
-
if (
|
|
4111
|
-
payload.workspace_id =
|
|
4382
|
+
if (WORKSPACE_ID7) {
|
|
4383
|
+
payload.workspace_id = WORKSPACE_ID7;
|
|
4112
4384
|
}
|
|
4113
4385
|
try {
|
|
4114
4386
|
const controller = new AbortController();
|
|
4115
4387
|
const timeoutId = setTimeout(() => controller.abort(), 3e3);
|
|
4116
|
-
await fetch(`${
|
|
4388
|
+
await fetch(`${API_URL9}/api/v1/memory/events`, {
|
|
4117
4389
|
method: "POST",
|
|
4118
4390
|
headers: {
|
|
4119
4391
|
"Content-Type": "application/json",
|
|
4120
|
-
"X-API-Key":
|
|
4392
|
+
"X-API-Key": API_KEY9
|
|
4121
4393
|
},
|
|
4122
4394
|
body: JSON.stringify(payload),
|
|
4123
4395
|
signal: controller.signal
|
|
@@ -4148,7 +4420,7 @@ async function runOnWebHook() {
|
|
|
4148
4420
|
process.exit(0);
|
|
4149
4421
|
}
|
|
4150
4422
|
const cwd = input.cwd || process.cwd();
|
|
4151
|
-
|
|
4423
|
+
loadConfigFromMcpJson7(cwd);
|
|
4152
4424
|
const sessionId = input.session_id || "unknown";
|
|
4153
4425
|
let target = "";
|
|
4154
4426
|
let summary = "";
|
|
@@ -4174,14 +4446,14 @@ ${topResults}`;
|
|
|
4174
4446
|
}
|
|
4175
4447
|
process.exit(0);
|
|
4176
4448
|
}
|
|
4177
|
-
var ENABLED11,
|
|
4449
|
+
var ENABLED11, API_URL9, API_KEY9, WORKSPACE_ID7, isDirectRun11;
|
|
4178
4450
|
var init_on_web = __esm({
|
|
4179
4451
|
"src/hooks/on-web.ts"() {
|
|
4180
4452
|
"use strict";
|
|
4181
4453
|
ENABLED11 = process.env.CONTEXTSTREAM_WEB_HOOK_ENABLED !== "false";
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4454
|
+
API_URL9 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4455
|
+
API_KEY9 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4456
|
+
WORKSPACE_ID7 = null;
|
|
4185
4457
|
isDirectRun11 = process.argv[1]?.includes("on-web") || process.argv[2] === "on-web";
|
|
4186
4458
|
if (isDirectRun11) {
|
|
4187
4459
|
runOnWebHook().catch(() => process.exit(0));
|
|
@@ -4194,78 +4466,78 @@ var session_init_exports = {};
|
|
|
4194
4466
|
__export(session_init_exports, {
|
|
4195
4467
|
runSessionInitHook: () => runSessionInitHook
|
|
4196
4468
|
});
|
|
4197
|
-
import * as
|
|
4198
|
-
import * as
|
|
4199
|
-
import { homedir as
|
|
4200
|
-
function
|
|
4201
|
-
let searchDir =
|
|
4469
|
+
import * as fs18 from "node:fs";
|
|
4470
|
+
import * as path19 from "node:path";
|
|
4471
|
+
import { homedir as homedir16 } from "node:os";
|
|
4472
|
+
function loadConfigFromMcpJson8(cwd) {
|
|
4473
|
+
let searchDir = path19.resolve(cwd);
|
|
4202
4474
|
for (let i = 0; i < 5; i++) {
|
|
4203
|
-
if (!
|
|
4204
|
-
const mcpPath =
|
|
4205
|
-
if (
|
|
4475
|
+
if (!API_KEY10) {
|
|
4476
|
+
const mcpPath = path19.join(searchDir, ".mcp.json");
|
|
4477
|
+
if (fs18.existsSync(mcpPath)) {
|
|
4206
4478
|
try {
|
|
4207
|
-
const content =
|
|
4479
|
+
const content = fs18.readFileSync(mcpPath, "utf-8");
|
|
4208
4480
|
const config = JSON.parse(content);
|
|
4209
4481
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4210
4482
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4211
|
-
|
|
4483
|
+
API_KEY10 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4212
4484
|
}
|
|
4213
4485
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4214
|
-
|
|
4486
|
+
API_URL10 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4215
4487
|
}
|
|
4216
4488
|
if (csEnv?.CONTEXTSTREAM_WORKSPACE_ID) {
|
|
4217
|
-
|
|
4489
|
+
WORKSPACE_ID8 = csEnv.CONTEXTSTREAM_WORKSPACE_ID;
|
|
4218
4490
|
}
|
|
4219
4491
|
} catch {
|
|
4220
4492
|
}
|
|
4221
4493
|
}
|
|
4222
4494
|
}
|
|
4223
|
-
if (!
|
|
4224
|
-
const csConfigPath =
|
|
4225
|
-
if (
|
|
4495
|
+
if (!WORKSPACE_ID8 || !PROJECT_ID2) {
|
|
4496
|
+
const csConfigPath = path19.join(searchDir, ".contextstream", "config.json");
|
|
4497
|
+
if (fs18.existsSync(csConfigPath)) {
|
|
4226
4498
|
try {
|
|
4227
|
-
const content =
|
|
4499
|
+
const content = fs18.readFileSync(csConfigPath, "utf-8");
|
|
4228
4500
|
const csConfig = JSON.parse(content);
|
|
4229
|
-
if (csConfig.workspace_id && !
|
|
4230
|
-
|
|
4501
|
+
if (csConfig.workspace_id && !WORKSPACE_ID8) {
|
|
4502
|
+
WORKSPACE_ID8 = csConfig.workspace_id;
|
|
4231
4503
|
}
|
|
4232
|
-
if (csConfig.project_id && !
|
|
4233
|
-
|
|
4504
|
+
if (csConfig.project_id && !PROJECT_ID2) {
|
|
4505
|
+
PROJECT_ID2 = csConfig.project_id;
|
|
4234
4506
|
}
|
|
4235
4507
|
} catch {
|
|
4236
4508
|
}
|
|
4237
4509
|
}
|
|
4238
4510
|
}
|
|
4239
|
-
const parentDir =
|
|
4511
|
+
const parentDir = path19.dirname(searchDir);
|
|
4240
4512
|
if (parentDir === searchDir) break;
|
|
4241
4513
|
searchDir = parentDir;
|
|
4242
4514
|
}
|
|
4243
|
-
if (!
|
|
4244
|
-
const homeMcpPath =
|
|
4245
|
-
if (
|
|
4515
|
+
if (!API_KEY10) {
|
|
4516
|
+
const homeMcpPath = path19.join(homedir16(), ".mcp.json");
|
|
4517
|
+
if (fs18.existsSync(homeMcpPath)) {
|
|
4246
4518
|
try {
|
|
4247
|
-
const content =
|
|
4519
|
+
const content = fs18.readFileSync(homeMcpPath, "utf-8");
|
|
4248
4520
|
const config = JSON.parse(content);
|
|
4249
4521
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4250
4522
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4251
|
-
|
|
4523
|
+
API_KEY10 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4252
4524
|
}
|
|
4253
4525
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4254
|
-
|
|
4526
|
+
API_URL10 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4255
4527
|
}
|
|
4256
4528
|
} catch {
|
|
4257
4529
|
}
|
|
4258
4530
|
}
|
|
4259
4531
|
}
|
|
4260
4532
|
}
|
|
4261
|
-
async function
|
|
4262
|
-
if (!
|
|
4533
|
+
async function fetchSessionContext2() {
|
|
4534
|
+
if (!API_KEY10) return null;
|
|
4263
4535
|
try {
|
|
4264
4536
|
const controller = new AbortController();
|
|
4265
4537
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
4266
|
-
const url = new URL(`${
|
|
4267
|
-
if (
|
|
4268
|
-
if (
|
|
4538
|
+
const url = new URL(`${API_URL10}/api/v1/context`);
|
|
4539
|
+
if (WORKSPACE_ID8) url.searchParams.set("workspace_id", WORKSPACE_ID8);
|
|
4540
|
+
if (PROJECT_ID2) url.searchParams.set("project_id", PROJECT_ID2);
|
|
4269
4541
|
url.searchParams.set("include_rules", "true");
|
|
4270
4542
|
url.searchParams.set("include_lessons", "true");
|
|
4271
4543
|
url.searchParams.set("include_decisions", "true");
|
|
@@ -4274,7 +4546,7 @@ async function fetchSessionContext() {
|
|
|
4274
4546
|
const response = await fetch(url.toString(), {
|
|
4275
4547
|
method: "GET",
|
|
4276
4548
|
headers: {
|
|
4277
|
-
"X-API-Key":
|
|
4549
|
+
"X-API-Key": API_KEY10
|
|
4278
4550
|
},
|
|
4279
4551
|
signal: controller.signal
|
|
4280
4552
|
});
|
|
@@ -4340,8 +4612,8 @@ async function runSessionInitHook() {
|
|
|
4340
4612
|
process.exit(0);
|
|
4341
4613
|
}
|
|
4342
4614
|
const cwd = input.cwd || process.cwd();
|
|
4343
|
-
|
|
4344
|
-
const context = await
|
|
4615
|
+
loadConfigFromMcpJson8(cwd);
|
|
4616
|
+
const context = await fetchSessionContext2();
|
|
4345
4617
|
const formattedContext = formatContext(context);
|
|
4346
4618
|
console.log(
|
|
4347
4619
|
JSON.stringify({
|
|
@@ -4353,15 +4625,15 @@ async function runSessionInitHook() {
|
|
|
4353
4625
|
);
|
|
4354
4626
|
process.exit(0);
|
|
4355
4627
|
}
|
|
4356
|
-
var ENABLED12,
|
|
4628
|
+
var ENABLED12, API_URL10, API_KEY10, WORKSPACE_ID8, PROJECT_ID2, isDirectRun12;
|
|
4357
4629
|
var init_session_init = __esm({
|
|
4358
4630
|
"src/hooks/session-init.ts"() {
|
|
4359
4631
|
"use strict";
|
|
4360
4632
|
ENABLED12 = process.env.CONTEXTSTREAM_SESSION_INIT_ENABLED !== "false";
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4633
|
+
API_URL10 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4634
|
+
API_KEY10 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4635
|
+
WORKSPACE_ID8 = null;
|
|
4636
|
+
PROJECT_ID2 = null;
|
|
4365
4637
|
isDirectRun12 = process.argv[1]?.includes("session-init") || process.argv[2] === "session-init";
|
|
4366
4638
|
if (isDirectRun12) {
|
|
4367
4639
|
runSessionInitHook().catch(() => process.exit(0));
|
|
@@ -4374,58 +4646,58 @@ var session_end_exports = {};
|
|
|
4374
4646
|
__export(session_end_exports, {
|
|
4375
4647
|
runSessionEndHook: () => runSessionEndHook
|
|
4376
4648
|
});
|
|
4377
|
-
import * as
|
|
4378
|
-
import * as
|
|
4379
|
-
import { homedir as
|
|
4380
|
-
function
|
|
4381
|
-
let searchDir =
|
|
4649
|
+
import * as fs19 from "node:fs";
|
|
4650
|
+
import * as path20 from "node:path";
|
|
4651
|
+
import { homedir as homedir17 } from "node:os";
|
|
4652
|
+
function loadConfigFromMcpJson9(cwd) {
|
|
4653
|
+
let searchDir = path20.resolve(cwd);
|
|
4382
4654
|
for (let i = 0; i < 5; i++) {
|
|
4383
|
-
if (!
|
|
4384
|
-
const mcpPath =
|
|
4385
|
-
if (
|
|
4655
|
+
if (!API_KEY11) {
|
|
4656
|
+
const mcpPath = path20.join(searchDir, ".mcp.json");
|
|
4657
|
+
if (fs19.existsSync(mcpPath)) {
|
|
4386
4658
|
try {
|
|
4387
|
-
const content =
|
|
4659
|
+
const content = fs19.readFileSync(mcpPath, "utf-8");
|
|
4388
4660
|
const config = JSON.parse(content);
|
|
4389
4661
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4390
4662
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4391
|
-
|
|
4663
|
+
API_KEY11 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4392
4664
|
}
|
|
4393
4665
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4394
|
-
|
|
4666
|
+
API_URL11 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4395
4667
|
}
|
|
4396
4668
|
} catch {
|
|
4397
4669
|
}
|
|
4398
4670
|
}
|
|
4399
4671
|
}
|
|
4400
|
-
if (!
|
|
4401
|
-
const csConfigPath =
|
|
4402
|
-
if (
|
|
4672
|
+
if (!WORKSPACE_ID9) {
|
|
4673
|
+
const csConfigPath = path20.join(searchDir, ".contextstream", "config.json");
|
|
4674
|
+
if (fs19.existsSync(csConfigPath)) {
|
|
4403
4675
|
try {
|
|
4404
|
-
const content =
|
|
4676
|
+
const content = fs19.readFileSync(csConfigPath, "utf-8");
|
|
4405
4677
|
const csConfig = JSON.parse(content);
|
|
4406
4678
|
if (csConfig.workspace_id) {
|
|
4407
|
-
|
|
4679
|
+
WORKSPACE_ID9 = csConfig.workspace_id;
|
|
4408
4680
|
}
|
|
4409
4681
|
} catch {
|
|
4410
4682
|
}
|
|
4411
4683
|
}
|
|
4412
4684
|
}
|
|
4413
|
-
const parentDir =
|
|
4685
|
+
const parentDir = path20.dirname(searchDir);
|
|
4414
4686
|
if (parentDir === searchDir) break;
|
|
4415
4687
|
searchDir = parentDir;
|
|
4416
4688
|
}
|
|
4417
|
-
if (!
|
|
4418
|
-
const homeMcpPath =
|
|
4419
|
-
if (
|
|
4689
|
+
if (!API_KEY11) {
|
|
4690
|
+
const homeMcpPath = path20.join(homedir17(), ".mcp.json");
|
|
4691
|
+
if (fs19.existsSync(homeMcpPath)) {
|
|
4420
4692
|
try {
|
|
4421
|
-
const content =
|
|
4693
|
+
const content = fs19.readFileSync(homeMcpPath, "utf-8");
|
|
4422
4694
|
const config = JSON.parse(content);
|
|
4423
4695
|
const csEnv = config.mcpServers?.contextstream?.env;
|
|
4424
4696
|
if (csEnv?.CONTEXTSTREAM_API_KEY) {
|
|
4425
|
-
|
|
4697
|
+
API_KEY11 = csEnv.CONTEXTSTREAM_API_KEY;
|
|
4426
4698
|
}
|
|
4427
4699
|
if (csEnv?.CONTEXTSTREAM_API_URL) {
|
|
4428
|
-
|
|
4700
|
+
API_URL11 = csEnv.CONTEXTSTREAM_API_URL;
|
|
4429
4701
|
}
|
|
4430
4702
|
} catch {
|
|
4431
4703
|
}
|
|
@@ -4439,11 +4711,11 @@ function parseTranscriptStats(transcriptPath) {
|
|
|
4439
4711
|
duration: 0,
|
|
4440
4712
|
filesModified: []
|
|
4441
4713
|
};
|
|
4442
|
-
if (!transcriptPath || !
|
|
4714
|
+
if (!transcriptPath || !fs19.existsSync(transcriptPath)) {
|
|
4443
4715
|
return stats;
|
|
4444
4716
|
}
|
|
4445
4717
|
try {
|
|
4446
|
-
const content =
|
|
4718
|
+
const content = fs19.readFileSync(transcriptPath, "utf-8");
|
|
4447
4719
|
const lines = content.split("\n");
|
|
4448
4720
|
let firstTimestamp = null;
|
|
4449
4721
|
let lastTimestamp = null;
|
|
@@ -4485,7 +4757,7 @@ function parseTranscriptStats(transcriptPath) {
|
|
|
4485
4757
|
return stats;
|
|
4486
4758
|
}
|
|
4487
4759
|
async function finalizeSession(sessionId, stats, reason) {
|
|
4488
|
-
if (!
|
|
4760
|
+
if (!API_KEY11) return;
|
|
4489
4761
|
const payload = {
|
|
4490
4762
|
event_type: "session_end",
|
|
4491
4763
|
title: `Session Ended: ${reason}`,
|
|
@@ -4506,17 +4778,17 @@ async function finalizeSession(sessionId, stats, reason) {
|
|
|
4506
4778
|
source_type: "hook",
|
|
4507
4779
|
session_id: sessionId
|
|
4508
4780
|
};
|
|
4509
|
-
if (
|
|
4510
|
-
payload.workspace_id =
|
|
4781
|
+
if (WORKSPACE_ID9) {
|
|
4782
|
+
payload.workspace_id = WORKSPACE_ID9;
|
|
4511
4783
|
}
|
|
4512
4784
|
try {
|
|
4513
4785
|
const controller = new AbortController();
|
|
4514
4786
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
4515
|
-
await fetch(`${
|
|
4787
|
+
await fetch(`${API_URL11}/api/v1/memory/events`, {
|
|
4516
4788
|
method: "POST",
|
|
4517
4789
|
headers: {
|
|
4518
4790
|
"Content-Type": "application/json",
|
|
4519
|
-
"X-API-Key":
|
|
4791
|
+
"X-API-Key": API_KEY11
|
|
4520
4792
|
},
|
|
4521
4793
|
body: JSON.stringify(payload),
|
|
4522
4794
|
signal: controller.signal
|
|
@@ -4543,7 +4815,7 @@ async function runSessionEndHook() {
|
|
|
4543
4815
|
process.exit(0);
|
|
4544
4816
|
}
|
|
4545
4817
|
const cwd = input.cwd || process.cwd();
|
|
4546
|
-
|
|
4818
|
+
loadConfigFromMcpJson9(cwd);
|
|
4547
4819
|
const sessionId = input.session_id || "unknown";
|
|
4548
4820
|
const transcriptPath = input.transcript_path || "";
|
|
4549
4821
|
const reason = input.reason || "user_exit";
|
|
@@ -4551,14 +4823,14 @@ async function runSessionEndHook() {
|
|
|
4551
4823
|
await finalizeSession(sessionId, stats, reason);
|
|
4552
4824
|
process.exit(0);
|
|
4553
4825
|
}
|
|
4554
|
-
var ENABLED13,
|
|
4826
|
+
var ENABLED13, API_URL11, API_KEY11, WORKSPACE_ID9, isDirectRun13;
|
|
4555
4827
|
var init_session_end = __esm({
|
|
4556
4828
|
"src/hooks/session-end.ts"() {
|
|
4557
4829
|
"use strict";
|
|
4558
4830
|
ENABLED13 = process.env.CONTEXTSTREAM_SESSION_END_ENABLED !== "false";
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4831
|
+
API_URL11 = process.env.CONTEXTSTREAM_API_URL || "https://api.contextstream.io";
|
|
4832
|
+
API_KEY11 = process.env.CONTEXTSTREAM_API_KEY || "";
|
|
4833
|
+
WORKSPACE_ID9 = null;
|
|
4562
4834
|
isDirectRun13 = process.argv[1]?.includes("session-end") || process.argv[2] === "session-end";
|
|
4563
4835
|
if (isDirectRun13) {
|
|
4564
4836
|
runSessionEndHook().catch(() => process.exit(0));
|
|
@@ -4712,9 +4984,9 @@ __export(verify_key_exports, {
|
|
|
4712
4984
|
runVerifyKey: () => runVerifyKey,
|
|
4713
4985
|
validateApiKey: () => validateApiKey
|
|
4714
4986
|
});
|
|
4715
|
-
import * as
|
|
4716
|
-
import * as
|
|
4717
|
-
import { homedir as
|
|
4987
|
+
import * as fs20 from "node:fs";
|
|
4988
|
+
import * as path21 from "node:path";
|
|
4989
|
+
import { homedir as homedir18 } from "node:os";
|
|
4718
4990
|
function maskApiKey2(key) {
|
|
4719
4991
|
if (!key || key.length < 10) return "***";
|
|
4720
4992
|
const prefix = key.slice(0, 6);
|
|
@@ -4746,11 +5018,11 @@ function extractFromMcpConfig(config) {
|
|
|
4746
5018
|
function getClaudeDesktopConfigPath() {
|
|
4747
5019
|
const platform = process.platform;
|
|
4748
5020
|
if (platform === "darwin") {
|
|
4749
|
-
return
|
|
5021
|
+
return path21.join(homedir18(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
4750
5022
|
} else if (platform === "win32") {
|
|
4751
|
-
return
|
|
5023
|
+
return path21.join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
|
|
4752
5024
|
} else {
|
|
4753
|
-
return
|
|
5025
|
+
return path21.join(homedir18(), ".config", "Claude", "claude_desktop_config.json");
|
|
4754
5026
|
}
|
|
4755
5027
|
}
|
|
4756
5028
|
function loadApiKey() {
|
|
@@ -4767,10 +5039,10 @@ function loadApiKey() {
|
|
|
4767
5039
|
}
|
|
4768
5040
|
let searchDir = process.cwd();
|
|
4769
5041
|
for (let i = 0; i < 5; i++) {
|
|
4770
|
-
const projectMcpPath =
|
|
4771
|
-
if (
|
|
5042
|
+
const projectMcpPath = path21.join(searchDir, ".mcp.json");
|
|
5043
|
+
if (fs20.existsSync(projectMcpPath)) {
|
|
4772
5044
|
try {
|
|
4773
|
-
const content =
|
|
5045
|
+
const content = fs20.readFileSync(projectMcpPath, "utf-8");
|
|
4774
5046
|
const config = JSON.parse(content);
|
|
4775
5047
|
const extracted = extractFromMcpConfig(config);
|
|
4776
5048
|
if (extracted.apiKey) {
|
|
@@ -4784,14 +5056,14 @@ function loadApiKey() {
|
|
|
4784
5056
|
} catch {
|
|
4785
5057
|
}
|
|
4786
5058
|
}
|
|
4787
|
-
const parentDir =
|
|
5059
|
+
const parentDir = path21.dirname(searchDir);
|
|
4788
5060
|
if (parentDir === searchDir) break;
|
|
4789
5061
|
searchDir = parentDir;
|
|
4790
5062
|
}
|
|
4791
|
-
const globalMcpPath =
|
|
4792
|
-
if (
|
|
5063
|
+
const globalMcpPath = path21.join(homedir18(), ".mcp.json");
|
|
5064
|
+
if (fs20.existsSync(globalMcpPath)) {
|
|
4793
5065
|
try {
|
|
4794
|
-
const content =
|
|
5066
|
+
const content = fs20.readFileSync(globalMcpPath, "utf-8");
|
|
4795
5067
|
const config = JSON.parse(content);
|
|
4796
5068
|
const extracted = extractFromMcpConfig(config);
|
|
4797
5069
|
if (extracted.apiKey) {
|
|
@@ -4806,13 +5078,13 @@ function loadApiKey() {
|
|
|
4806
5078
|
}
|
|
4807
5079
|
}
|
|
4808
5080
|
const cursorPaths = [
|
|
4809
|
-
|
|
4810
|
-
|
|
5081
|
+
path21.join(process.cwd(), ".cursor", "mcp.json"),
|
|
5082
|
+
path21.join(homedir18(), ".cursor", "mcp.json")
|
|
4811
5083
|
];
|
|
4812
5084
|
for (const cursorPath of cursorPaths) {
|
|
4813
|
-
if (
|
|
5085
|
+
if (fs20.existsSync(cursorPath)) {
|
|
4814
5086
|
try {
|
|
4815
|
-
const content =
|
|
5087
|
+
const content = fs20.readFileSync(cursorPath, "utf-8");
|
|
4816
5088
|
const config = JSON.parse(content);
|
|
4817
5089
|
const extracted = extractFromMcpConfig(config);
|
|
4818
5090
|
if (extracted.apiKey) {
|
|
@@ -4828,9 +5100,9 @@ function loadApiKey() {
|
|
|
4828
5100
|
}
|
|
4829
5101
|
}
|
|
4830
5102
|
const claudeDesktopPath = getClaudeDesktopConfigPath();
|
|
4831
|
-
if (
|
|
5103
|
+
if (fs20.existsSync(claudeDesktopPath)) {
|
|
4832
5104
|
try {
|
|
4833
|
-
const content =
|
|
5105
|
+
const content = fs20.readFileSync(claudeDesktopPath, "utf-8");
|
|
4834
5106
|
const config = JSON.parse(content);
|
|
4835
5107
|
const extracted = extractFromMcpConfig(config);
|
|
4836
5108
|
if (extracted.apiKey) {
|
|
@@ -4845,14 +5117,14 @@ function loadApiKey() {
|
|
|
4845
5117
|
}
|
|
4846
5118
|
}
|
|
4847
5119
|
const vscodePaths = [
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
5120
|
+
path21.join(homedir18(), ".vscode", "mcp.json"),
|
|
5121
|
+
path21.join(homedir18(), ".codeium", "windsurf", "mcp_config.json"),
|
|
5122
|
+
path21.join(homedir18(), ".continue", "config.json")
|
|
4851
5123
|
];
|
|
4852
5124
|
for (const vsPath of vscodePaths) {
|
|
4853
|
-
if (
|
|
5125
|
+
if (fs20.existsSync(vsPath)) {
|
|
4854
5126
|
try {
|
|
4855
|
-
const content =
|
|
5127
|
+
const content = fs20.readFileSync(vsPath, "utf-8");
|
|
4856
5128
|
const config = JSON.parse(content);
|
|
4857
5129
|
const extracted = extractFromMcpConfig(config);
|
|
4858
5130
|
if (extracted.apiKey) {
|
|
@@ -4867,10 +5139,10 @@ function loadApiKey() {
|
|
|
4867
5139
|
}
|
|
4868
5140
|
}
|
|
4869
5141
|
}
|
|
4870
|
-
const credentialsPath =
|
|
4871
|
-
if (
|
|
5142
|
+
const credentialsPath = path21.join(homedir18(), ".contextstream", "credentials.json");
|
|
5143
|
+
if (fs20.existsSync(credentialsPath)) {
|
|
4872
5144
|
try {
|
|
4873
|
-
const content =
|
|
5145
|
+
const content = fs20.readFileSync(credentialsPath, "utf-8");
|
|
4874
5146
|
const creds = JSON.parse(content);
|
|
4875
5147
|
if (creds.api_key) {
|
|
4876
5148
|
apiKey = creds.api_key;
|
|
@@ -5465,8 +5737,8 @@ function getErrorMap() {
|
|
|
5465
5737
|
|
|
5466
5738
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
5467
5739
|
var makeIssue = (params) => {
|
|
5468
|
-
const { data, path:
|
|
5469
|
-
const fullPath = [...
|
|
5740
|
+
const { data, path: path22, errorMaps, issueData } = params;
|
|
5741
|
+
const fullPath = [...path22, ...issueData.path || []];
|
|
5470
5742
|
const fullIssue = {
|
|
5471
5743
|
...issueData,
|
|
5472
5744
|
path: fullPath
|
|
@@ -5582,11 +5854,11 @@ var errorUtil;
|
|
|
5582
5854
|
|
|
5583
5855
|
// node_modules/zod/v3/types.js
|
|
5584
5856
|
var ParseInputLazyPath = class {
|
|
5585
|
-
constructor(parent, value,
|
|
5857
|
+
constructor(parent, value, path22, key) {
|
|
5586
5858
|
this._cachedPath = [];
|
|
5587
5859
|
this.parent = parent;
|
|
5588
5860
|
this.data = value;
|
|
5589
|
-
this._path =
|
|
5861
|
+
this._path = path22;
|
|
5590
5862
|
this._key = key;
|
|
5591
5863
|
}
|
|
5592
5864
|
get path() {
|
|
@@ -9322,14 +9594,14 @@ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504])
|
|
|
9322
9594
|
var MAX_RETRIES = 3;
|
|
9323
9595
|
var BASE_DELAY = 1e3;
|
|
9324
9596
|
async function sleep(ms) {
|
|
9325
|
-
return new Promise((
|
|
9597
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
9326
9598
|
}
|
|
9327
|
-
async function request(config,
|
|
9599
|
+
async function request(config, path22, options = {}) {
|
|
9328
9600
|
const { apiUrl, userAgent } = config;
|
|
9329
9601
|
const authOverride = getAuthOverride();
|
|
9330
9602
|
const apiKey = authOverride?.apiKey ?? config.apiKey;
|
|
9331
9603
|
const jwt = authOverride?.jwt ?? config.jwt;
|
|
9332
|
-
const apiPath =
|
|
9604
|
+
const apiPath = path22.startsWith("/api/") ? path22 : `/api/v1${path22}`;
|
|
9333
9605
|
const url = `${apiUrl.replace(/\/$/, "")}${apiPath}`;
|
|
9334
9606
|
const maxRetries = options.retries ?? MAX_RETRIES;
|
|
9335
9607
|
const baseDelay = options.retryDelay ?? BASE_DELAY;
|
|
@@ -9475,9 +9747,9 @@ function extractErrorCode(payload) {
|
|
|
9475
9747
|
if (typeof payload.code === "string" && payload.code.trim()) return payload.code.trim();
|
|
9476
9748
|
return null;
|
|
9477
9749
|
}
|
|
9478
|
-
function detectIntegrationProvider(
|
|
9479
|
-
if (/\/github(\/|$)/i.test(
|
|
9480
|
-
if (/\/slack(\/|$)/i.test(
|
|
9750
|
+
function detectIntegrationProvider(path22) {
|
|
9751
|
+
if (/\/github(\/|$)/i.test(path22)) return "github";
|
|
9752
|
+
if (/\/slack(\/|$)/i.test(path22)) return "slack";
|
|
9481
9753
|
return null;
|
|
9482
9754
|
}
|
|
9483
9755
|
function rewriteNotFoundMessage(input) {
|
|
@@ -10130,10 +10402,10 @@ var PROJECT_MARKERS = [
|
|
|
10130
10402
|
];
|
|
10131
10403
|
function isMultiProjectFolder(folderPath) {
|
|
10132
10404
|
try {
|
|
10133
|
-
const
|
|
10405
|
+
const fs21 = __require("fs");
|
|
10134
10406
|
const pathModule = __require("path");
|
|
10135
|
-
const rootHasGit =
|
|
10136
|
-
const entries =
|
|
10407
|
+
const rootHasGit = fs21.existsSync(pathModule.join(folderPath, ".git"));
|
|
10408
|
+
const entries = fs21.readdirSync(folderPath, { withFileTypes: true });
|
|
10137
10409
|
const subdirs = entries.filter(
|
|
10138
10410
|
(e) => e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules"
|
|
10139
10411
|
);
|
|
@@ -10141,7 +10413,7 @@ function isMultiProjectFolder(folderPath) {
|
|
|
10141
10413
|
for (const subdir of subdirs) {
|
|
10142
10414
|
const subdirPath = pathModule.join(folderPath, subdir.name);
|
|
10143
10415
|
for (const marker of PROJECT_MARKERS) {
|
|
10144
|
-
if (
|
|
10416
|
+
if (fs21.existsSync(pathModule.join(subdirPath, marker))) {
|
|
10145
10417
|
projectSubdirs.push(subdir.name);
|
|
10146
10418
|
break;
|
|
10147
10419
|
}
|
|
@@ -12208,9 +12480,9 @@ var ContextStreamClient = class {
|
|
|
12208
12480
|
candidateParts.push("## Relevant Code\n");
|
|
12209
12481
|
currentChars += 18;
|
|
12210
12482
|
const codeEntries = code.results.map((c) => {
|
|
12211
|
-
const
|
|
12483
|
+
const path22 = c.file_path || "file";
|
|
12212
12484
|
const content = c.content?.slice(0, 150) || "";
|
|
12213
|
-
return { path:
|
|
12485
|
+
return { path: path22, entry: `\u2022 ${path22}: ${content}...
|
|
12214
12486
|
` };
|
|
12215
12487
|
});
|
|
12216
12488
|
for (const c of codeEntries) {
|
|
@@ -14724,6 +14996,143 @@ Use for monorepos or folders with multiple independent projects.
|
|
|
14724
14996
|
|
|
14725
14997
|
Full docs: https://contextstream.io/docs/mcp/tools
|
|
14726
14998
|
`.trim();
|
|
14999
|
+
var NO_HOOKS_SUPPLEMENT = `
|
|
15000
|
+
|
|
15001
|
+
---
|
|
15002
|
+
## \u26A0\uFE0F IMPORTANT: No Hooks Available \u26A0\uFE0F
|
|
15003
|
+
|
|
15004
|
+
**This editor does NOT have hooks to enforce ContextStream behavior.**
|
|
15005
|
+
You MUST follow these rules manually - there is no automatic enforcement.
|
|
15006
|
+
|
|
15007
|
+
---
|
|
15008
|
+
|
|
15009
|
+
## \u{1F680} SESSION START PROTOCOL
|
|
15010
|
+
|
|
15011
|
+
**On EVERY new session, you MUST:**
|
|
15012
|
+
|
|
15013
|
+
1. **Call \`init(folder_path="<project_path>")\`** FIRST
|
|
15014
|
+
- This triggers project indexing
|
|
15015
|
+
- Check response for \`indexing_status\`
|
|
15016
|
+
- If \`"started"\` or \`"refreshing"\`: wait before searching
|
|
15017
|
+
|
|
15018
|
+
2. **Call \`context(user_message="<first_message>")\`** SECOND
|
|
15019
|
+
- Gets task-specific rules and lessons
|
|
15020
|
+
- Check for [LESSONS_WARNING] - past mistakes to avoid
|
|
15021
|
+
- Check for [RULES_NOTICE] - update rules if needed
|
|
15022
|
+
|
|
15023
|
+
3. **NEVER skip init/context** - you will miss critical context
|
|
15024
|
+
|
|
15025
|
+
---
|
|
15026
|
+
|
|
15027
|
+
## \u{1F4C1} FILE INDEXING (CRITICAL)
|
|
15028
|
+
|
|
15029
|
+
**There is NO automatic file indexing in this editor.**
|
|
15030
|
+
You MUST manage indexing manually:
|
|
15031
|
+
|
|
15032
|
+
### After Creating/Editing Files:
|
|
15033
|
+
\`\`\`
|
|
15034
|
+
project(action="index") # Re-index entire project
|
|
15035
|
+
\`\`\`
|
|
15036
|
+
|
|
15037
|
+
### For Single File Updates:
|
|
15038
|
+
\`\`\`
|
|
15039
|
+
project(action="ingest_local", path="<file_path>")
|
|
15040
|
+
\`\`\`
|
|
15041
|
+
|
|
15042
|
+
### Signs You Need to Re-index:
|
|
15043
|
+
- Search doesn't find code you just wrote
|
|
15044
|
+
- Search returns old versions of functions
|
|
15045
|
+
- New files don't appear in search results
|
|
15046
|
+
|
|
15047
|
+
### Best Practice:
|
|
15048
|
+
After completing a feature or making multiple file changes, ALWAYS run:
|
|
15049
|
+
\`\`\`
|
|
15050
|
+
project(action="index")
|
|
15051
|
+
\`\`\`
|
|
15052
|
+
|
|
15053
|
+
---
|
|
15054
|
+
|
|
15055
|
+
## \u{1F50D} SEARCH-FIRST (No PreToolUse Hook)
|
|
15056
|
+
|
|
15057
|
+
**There is NO hook to block local tools.** You MUST self-enforce:
|
|
15058
|
+
|
|
15059
|
+
### Before ANY Search, Check Index Status:
|
|
15060
|
+
\`\`\`
|
|
15061
|
+
project(action="index_status")
|
|
15062
|
+
\`\`\`
|
|
15063
|
+
|
|
15064
|
+
This tells you:
|
|
15065
|
+
- \`indexed\`: true/false - is project indexed?
|
|
15066
|
+
- \`last_indexed_at\`: timestamp - when was it last indexed?
|
|
15067
|
+
- \`file_count\`: number - how many files indexed?
|
|
15068
|
+
|
|
15069
|
+
### Search Protocol:
|
|
15070
|
+
|
|
15071
|
+
**IF project is indexed and fresh:**
|
|
15072
|
+
\`\`\`
|
|
15073
|
+
search(mode="hybrid", query="what you're looking for")
|
|
15074
|
+
\`\`\`
|
|
15075
|
+
|
|
15076
|
+
**IF project is NOT indexed or very stale (>7 days):**
|
|
15077
|
+
\u2192 Use local tools (Glob/Grep/Read) directly
|
|
15078
|
+
\u2192 OR run \`project(action="index")\` first, then search
|
|
15079
|
+
|
|
15080
|
+
**IF ContextStream search returns 0 results or errors:**
|
|
15081
|
+
\u2192 Use local tools (Glob/Grep/Read) as fallback
|
|
15082
|
+
|
|
15083
|
+
### When Local Tools Are OK:
|
|
15084
|
+
\u2705 Project is not indexed
|
|
15085
|
+
\u2705 Index is stale/outdated (>7 days old)
|
|
15086
|
+
\u2705 ContextStream search returns 0 results
|
|
15087
|
+
\u2705 ContextStream returns errors
|
|
15088
|
+
\u2705 User explicitly requests local tools
|
|
15089
|
+
|
|
15090
|
+
### When to Use ContextStream Search:
|
|
15091
|
+
\u2705 Project is indexed and fresh
|
|
15092
|
+
\u2705 Looking for code by meaning/concept
|
|
15093
|
+
\u2705 Need semantic understanding
|
|
15094
|
+
|
|
15095
|
+
---
|
|
15096
|
+
|
|
15097
|
+
## \u{1F4BE} CONTEXT COMPACTION (No PreCompact Hook)
|
|
15098
|
+
|
|
15099
|
+
**There is NO automatic state saving before compaction.**
|
|
15100
|
+
You MUST save state manually when the conversation gets long:
|
|
15101
|
+
|
|
15102
|
+
### When to Save State:
|
|
15103
|
+
- After completing a major task
|
|
15104
|
+
- Before the conversation might be compacted
|
|
15105
|
+
- If \`context()\` returns \`context_pressure.level: "high"\`
|
|
15106
|
+
|
|
15107
|
+
### How to Save State:
|
|
15108
|
+
\`\`\`
|
|
15109
|
+
session(action="capture", event_type="session_snapshot",
|
|
15110
|
+
title="Session checkpoint",
|
|
15111
|
+
content="{ \\"summary\\": \\"what we did\\", \\"active_files\\": [...], \\"next_steps\\": [...] }")
|
|
15112
|
+
\`\`\`
|
|
15113
|
+
|
|
15114
|
+
### After Compaction (if context seems lost):
|
|
15115
|
+
\`\`\`
|
|
15116
|
+
init(folder_path="...", is_post_compact=true)
|
|
15117
|
+
\`\`\`
|
|
15118
|
+
This restores the most recent snapshot.
|
|
15119
|
+
|
|
15120
|
+
---
|
|
15121
|
+
|
|
15122
|
+
## \u{1F4CB} PLANS & TASKS (No EnterPlanMode)
|
|
15123
|
+
|
|
15124
|
+
**Always use ContextStream for planning:**
|
|
15125
|
+
|
|
15126
|
+
\`\`\`
|
|
15127
|
+
session(action="capture_plan", title="...", steps=[...])
|
|
15128
|
+
memory(action="create_task", title="...", plan_id="...")
|
|
15129
|
+
\`\`\`
|
|
15130
|
+
|
|
15131
|
+
\u274C DO NOT use built-in plan mode or write plans to markdown files.
|
|
15132
|
+
|
|
15133
|
+
---
|
|
15134
|
+
`;
|
|
15135
|
+
var NO_HOOKS_EDITORS = ["codex", "aider", "antigravity"];
|
|
14727
15136
|
var TEMPLATES = {
|
|
14728
15137
|
codex: {
|
|
14729
15138
|
filename: "AGENTS.md",
|
|
@@ -14807,6 +15216,9 @@ ${options.workspaceId ? `# Workspace ID: ${options.workspaceId}` : ""}
|
|
|
14807
15216
|
`;
|
|
14808
15217
|
content = header + content;
|
|
14809
15218
|
}
|
|
15219
|
+
if (NO_HOOKS_EDITORS.includes(editor.toLowerCase())) {
|
|
15220
|
+
content += NO_HOOKS_SUPPLEMENT;
|
|
15221
|
+
}
|
|
14810
15222
|
if (options?.additionalRules) {
|
|
14811
15223
|
content += "\n\n## Project-Specific Rules\n\n" + options.additionalRules;
|
|
14812
15224
|
}
|
|
@@ -15920,9 +16332,9 @@ function humanizeKey(raw) {
|
|
|
15920
16332
|
const withSpaces = raw.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/_/g, " ");
|
|
15921
16333
|
return withSpaces.toLowerCase();
|
|
15922
16334
|
}
|
|
15923
|
-
function buildParamDescription(key,
|
|
16335
|
+
function buildParamDescription(key, path22) {
|
|
15924
16336
|
const normalized = key in DEFAULT_PARAM_DESCRIPTIONS ? key : key.toLowerCase();
|
|
15925
|
-
const parent =
|
|
16337
|
+
const parent = path22[path22.length - 1];
|
|
15926
16338
|
if (parent === "target") {
|
|
15927
16339
|
if (key === "id") return "Target identifier (module path, function id, etc.).";
|
|
15928
16340
|
if (key === "type") return "Target type (module, file, function, type, variable).";
|
|
@@ -15953,7 +16365,7 @@ function getDescription(schema) {
|
|
|
15953
16365
|
if (def?.description && def.description.trim()) return def.description;
|
|
15954
16366
|
return void 0;
|
|
15955
16367
|
}
|
|
15956
|
-
function applyParamDescriptions(schema,
|
|
16368
|
+
function applyParamDescriptions(schema, path22 = []) {
|
|
15957
16369
|
if (!(schema instanceof external_exports.ZodObject)) {
|
|
15958
16370
|
return schema;
|
|
15959
16371
|
}
|
|
@@ -15964,7 +16376,7 @@ function applyParamDescriptions(schema, path21 = []) {
|
|
|
15964
16376
|
let nextField = field;
|
|
15965
16377
|
const existingDescription = getDescription(field);
|
|
15966
16378
|
if (field instanceof external_exports.ZodObject) {
|
|
15967
|
-
const nested = applyParamDescriptions(field, [...
|
|
16379
|
+
const nested = applyParamDescriptions(field, [...path22, key]);
|
|
15968
16380
|
if (nested !== field) {
|
|
15969
16381
|
nextField = nested;
|
|
15970
16382
|
changed = true;
|
|
@@ -15976,7 +16388,7 @@ function applyParamDescriptions(schema, path21 = []) {
|
|
|
15976
16388
|
changed = true;
|
|
15977
16389
|
}
|
|
15978
16390
|
} else {
|
|
15979
|
-
nextField = nextField.describe(buildParamDescription(key,
|
|
16391
|
+
nextField = nextField.describe(buildParamDescription(key, path22));
|
|
15980
16392
|
changed = true;
|
|
15981
16393
|
}
|
|
15982
16394
|
nextShape[key] = nextField;
|
|
@@ -24973,13 +25385,13 @@ Example workflow:
|
|
|
24973
25385
|
);
|
|
24974
25386
|
}
|
|
24975
25387
|
if (input.file_path) {
|
|
24976
|
-
const
|
|
25388
|
+
const fs21 = await import("fs/promises");
|
|
24977
25389
|
const pathModule = await import("path");
|
|
24978
25390
|
const filePath = input.file_path.startsWith("~") ? input.file_path.replace("~", process.env.HOME || "") : input.file_path;
|
|
24979
25391
|
const resolvedPath = pathModule.resolve(filePath);
|
|
24980
25392
|
let fileStats;
|
|
24981
25393
|
try {
|
|
24982
|
-
fileStats = await
|
|
25394
|
+
fileStats = await fs21.stat(resolvedPath);
|
|
24983
25395
|
} catch {
|
|
24984
25396
|
return errorResult(`File not found: ${resolvedPath}`);
|
|
24985
25397
|
}
|
|
@@ -25026,7 +25438,7 @@ Example workflow:
|
|
|
25026
25438
|
mime_type: mimeType,
|
|
25027
25439
|
tags: input.tags
|
|
25028
25440
|
});
|
|
25029
|
-
const fileBuffer = await
|
|
25441
|
+
const fileBuffer = await fs21.readFile(resolvedPath);
|
|
25030
25442
|
const uploadResponse = await fetch(uploadInit.upload_url, {
|
|
25031
25443
|
method: "PUT",
|
|
25032
25444
|
headers: uploadInit.headers,
|
|
@@ -26433,8 +26845,8 @@ var SessionManager = class _SessionManager {
|
|
|
26433
26845
|
/**
|
|
26434
26846
|
* Set the folder path hint (can be passed from tools that know the workspace path)
|
|
26435
26847
|
*/
|
|
26436
|
-
setFolderPath(
|
|
26437
|
-
this.folderPath =
|
|
26848
|
+
setFolderPath(path22) {
|
|
26849
|
+
this.folderPath = path22;
|
|
26438
26850
|
}
|
|
26439
26851
|
/**
|
|
26440
26852
|
* Mark that context_smart has been called in this session.
|
|
@@ -26624,7 +27036,7 @@ var SessionManager = class _SessionManager {
|
|
|
26624
27036
|
}
|
|
26625
27037
|
if (this.ideRoots.length === 0) {
|
|
26626
27038
|
const cwd = process.cwd();
|
|
26627
|
-
const
|
|
27039
|
+
const fs21 = await import("fs");
|
|
26628
27040
|
const projectIndicators = [
|
|
26629
27041
|
".git",
|
|
26630
27042
|
"package.json",
|
|
@@ -26634,7 +27046,7 @@ var SessionManager = class _SessionManager {
|
|
|
26634
27046
|
];
|
|
26635
27047
|
const hasProjectIndicator = projectIndicators.some((f) => {
|
|
26636
27048
|
try {
|
|
26637
|
-
return
|
|
27049
|
+
return fs21.existsSync(`${cwd}/${f}`);
|
|
26638
27050
|
} catch {
|
|
26639
27051
|
return false;
|
|
26640
27052
|
}
|
|
@@ -27211,9 +27623,9 @@ async function runHttpGateway() {
|
|
|
27211
27623
|
}
|
|
27212
27624
|
|
|
27213
27625
|
// src/index.ts
|
|
27214
|
-
import { existsSync as
|
|
27215
|
-
import { homedir as
|
|
27216
|
-
import { join as
|
|
27626
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
27627
|
+
import { homedir as homedir19 } from "os";
|
|
27628
|
+
import { join as join23 } from "path";
|
|
27217
27629
|
|
|
27218
27630
|
// src/setup.ts
|
|
27219
27631
|
import * as fs7 from "node:fs/promises";
|
|
@@ -28043,10 +28455,10 @@ Code: ${device.user_code}`);
|
|
|
28043
28455
|
if (poll && poll.status === "pending") {
|
|
28044
28456
|
const intervalSeconds = typeof poll.interval === "number" ? poll.interval : 5;
|
|
28045
28457
|
const waitMs = Math.max(1, intervalSeconds) * 1e3;
|
|
28046
|
-
await new Promise((
|
|
28458
|
+
await new Promise((resolve16) => setTimeout(resolve16, waitMs));
|
|
28047
28459
|
continue;
|
|
28048
28460
|
}
|
|
28049
|
-
await new Promise((
|
|
28461
|
+
await new Promise((resolve16) => setTimeout(resolve16, 1e3));
|
|
28050
28462
|
}
|
|
28051
28463
|
if (!accessToken) {
|
|
28052
28464
|
throw new Error(
|
|
@@ -28611,12 +29023,12 @@ Applying to ${projects.length} project(s)...`);
|
|
|
28611
29023
|
// src/index.ts
|
|
28612
29024
|
var ENABLE_PROMPTS2 = (process.env.CONTEXTSTREAM_ENABLE_PROMPTS || "true").toLowerCase() !== "false";
|
|
28613
29025
|
function showFirstRunMessage() {
|
|
28614
|
-
const configDir =
|
|
28615
|
-
const starShownFile =
|
|
28616
|
-
if (
|
|
29026
|
+
const configDir = join23(homedir19(), ".contextstream");
|
|
29027
|
+
const starShownFile = join23(configDir, ".star-shown");
|
|
29028
|
+
if (existsSync17(starShownFile)) {
|
|
28617
29029
|
return;
|
|
28618
29030
|
}
|
|
28619
|
-
if (!
|
|
29031
|
+
if (!existsSync17(configDir)) {
|
|
28620
29032
|
try {
|
|
28621
29033
|
mkdirSync5(configDir, { recursive: true });
|
|
28622
29034
|
} catch {
|