midnight-mcp 0.1.41 → 0.2.2

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.
Files changed (103) hide show
  1. package/README.md +32 -1
  2. package/dist/bin.d.ts +1 -0
  3. package/dist/bin.js +60 -0
  4. package/dist/chunk-HOWO4K5A.js +2197 -0
  5. package/dist/chunk-S7G4OHA4.js +8306 -0
  6. package/dist/db-YDGUWI5K.js +7 -0
  7. package/dist/index.d.ts +205 -3
  8. package/dist/index.js +28 -16
  9. package/package.json +16 -6
  10. package/dist/config/compact-version.d.ts +0 -183
  11. package/dist/config/compact-version.js +0 -423
  12. package/dist/db/index.d.ts +0 -3
  13. package/dist/db/index.js +0 -2
  14. package/dist/db/vectorStore.d.ts +0 -69
  15. package/dist/db/vectorStore.js +0 -196
  16. package/dist/pipeline/embeddings.d.ts +0 -25
  17. package/dist/pipeline/embeddings.js +0 -103
  18. package/dist/pipeline/github.d.ts +0 -84
  19. package/dist/pipeline/github.js +0 -399
  20. package/dist/pipeline/index.d.ts +0 -11
  21. package/dist/pipeline/index.js +0 -6
  22. package/dist/pipeline/indexer.d.ts +0 -41
  23. package/dist/pipeline/indexer.js +0 -254
  24. package/dist/pipeline/parser.d.ts +0 -46
  25. package/dist/pipeline/parser.js +0 -436
  26. package/dist/pipeline/releases.d.ts +0 -112
  27. package/dist/pipeline/releases.js +0 -298
  28. package/dist/pipeline/repository.d.ts +0 -372
  29. package/dist/pipeline/repository.js +0 -520
  30. package/dist/prompts/index.d.ts +0 -3
  31. package/dist/prompts/index.js +0 -2
  32. package/dist/prompts/templates.d.ts +0 -26
  33. package/dist/prompts/templates.js +0 -443
  34. package/dist/resources/code.d.ts +0 -15
  35. package/dist/resources/code.js +0 -122
  36. package/dist/resources/content/code-content.d.ts +0 -6
  37. package/dist/resources/content/code-content.js +0 -802
  38. package/dist/resources/content/docs-content.d.ts +0 -14
  39. package/dist/resources/content/docs-content.js +0 -1202
  40. package/dist/resources/content/index.d.ts +0 -6
  41. package/dist/resources/content/index.js +0 -6
  42. package/dist/resources/docs.d.ts +0 -15
  43. package/dist/resources/docs.js +0 -98
  44. package/dist/resources/index.d.ts +0 -6
  45. package/dist/resources/index.js +0 -13
  46. package/dist/resources/schemas.d.ts +0 -16
  47. package/dist/resources/schemas.js +0 -407
  48. package/dist/scripts/index-repos.d.ts +0 -12
  49. package/dist/scripts/index-repos.js +0 -53
  50. package/dist/server.d.ts +0 -43
  51. package/dist/server.js +0 -696
  52. package/dist/services/index.d.ts +0 -6
  53. package/dist/services/index.js +0 -6
  54. package/dist/services/sampling.d.ts +0 -62
  55. package/dist/services/sampling.js +0 -277
  56. package/dist/tools/analyze.d.ts +0 -106
  57. package/dist/tools/analyze.js +0 -431
  58. package/dist/tools/generation.d.ts +0 -9
  59. package/dist/tools/generation.js +0 -285
  60. package/dist/tools/health.d.ts +0 -120
  61. package/dist/tools/health.js +0 -365
  62. package/dist/tools/index.d.ts +0 -14
  63. package/dist/tools/index.js +0 -22
  64. package/dist/tools/meta.d.ts +0 -61
  65. package/dist/tools/meta.js +0 -282
  66. package/dist/tools/repository/constants.d.ts +0 -19
  67. package/dist/tools/repository/constants.js +0 -324
  68. package/dist/tools/repository/handlers.d.ts +0 -373
  69. package/dist/tools/repository/handlers.js +0 -724
  70. package/dist/tools/repository/index.d.ts +0 -9
  71. package/dist/tools/repository/index.js +0 -13
  72. package/dist/tools/repository/schemas.d.ts +0 -153
  73. package/dist/tools/repository/schemas.js +0 -106
  74. package/dist/tools/repository/tools.d.ts +0 -7
  75. package/dist/tools/repository/tools.js +0 -484
  76. package/dist/tools/repository/validation.d.ts +0 -106
  77. package/dist/tools/repository/validation.js +0 -820
  78. package/dist/tools/repository.d.ts +0 -6
  79. package/dist/tools/repository.js +0 -7
  80. package/dist/tools/search.d.ts +0 -76
  81. package/dist/tools/search.js +0 -423
  82. package/dist/types/index.d.ts +0 -2
  83. package/dist/types/index.js +0 -2
  84. package/dist/types/mcp.d.ts +0 -187
  85. package/dist/types/mcp.js +0 -6
  86. package/dist/utils/cache.d.ts +0 -77
  87. package/dist/utils/cache.js +0 -172
  88. package/dist/utils/config.d.ts +0 -70
  89. package/dist/utils/config.js +0 -294
  90. package/dist/utils/errors.d.ts +0 -111
  91. package/dist/utils/errors.js +0 -165
  92. package/dist/utils/health.d.ts +0 -29
  93. package/dist/utils/health.js +0 -132
  94. package/dist/utils/hosted-api.d.ts +0 -67
  95. package/dist/utils/hosted-api.js +0 -119
  96. package/dist/utils/index.d.ts +0 -16
  97. package/dist/utils/index.js +0 -15
  98. package/dist/utils/logger.d.ts +0 -48
  99. package/dist/utils/logger.js +0 -124
  100. package/dist/utils/rate-limit.d.ts +0 -61
  101. package/dist/utils/rate-limit.js +0 -148
  102. package/dist/utils/validation.d.ts +0 -52
  103. package/dist/utils/validation.js +0 -255
@@ -1,148 +0,0 @@
1
- /**
2
- * Rate limit tracking and management utilities
3
- * Tracks GitHub API rate limits and warns before hitting limits
4
- */
5
- import { logger } from "./logger.js";
6
- // Warning threshold - warn when this percentage of rate limit is used
7
- const WARNING_THRESHOLD = 0.8; // 80%
8
- // Critical threshold - consider limited when this percentage is used
9
- const CRITICAL_THRESHOLD = 0.95; // 95%
10
- // Cached rate limit info
11
- let cachedRateLimit = null;
12
- let lastUpdate = 0;
13
- const CACHE_TTL = 60 * 1000; // 1 minute cache
14
- /**
15
- * Update rate limit info from API response headers
16
- */
17
- export function updateRateLimitFromHeaders(headers) {
18
- const limit = parseInt(headers["x-ratelimit-limit"] || "5000", 10);
19
- const remaining = parseInt(headers["x-ratelimit-remaining"] || "5000", 10);
20
- const resetTimestamp = parseInt(headers["x-ratelimit-reset"] || "0", 10);
21
- cachedRateLimit = {
22
- limit,
23
- remaining,
24
- reset: new Date(resetTimestamp * 1000),
25
- used: limit - remaining,
26
- };
27
- lastUpdate = Date.now();
28
- // Log warning if approaching limit
29
- const percentUsed = (cachedRateLimit.used / cachedRateLimit.limit) * 100;
30
- if (percentUsed >= WARNING_THRESHOLD * 100) {
31
- logger.warn("GitHub API rate limit warning", {
32
- remaining: cachedRateLimit.remaining,
33
- limit: cachedRateLimit.limit,
34
- percentUsed: Math.round(percentUsed),
35
- resetAt: cachedRateLimit.reset.toISOString(),
36
- });
37
- }
38
- }
39
- /**
40
- * Update rate limit info directly
41
- */
42
- export function updateRateLimit(info) {
43
- cachedRateLimit = info;
44
- lastUpdate = Date.now();
45
- }
46
- /**
47
- * Get current rate limit status
48
- */
49
- export function getRateLimitStatus() {
50
- if (!cachedRateLimit) {
51
- return {
52
- isLimited: false,
53
- isWarning: false,
54
- remaining: 5000,
55
- limit: 5000,
56
- resetAt: new Date(),
57
- percentUsed: 0,
58
- message: "Rate limit info not yet available",
59
- };
60
- }
61
- const percentUsed = cachedRateLimit.used / cachedRateLimit.limit;
62
- const isWarning = percentUsed >= WARNING_THRESHOLD;
63
- const isLimited = percentUsed >= CRITICAL_THRESHOLD || cachedRateLimit.remaining <= 10;
64
- let message;
65
- if (isLimited) {
66
- const minutesUntilReset = Math.ceil((cachedRateLimit.reset.getTime() - Date.now()) / 60000);
67
- message = `Rate limited! Resets in ${minutesUntilReset} minutes`;
68
- }
69
- else if (isWarning) {
70
- message = `Warning: ${cachedRateLimit.remaining} API calls remaining (${Math.round(percentUsed * 100)}% used)`;
71
- }
72
- else {
73
- message = `${cachedRateLimit.remaining}/${cachedRateLimit.limit} API calls remaining`;
74
- }
75
- return {
76
- isLimited,
77
- isWarning,
78
- remaining: cachedRateLimit.remaining,
79
- limit: cachedRateLimit.limit,
80
- resetAt: cachedRateLimit.reset,
81
- percentUsed: Math.round(percentUsed * 100),
82
- message,
83
- };
84
- }
85
- /**
86
- * Check if we should proceed with an API call
87
- * Returns true if safe to proceed, false if we should wait/fail
88
- */
89
- export function shouldProceedWithRequest() {
90
- if (!cachedRateLimit) {
91
- return { proceed: true };
92
- }
93
- if (cachedRateLimit.remaining <= 10) {
94
- const waitMs = Math.max(0, cachedRateLimit.reset.getTime() - Date.now());
95
- return {
96
- proceed: false,
97
- reason: `Rate limit nearly exhausted (${cachedRateLimit.remaining} remaining)`,
98
- waitMs,
99
- };
100
- }
101
- return { proceed: true };
102
- }
103
- /**
104
- * Get time until rate limit resets
105
- */
106
- export function getTimeUntilReset() {
107
- if (!cachedRateLimit) {
108
- return 0;
109
- }
110
- return Math.max(0, cachedRateLimit.reset.getTime() - Date.now());
111
- }
112
- /**
113
- * Check if cached rate limit info is stale
114
- */
115
- export function isRateLimitStale() {
116
- return Date.now() - lastUpdate > CACHE_TTL;
117
- }
118
- /**
119
- * Get cached rate limit info
120
- */
121
- export function getCachedRateLimit() {
122
- return cachedRateLimit;
123
- }
124
- /**
125
- * Decrement remaining count (for optimistic tracking)
126
- */
127
- export function decrementRemaining() {
128
- if (cachedRateLimit && cachedRateLimit.remaining > 0) {
129
- cachedRateLimit.remaining--;
130
- cachedRateLimit.used++;
131
- }
132
- }
133
- /**
134
- * Format rate limit status for display
135
- */
136
- export function formatRateLimitStatus() {
137
- const status = getRateLimitStatus();
138
- if (status.isLimited) {
139
- return `⛔ ${status.message}`;
140
- }
141
- else if (status.isWarning) {
142
- return `⚠️ ${status.message}`;
143
- }
144
- else {
145
- return `✅ ${status.message}`;
146
- }
147
- }
148
- //# sourceMappingURL=rate-limit.js.map
@@ -1,52 +0,0 @@
1
- /**
2
- * Input validation and sanitization utilities
3
- * Protects against injection attacks and malformed inputs
4
- */
5
- export interface ValidationResult {
6
- isValid: boolean;
7
- sanitized: string;
8
- warnings: string[];
9
- errors: string[];
10
- }
11
- /**
12
- * Sanitize a string by removing dangerous patterns
13
- */
14
- export declare function sanitizeString(input: string, maxLength?: number): string;
15
- /**
16
- * Validate and sanitize a search query
17
- */
18
- export declare function validateQuery(query: unknown): ValidationResult;
19
- /**
20
- * Validate and sanitize a repository name
21
- */
22
- export declare function validateRepository(repo: unknown): ValidationResult;
23
- /**
24
- * Validate and sanitize a file path
25
- */
26
- export declare function validatePath(path: unknown): ValidationResult;
27
- /**
28
- * Validate and sanitize a git ref (branch, tag, or commit)
29
- */
30
- export declare function validateRef(ref: unknown): ValidationResult;
31
- /**
32
- * Validate a numeric input within bounds
33
- */
34
- export declare function validateNumber(value: unknown, options: {
35
- min?: number;
36
- max?: number;
37
- defaultValue: number;
38
- }): {
39
- isValid: boolean;
40
- value: number;
41
- error?: string;
42
- };
43
- /**
44
- * Validate tool arguments with automatic sanitization
45
- */
46
- export declare function validateToolArgs<T extends Record<string, unknown>>(args: T, validators: Partial<Record<keyof T, (value: unknown) => ValidationResult>>): {
47
- isValid: boolean;
48
- sanitized: Partial<T>;
49
- errors: string[];
50
- warnings: string[];
51
- };
52
- //# sourceMappingURL=validation.d.ts.map
@@ -1,255 +0,0 @@
1
- /**
2
- * Input validation and sanitization utilities
3
- * Protects against injection attacks and malformed inputs
4
- */
5
- // Maximum allowed lengths for different input types
6
- const MAX_LENGTHS = {
7
- query: 1000,
8
- path: 500,
9
- repository: 100,
10
- ref: 100,
11
- generic: 500,
12
- };
13
- // Patterns that could indicate injection attempts
14
- const DANGEROUS_PATTERNS = [
15
- /[<>]/g, // HTML/XML injection
16
- /javascript:/gi, // JS protocol
17
- /data:/gi, // Data URLs
18
- /\0/g, // Null bytes
19
- /[\x00-\x08\x0B\x0C\x0E-\x1F]/g, // Control characters (except newline, tab)
20
- ];
21
- // Valid characters for different input types
22
- const VALID_PATTERNS = {
23
- // Repository names: alphanumeric, hyphens, underscores, slashes
24
- repository: /^[a-zA-Z0-9_\-./]+$/,
25
- // Git refs: alphanumeric, hyphens, underscores, dots, slashes
26
- ref: /^[a-zA-Z0-9_\-./]+$/,
27
- // File paths: most characters except dangerous ones
28
- path: /^[a-zA-Z0-9_\-./\s]+$/,
29
- };
30
- /**
31
- * Sanitize a string by removing dangerous patterns
32
- */
33
- export function sanitizeString(input, maxLength = MAX_LENGTHS.generic) {
34
- if (!input || typeof input !== "string") {
35
- return "";
36
- }
37
- let sanitized = input;
38
- // Remove dangerous patterns
39
- for (const pattern of DANGEROUS_PATTERNS) {
40
- sanitized = sanitized.replace(pattern, "");
41
- }
42
- // Trim whitespace
43
- sanitized = sanitized.trim();
44
- // Truncate to max length
45
- if (sanitized.length > maxLength) {
46
- sanitized = sanitized.substring(0, maxLength);
47
- }
48
- return sanitized;
49
- }
50
- /**
51
- * Validate and sanitize a search query
52
- */
53
- export function validateQuery(query) {
54
- const warnings = [];
55
- const errors = [];
56
- if (query === null || query === undefined) {
57
- return {
58
- isValid: false,
59
- sanitized: "",
60
- warnings,
61
- errors: ["Query is required"],
62
- };
63
- }
64
- if (typeof query !== "string") {
65
- return {
66
- isValid: false,
67
- sanitized: "",
68
- warnings,
69
- errors: ["Query must be a string"],
70
- };
71
- }
72
- const sanitized = sanitizeString(query, MAX_LENGTHS.query);
73
- if (sanitized.length === 0) {
74
- errors.push("Query cannot be empty after sanitization");
75
- }
76
- if (sanitized.length < 2) {
77
- warnings.push("Query is very short, results may be limited");
78
- }
79
- if (query.length !== sanitized.length) {
80
- warnings.push("Query was sanitized to remove potentially dangerous characters");
81
- }
82
- return {
83
- isValid: errors.length === 0,
84
- sanitized,
85
- warnings,
86
- errors,
87
- };
88
- }
89
- /**
90
- * Validate and sanitize a repository name
91
- */
92
- export function validateRepository(repo) {
93
- const warnings = [];
94
- const errors = [];
95
- if (repo === null || repo === undefined) {
96
- return {
97
- isValid: false,
98
- sanitized: "",
99
- warnings,
100
- errors: ["Repository name is required"],
101
- };
102
- }
103
- if (typeof repo !== "string") {
104
- return {
105
- isValid: false,
106
- sanitized: "",
107
- warnings,
108
- errors: ["Repository name must be a string"],
109
- };
110
- }
111
- const sanitized = sanitizeString(repo, MAX_LENGTHS.repository);
112
- if (!VALID_PATTERNS.repository.test(sanitized)) {
113
- errors.push("Repository name contains invalid characters");
114
- }
115
- // Check for path traversal attempts
116
- if (sanitized.includes("..")) {
117
- errors.push("Repository name cannot contain path traversal sequences");
118
- }
119
- return {
120
- isValid: errors.length === 0,
121
- sanitized,
122
- warnings,
123
- errors,
124
- };
125
- }
126
- /**
127
- * Validate and sanitize a file path
128
- */
129
- export function validatePath(path) {
130
- const warnings = [];
131
- const errors = [];
132
- if (path === null || path === undefined) {
133
- return {
134
- isValid: false,
135
- sanitized: "",
136
- warnings,
137
- errors: ["Path is required"],
138
- };
139
- }
140
- if (typeof path !== "string") {
141
- return {
142
- isValid: false,
143
- sanitized: "",
144
- warnings,
145
- errors: ["Path must be a string"],
146
- };
147
- }
148
- let sanitized = sanitizeString(path, MAX_LENGTHS.path);
149
- // Normalize path separators
150
- sanitized = sanitized.replace(/\\/g, "/");
151
- // Remove leading slashes
152
- sanitized = sanitized.replace(/^\/+/, "");
153
- // Check for path traversal attempts
154
- if (sanitized.includes("..")) {
155
- errors.push("Path cannot contain traversal sequences (..)");
156
- }
157
- // Check for absolute paths
158
- if (path.startsWith("/") || /^[a-zA-Z]:/.test(path)) {
159
- warnings.push("Absolute paths are converted to relative paths");
160
- }
161
- return {
162
- isValid: errors.length === 0,
163
- sanitized,
164
- warnings,
165
- errors,
166
- };
167
- }
168
- /**
169
- * Validate and sanitize a git ref (branch, tag, or commit)
170
- */
171
- export function validateRef(ref) {
172
- const warnings = [];
173
- const errors = [];
174
- // Ref is optional, so null/undefined is valid
175
- if (ref === null || ref === undefined) {
176
- return {
177
- isValid: true,
178
- sanitized: "",
179
- warnings,
180
- errors,
181
- };
182
- }
183
- if (typeof ref !== "string") {
184
- return {
185
- isValid: false,
186
- sanitized: "",
187
- warnings,
188
- errors: ["Ref must be a string"],
189
- };
190
- }
191
- const sanitized = sanitizeString(ref, MAX_LENGTHS.ref);
192
- if (!VALID_PATTERNS.ref.test(sanitized)) {
193
- errors.push("Ref contains invalid characters");
194
- }
195
- // Check for path traversal
196
- if (sanitized.includes("..")) {
197
- errors.push("Ref cannot contain path traversal sequences");
198
- }
199
- return {
200
- isValid: errors.length === 0,
201
- sanitized,
202
- warnings,
203
- errors,
204
- };
205
- }
206
- /**
207
- * Validate a numeric input within bounds
208
- */
209
- export function validateNumber(value, options) {
210
- const { min = 1, max = 100, defaultValue } = options;
211
- if (value === null || value === undefined) {
212
- return { isValid: true, value: defaultValue };
213
- }
214
- const num = typeof value === "string" ? parseInt(value, 10) : value;
215
- if (typeof num !== "number" || isNaN(num)) {
216
- return {
217
- isValid: false,
218
- value: defaultValue,
219
- error: "Must be a valid number",
220
- };
221
- }
222
- if (num < min) {
223
- return { isValid: true, value: min };
224
- }
225
- if (num > max) {
226
- return { isValid: true, value: max };
227
- }
228
- return { isValid: true, value: num };
229
- }
230
- /**
231
- * Validate tool arguments with automatic sanitization
232
- */
233
- export function validateToolArgs(args, validators) {
234
- const errors = [];
235
- const warnings = [];
236
- const sanitized = { ...args };
237
- for (const [key, validator] of Object.entries(validators)) {
238
- if (validator && key in args) {
239
- const result = validator(args[key]);
240
- if (!result.isValid) {
241
- errors.push(`${key}: ${result.errors.join(", ")}`);
242
- }
243
- warnings.push(...result.warnings.map((w) => `${key}: ${w}`));
244
- sanitized[key] =
245
- result.sanitized || args[key];
246
- }
247
- }
248
- return {
249
- isValid: errors.length === 0,
250
- sanitized,
251
- errors,
252
- warnings,
253
- };
254
- }
255
- //# sourceMappingURL=validation.js.map