baseguard 1.0.0

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 (244) hide show
  1. package/.eslintrc.json +25 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +94 -0
  4. package/bin/base.js +494 -0
  5. package/dist/ai/fix-manager.d.ts +67 -0
  6. package/dist/ai/fix-manager.d.ts.map +1 -0
  7. package/dist/ai/fix-manager.js +326 -0
  8. package/dist/ai/fix-manager.js.map +1 -0
  9. package/dist/ai/gemini-analyzer.d.ts +116 -0
  10. package/dist/ai/gemini-analyzer.d.ts.map +1 -0
  11. package/dist/ai/gemini-analyzer.js +572 -0
  12. package/dist/ai/gemini-analyzer.js.map +1 -0
  13. package/dist/ai/index.d.ts +4 -0
  14. package/dist/ai/index.d.ts.map +1 -0
  15. package/dist/ai/index.js +5 -0
  16. package/dist/ai/index.js.map +1 -0
  17. package/dist/ai/jules-implementer.d.ts +115 -0
  18. package/dist/ai/jules-implementer.d.ts.map +1 -0
  19. package/dist/ai/jules-implementer.js +387 -0
  20. package/dist/ai/jules-implementer.js.map +1 -0
  21. package/dist/commands/automation.d.ts +5 -0
  22. package/dist/commands/automation.d.ts.map +1 -0
  23. package/dist/commands/automation.js +305 -0
  24. package/dist/commands/automation.js.map +1 -0
  25. package/dist/commands/check.d.ts +9 -0
  26. package/dist/commands/check.d.ts.map +1 -0
  27. package/dist/commands/check.js +113 -0
  28. package/dist/commands/check.js.map +1 -0
  29. package/dist/commands/config.d.ts +11 -0
  30. package/dist/commands/config.d.ts.map +1 -0
  31. package/dist/commands/config.js +324 -0
  32. package/dist/commands/config.js.map +1 -0
  33. package/dist/commands/fix.d.ts +9 -0
  34. package/dist/commands/fix.d.ts.map +1 -0
  35. package/dist/commands/fix.js +207 -0
  36. package/dist/commands/fix.js.map +1 -0
  37. package/dist/commands/index.d.ts +6 -0
  38. package/dist/commands/index.d.ts.map +1 -0
  39. package/dist/commands/index.js +7 -0
  40. package/dist/commands/index.js.map +1 -0
  41. package/dist/commands/init.d.ts +9 -0
  42. package/dist/commands/init.d.ts.map +1 -0
  43. package/dist/commands/init.js +125 -0
  44. package/dist/commands/init.js.map +1 -0
  45. package/dist/core/api-key-manager.d.ts +83 -0
  46. package/dist/core/api-key-manager.d.ts.map +1 -0
  47. package/dist/core/api-key-manager.js +244 -0
  48. package/dist/core/api-key-manager.js.map +1 -0
  49. package/dist/core/baseguard.d.ts +46 -0
  50. package/dist/core/baseguard.d.ts.map +1 -0
  51. package/dist/core/baseguard.js +132 -0
  52. package/dist/core/baseguard.js.map +1 -0
  53. package/dist/core/baseline-checker.d.ts +63 -0
  54. package/dist/core/baseline-checker.d.ts.map +1 -0
  55. package/dist/core/baseline-checker.js +502 -0
  56. package/dist/core/baseline-checker.js.map +1 -0
  57. package/dist/core/cache-manager.d.ts +88 -0
  58. package/dist/core/cache-manager.d.ts.map +1 -0
  59. package/dist/core/cache-manager.js +213 -0
  60. package/dist/core/cache-manager.js.map +1 -0
  61. package/dist/core/configuration.d.ts +140 -0
  62. package/dist/core/configuration.d.ts.map +1 -0
  63. package/dist/core/configuration.js +474 -0
  64. package/dist/core/configuration.js.map +1 -0
  65. package/dist/core/directory-filter.d.ts +90 -0
  66. package/dist/core/directory-filter.d.ts.map +1 -0
  67. package/dist/core/directory-filter.js +319 -0
  68. package/dist/core/directory-filter.js.map +1 -0
  69. package/dist/core/error-handler.d.ts +110 -0
  70. package/dist/core/error-handler.d.ts.map +1 -0
  71. package/dist/core/error-handler.js +392 -0
  72. package/dist/core/error-handler.js.map +1 -0
  73. package/dist/core/file-processor.d.ts +80 -0
  74. package/dist/core/file-processor.d.ts.map +1 -0
  75. package/dist/core/file-processor.js +259 -0
  76. package/dist/core/file-processor.js.map +1 -0
  77. package/dist/core/gitignore-manager.d.ts +44 -0
  78. package/dist/core/gitignore-manager.d.ts.map +1 -0
  79. package/dist/core/gitignore-manager.js +147 -0
  80. package/dist/core/gitignore-manager.js.map +1 -0
  81. package/dist/core/index.d.ts +13 -0
  82. package/dist/core/index.d.ts.map +1 -0
  83. package/dist/core/index.js +13 -0
  84. package/dist/core/index.js.map +1 -0
  85. package/dist/core/lazy-loader.d.ts +68 -0
  86. package/dist/core/lazy-loader.d.ts.map +1 -0
  87. package/dist/core/lazy-loader.js +260 -0
  88. package/dist/core/lazy-loader.js.map +1 -0
  89. package/dist/core/memory-manager.d.ts +1 -0
  90. package/dist/core/memory-manager.d.ts.map +1 -0
  91. package/dist/core/memory-manager.js +2 -0
  92. package/dist/core/memory-manager.js.map +1 -0
  93. package/dist/core/startup-optimizer.d.ts +45 -0
  94. package/dist/core/startup-optimizer.d.ts.map +1 -0
  95. package/dist/core/startup-optimizer.js +140 -0
  96. package/dist/core/startup-optimizer.js.map +1 -0
  97. package/dist/git/automation-engine.d.ts +58 -0
  98. package/dist/git/automation-engine.d.ts.map +1 -0
  99. package/dist/git/automation-engine.js +318 -0
  100. package/dist/git/automation-engine.js.map +1 -0
  101. package/dist/git/github-manager.d.ts +71 -0
  102. package/dist/git/github-manager.d.ts.map +1 -0
  103. package/dist/git/github-manager.js +226 -0
  104. package/dist/git/github-manager.js.map +1 -0
  105. package/dist/git/hook-manager.d.ts +43 -0
  106. package/dist/git/hook-manager.d.ts.map +1 -0
  107. package/dist/git/hook-manager.js +191 -0
  108. package/dist/git/hook-manager.js.map +1 -0
  109. package/dist/git/index.d.ts +4 -0
  110. package/dist/git/index.d.ts.map +1 -0
  111. package/dist/git/index.js +5 -0
  112. package/dist/git/index.js.map +1 -0
  113. package/dist/index.d.ts +8 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +9 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/parsers/feature-validator.d.ts +60 -0
  118. package/dist/parsers/feature-validator.d.ts.map +1 -0
  119. package/dist/parsers/feature-validator.js +483 -0
  120. package/dist/parsers/feature-validator.js.map +1 -0
  121. package/dist/parsers/index.d.ts +8 -0
  122. package/dist/parsers/index.d.ts.map +1 -0
  123. package/dist/parsers/index.js +9 -0
  124. package/dist/parsers/index.js.map +1 -0
  125. package/dist/parsers/parser-manager.d.ts +103 -0
  126. package/dist/parsers/parser-manager.d.ts.map +1 -0
  127. package/dist/parsers/parser-manager.js +321 -0
  128. package/dist/parsers/parser-manager.js.map +1 -0
  129. package/dist/parsers/parser.d.ts +23 -0
  130. package/dist/parsers/parser.d.ts.map +1 -0
  131. package/dist/parsers/parser.js +6 -0
  132. package/dist/parsers/parser.js.map +1 -0
  133. package/dist/parsers/react-parser.d.ts +22 -0
  134. package/dist/parsers/react-parser.d.ts.map +1 -0
  135. package/dist/parsers/react-parser.js +307 -0
  136. package/dist/parsers/react-parser.js.map +1 -0
  137. package/dist/parsers/svelte-parser.d.ts +33 -0
  138. package/dist/parsers/svelte-parser.d.ts.map +1 -0
  139. package/dist/parsers/svelte-parser.js +408 -0
  140. package/dist/parsers/svelte-parser.js.map +1 -0
  141. package/dist/parsers/vanilla-parser.d.ts +31 -0
  142. package/dist/parsers/vanilla-parser.d.ts.map +1 -0
  143. package/dist/parsers/vanilla-parser.js +590 -0
  144. package/dist/parsers/vanilla-parser.js.map +1 -0
  145. package/dist/parsers/vue-parser.d.ts +9 -0
  146. package/dist/parsers/vue-parser.d.ts.map +1 -0
  147. package/dist/parsers/vue-parser.js +16 -0
  148. package/dist/parsers/vue-parser.js.map +1 -0
  149. package/dist/terminal-header.d.ts +12 -0
  150. package/dist/terminal-header.js +45 -0
  151. package/dist/types/index.d.ts +83 -0
  152. package/dist/types/index.d.ts.map +1 -0
  153. package/dist/types/index.js +5 -0
  154. package/dist/types/index.js.map +1 -0
  155. package/dist/ui/components.d.ts +133 -0
  156. package/dist/ui/components.d.ts.map +1 -0
  157. package/dist/ui/components.js +482 -0
  158. package/dist/ui/components.js.map +1 -0
  159. package/dist/ui/help.d.ts +11 -0
  160. package/dist/ui/help.d.ts.map +1 -0
  161. package/dist/ui/help.js +161 -0
  162. package/dist/ui/help.js.map +1 -0
  163. package/dist/ui/index.d.ts +5 -0
  164. package/dist/ui/index.d.ts.map +1 -0
  165. package/dist/ui/index.js +5 -0
  166. package/dist/ui/index.js.map +1 -0
  167. package/dist/ui/prompts.d.ts +63 -0
  168. package/dist/ui/prompts.d.ts.map +1 -0
  169. package/dist/ui/prompts.js +611 -0
  170. package/dist/ui/prompts.js.map +1 -0
  171. package/dist/ui/terminal-header.d.ts +13 -0
  172. package/dist/ui/terminal-header.d.ts.map +1 -0
  173. package/dist/ui/terminal-header.js +46 -0
  174. package/dist/ui/terminal-header.js.map +1 -0
  175. package/package.json +80 -0
  176. package/src/ai/__tests__/gemini-analyzer.test.ts +181 -0
  177. package/src/ai/fix-manager.ts +362 -0
  178. package/src/ai/gemini-analyzer.ts +671 -0
  179. package/src/ai/index.ts +4 -0
  180. package/src/ai/jules-implementer.ts +459 -0
  181. package/src/commands/automation.ts +344 -0
  182. package/src/commands/check.ts +299 -0
  183. package/src/commands/config.ts +365 -0
  184. package/src/commands/fix.ts +234 -0
  185. package/src/commands/index.ts +6 -0
  186. package/src/commands/init.ts +142 -0
  187. package/src/commands/status.ts +0 -0
  188. package/src/core/api-key-manager.ts +298 -0
  189. package/src/core/baseguard.ts +742 -0
  190. package/src/core/baseline-checker.ts +563 -0
  191. package/src/core/cache-manager.ts +270 -0
  192. package/src/core/configuration-recovery.ts +676 -0
  193. package/src/core/configuration.ts +559 -0
  194. package/src/core/debug-logger.ts +590 -0
  195. package/src/core/directory-filter.ts +421 -0
  196. package/src/core/error-handler.ts +517 -0
  197. package/src/core/file-processor.ts +331 -0
  198. package/src/core/gitignore-manager.ts +169 -0
  199. package/src/core/graceful-degradation-manager.ts +596 -0
  200. package/src/core/index.ts +13 -0
  201. package/src/core/lazy-loader.ts +307 -0
  202. package/src/core/logger.ts +0 -0
  203. package/src/core/memory-manager.ts +294 -0
  204. package/src/core/startup-optimizer.ts +173 -0
  205. package/src/core/system-error-handler.ts +746 -0
  206. package/src/git/automation-engine.ts +361 -0
  207. package/src/git/github-manager.ts +260 -0
  208. package/src/git/hook-manager.ts +210 -0
  209. package/src/git/index.ts +4 -0
  210. package/src/index.ts +8 -0
  211. package/src/parsers/feature-validator.ts +559 -0
  212. package/src/parsers/index.ts +8 -0
  213. package/src/parsers/parser-manager.ts +419 -0
  214. package/src/parsers/parser.ts +26 -0
  215. package/src/parsers/react-parser-optimized.ts +161 -0
  216. package/src/parsers/react-parser.ts +359 -0
  217. package/src/parsers/svelte-parser.ts +506 -0
  218. package/src/parsers/vanilla-parser.ts +682 -0
  219. package/src/parsers/vue-parser.ts +472 -0
  220. package/src/types/index.ts +92 -0
  221. package/src/ui/components.ts +567 -0
  222. package/src/ui/help.ts +193 -0
  223. package/src/ui/index.ts +4 -0
  224. package/src/ui/prompts.ts +688 -0
  225. package/src/ui/terminal-header.ts +59 -0
  226. package/test-config-commands.js +56 -0
  227. package/test-header-simple.js +33 -0
  228. package/test-terminal-header.js +12 -0
  229. package/test-ui.js +29 -0
  230. package/tests/e2e/baseguard.e2e.test.ts +516 -0
  231. package/tests/e2e/cross-platform.e2e.test.ts +420 -0
  232. package/tests/e2e/git-integration.e2e.test.ts +487 -0
  233. package/tests/fixtures/react-project/package.json +14 -0
  234. package/tests/fixtures/react-project/src/App.css +76 -0
  235. package/tests/fixtures/react-project/src/App.tsx +77 -0
  236. package/tests/fixtures/svelte-project/package.json +11 -0
  237. package/tests/fixtures/svelte-project/src/App.svelte +369 -0
  238. package/tests/fixtures/vanilla-project/index.html +76 -0
  239. package/tests/fixtures/vanilla-project/script.js +331 -0
  240. package/tests/fixtures/vanilla-project/styles.css +359 -0
  241. package/tests/fixtures/vue-project/package.json +12 -0
  242. package/tests/fixtures/vue-project/src/App.vue +216 -0
  243. package/tsconfig.json +36 -0
  244. package/vitest.config.ts +10 -0
@@ -0,0 +1,270 @@
1
+ import { createHash } from 'crypto';
2
+ import { stat } from 'fs/promises';
3
+ import type { DetectedFeature } from '../types/index.js';
4
+
5
+ /**
6
+ * LRU Cache implementation for web-features data and parsing results
7
+ */
8
+ export class LRUCache<K, V> {
9
+ private cache = new Map<K, V>();
10
+ private readonly maxSize: number;
11
+
12
+ constructor(maxSize: number = 1000) {
13
+ this.maxSize = maxSize;
14
+ }
15
+
16
+ get(key: K): V | undefined {
17
+ const value = this.cache.get(key);
18
+ if (value !== undefined) {
19
+ // Move to end (most recently used)
20
+ this.cache.delete(key);
21
+ this.cache.set(key, value);
22
+ }
23
+ return value;
24
+ }
25
+
26
+ set(key: K, value: V): void {
27
+ if (this.cache.has(key)) {
28
+ this.cache.delete(key);
29
+ } else if (this.cache.size >= this.maxSize) {
30
+ // Remove least recently used (first item)
31
+ const firstKey = this.cache.keys().next().value;
32
+ this.cache.delete(firstKey);
33
+ }
34
+ this.cache.set(key, value);
35
+ }
36
+
37
+ has(key: K): boolean {
38
+ return this.cache.has(key);
39
+ }
40
+
41
+ clear(): void {
42
+ this.cache.clear();
43
+ }
44
+
45
+ size(): number {
46
+ return this.cache.size;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * File metadata for incremental scanning
52
+ */
53
+ interface FileMetadata {
54
+ path: string;
55
+ mtime: number;
56
+ size: number;
57
+ hash: string;
58
+ }
59
+
60
+ /**
61
+ * Cached parsing result
62
+ */
63
+ interface CachedResult {
64
+ features: DetectedFeature[];
65
+ metadata: FileMetadata;
66
+ timestamp: number;
67
+ }
68
+
69
+ /**
70
+ * Cache manager for efficient file processing and incremental scanning
71
+ */
72
+ export class CacheManager {
73
+ private readonly parseCache: LRUCache<string, CachedResult>;
74
+ private readonly webFeaturesCache: LRUCache<string, any>;
75
+ private readonly fileMetadataCache: Map<string, FileMetadata>;
76
+ private readonly maxCacheSize: number;
77
+ private readonly cacheValidityMs: number;
78
+
79
+ constructor(options: {
80
+ maxCacheSize?: number;
81
+ cacheValidityMs?: number;
82
+ } = {}) {
83
+ this.maxCacheSize = options.maxCacheSize || 1000;
84
+ this.cacheValidityMs = options.cacheValidityMs || 5 * 60 * 1000; // 5 minutes
85
+ this.parseCache = new LRUCache(this.maxCacheSize);
86
+ this.webFeaturesCache = new LRUCache(500);
87
+ this.fileMetadataCache = new Map();
88
+ }
89
+
90
+ /**
91
+ * Get cached parsing result if file hasn't changed
92
+ */
93
+ async getCachedParseResult(filePath: string): Promise<DetectedFeature[] | null> {
94
+ try {
95
+ const currentMetadata = await this.getFileMetadata(filePath);
96
+ const cached = this.parseCache.get(filePath);
97
+
98
+ if (!cached) {
99
+ return null;
100
+ }
101
+
102
+ // Check if file has changed
103
+ if (this.hasFileChanged(cached.metadata, currentMetadata)) {
104
+ this.parseCache.set(filePath, { ...cached, metadata: currentMetadata });
105
+ return null;
106
+ }
107
+
108
+ // Check cache validity
109
+ if (Date.now() - cached.timestamp > this.cacheValidityMs) {
110
+ return null;
111
+ }
112
+
113
+ return cached.features;
114
+ } catch (error) {
115
+ // File doesn't exist or can't be accessed
116
+ return null;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Cache parsing result
122
+ */
123
+ async setCachedParseResult(filePath: string, features: DetectedFeature[]): Promise<void> {
124
+ try {
125
+ const metadata = await this.getFileMetadata(filePath);
126
+ const cached: CachedResult = {
127
+ features,
128
+ metadata,
129
+ timestamp: Date.now()
130
+ };
131
+
132
+ this.parseCache.set(filePath, cached);
133
+ this.fileMetadataCache.set(filePath, metadata);
134
+ } catch (error) {
135
+ // Ignore caching errors
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Get cached web-features data
141
+ */
142
+ getCachedWebFeature(featureId: string): any | null {
143
+ return this.webFeaturesCache.get(featureId) || null;
144
+ }
145
+
146
+ /**
147
+ * Cache web-features data
148
+ */
149
+ setCachedWebFeature(featureId: string, data: any): void {
150
+ this.webFeaturesCache.set(featureId, data);
151
+ }
152
+
153
+ /**
154
+ * Check if files have changed since last scan
155
+ */
156
+ async getChangedFiles(filePaths: string[]): Promise<{
157
+ changed: string[];
158
+ unchanged: string[];
159
+ }> {
160
+ const changed: string[] = [];
161
+ const unchanged: string[] = [];
162
+
163
+ await Promise.all(
164
+ filePaths.map(async (filePath) => {
165
+ try {
166
+ const currentMetadata = await this.getFileMetadata(filePath);
167
+ const cachedMetadata = this.fileMetadataCache.get(filePath);
168
+
169
+ if (!cachedMetadata || this.hasFileChanged(cachedMetadata, currentMetadata)) {
170
+ changed.push(filePath);
171
+ this.fileMetadataCache.set(filePath, currentMetadata);
172
+ } else {
173
+ unchanged.push(filePath);
174
+ }
175
+ } catch (error) {
176
+ // File doesn't exist or can't be accessed, consider it changed
177
+ changed.push(filePath);
178
+ }
179
+ })
180
+ );
181
+
182
+ return { changed, unchanged };
183
+ }
184
+
185
+ /**
186
+ * Clear all caches
187
+ */
188
+ clearAll(): void {
189
+ this.parseCache.clear();
190
+ this.webFeaturesCache.clear();
191
+ this.fileMetadataCache.clear();
192
+ }
193
+
194
+ /**
195
+ * Clear expired cache entries
196
+ */
197
+ clearExpired(): void {
198
+ const now = Date.now();
199
+ const expiredKeys: string[] = [];
200
+
201
+ // Find expired parse cache entries
202
+ for (const [key, value] of this.parseCache['cache']) {
203
+ if (now - value.timestamp > this.cacheValidityMs) {
204
+ expiredKeys.push(key);
205
+ }
206
+ }
207
+
208
+ // Remove expired entries
209
+ expiredKeys.forEach(key => {
210
+ this.parseCache['cache'].delete(key);
211
+ this.fileMetadataCache.delete(key);
212
+ });
213
+ }
214
+
215
+ /**
216
+ * Get cache statistics
217
+ */
218
+ getStats(): {
219
+ parseCache: { size: number; maxSize: number };
220
+ webFeaturesCache: { size: number; maxSize: number };
221
+ fileMetadataCache: { size: number };
222
+ } {
223
+ return {
224
+ parseCache: {
225
+ size: this.parseCache.size(),
226
+ maxSize: this.maxCacheSize
227
+ },
228
+ webFeaturesCache: {
229
+ size: this.webFeaturesCache.size(),
230
+ maxSize: 500
231
+ },
232
+ fileMetadataCache: {
233
+ size: this.fileMetadataCache.size
234
+ }
235
+ };
236
+ }
237
+
238
+ /**
239
+ * Get file metadata for change detection
240
+ */
241
+ private async getFileMetadata(filePath: string): Promise<FileMetadata> {
242
+ const stats = await stat(filePath);
243
+ const hash = this.generateFileHash(filePath, stats.mtime.getTime(), stats.size);
244
+
245
+ return {
246
+ path: filePath,
247
+ mtime: stats.mtime.getTime(),
248
+ size: stats.size,
249
+ hash
250
+ };
251
+ }
252
+
253
+ /**
254
+ * Check if file has changed based on metadata
255
+ */
256
+ private hasFileChanged(cached: FileMetadata, current: FileMetadata): boolean {
257
+ return cached.mtime !== current.mtime ||
258
+ cached.size !== current.size ||
259
+ cached.hash !== current.hash;
260
+ }
261
+
262
+ /**
263
+ * Generate hash for file identification
264
+ */
265
+ private generateFileHash(filePath: string, mtime: number, size: number): string {
266
+ return createHash('md5')
267
+ .update(`${filePath}:${mtime}:${size}`)
268
+ .digest('hex');
269
+ }
270
+ }