tlc-claude-code 1.2.29 → 1.4.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 (182) hide show
  1. package/dashboard/dist/components/AuditPane.d.ts +30 -0
  2. package/dashboard/dist/components/AuditPane.js +127 -0
  3. package/dashboard/dist/components/AuditPane.test.d.ts +1 -0
  4. package/dashboard/dist/components/AuditPane.test.js +339 -0
  5. package/dashboard/dist/components/CompliancePane.d.ts +39 -0
  6. package/dashboard/dist/components/CompliancePane.js +96 -0
  7. package/dashboard/dist/components/CompliancePane.test.d.ts +1 -0
  8. package/dashboard/dist/components/CompliancePane.test.js +183 -0
  9. package/dashboard/dist/components/SSOPane.d.ts +36 -0
  10. package/dashboard/dist/components/SSOPane.js +71 -0
  11. package/dashboard/dist/components/SSOPane.test.d.ts +1 -0
  12. package/dashboard/dist/components/SSOPane.test.js +155 -0
  13. package/dashboard/dist/components/UsagePane.d.ts +13 -0
  14. package/dashboard/dist/components/UsagePane.js +51 -0
  15. package/dashboard/dist/components/UsagePane.test.d.ts +1 -0
  16. package/dashboard/dist/components/UsagePane.test.js +142 -0
  17. package/dashboard/dist/components/WorkspaceDocsPane.d.ts +19 -0
  18. package/dashboard/dist/components/WorkspaceDocsPane.js +130 -0
  19. package/dashboard/dist/components/WorkspaceDocsPane.test.d.ts +1 -0
  20. package/dashboard/dist/components/WorkspaceDocsPane.test.js +242 -0
  21. package/dashboard/dist/components/WorkspacePane.d.ts +18 -0
  22. package/dashboard/dist/components/WorkspacePane.js +17 -0
  23. package/dashboard/dist/components/WorkspacePane.test.d.ts +1 -0
  24. package/dashboard/dist/components/WorkspacePane.test.js +84 -0
  25. package/dashboard/dist/components/ZeroRetentionPane.d.ts +44 -0
  26. package/dashboard/dist/components/ZeroRetentionPane.js +83 -0
  27. package/dashboard/dist/components/ZeroRetentionPane.test.d.ts +1 -0
  28. package/dashboard/dist/components/ZeroRetentionPane.test.js +160 -0
  29. package/package.json +1 -1
  30. package/server/lib/access-control-doc.js +541 -0
  31. package/server/lib/access-control-doc.test.js +672 -0
  32. package/server/lib/adr-generator.js +423 -0
  33. package/server/lib/adr-generator.test.js +586 -0
  34. package/server/lib/agent-progress-monitor.js +223 -0
  35. package/server/lib/agent-progress-monitor.test.js +202 -0
  36. package/server/lib/architecture-command.js +450 -0
  37. package/server/lib/architecture-command.test.js +754 -0
  38. package/server/lib/ast-analyzer.js +324 -0
  39. package/server/lib/ast-analyzer.test.js +437 -0
  40. package/server/lib/audit-attribution.js +191 -0
  41. package/server/lib/audit-attribution.test.js +359 -0
  42. package/server/lib/audit-classifier.js +202 -0
  43. package/server/lib/audit-classifier.test.js +209 -0
  44. package/server/lib/audit-command.js +275 -0
  45. package/server/lib/audit-command.test.js +325 -0
  46. package/server/lib/audit-exporter.js +380 -0
  47. package/server/lib/audit-exporter.test.js +464 -0
  48. package/server/lib/audit-logger.js +236 -0
  49. package/server/lib/audit-logger.test.js +364 -0
  50. package/server/lib/audit-query.js +257 -0
  51. package/server/lib/audit-query.test.js +352 -0
  52. package/server/lib/audit-storage.js +269 -0
  53. package/server/lib/audit-storage.test.js +272 -0
  54. package/server/lib/auth-system.test.js +4 -1
  55. package/server/lib/boundary-detector.js +427 -0
  56. package/server/lib/boundary-detector.test.js +320 -0
  57. package/server/lib/budget-alerts.js +138 -0
  58. package/server/lib/budget-alerts.test.js +235 -0
  59. package/server/lib/bulk-repo-init.js +342 -0
  60. package/server/lib/bulk-repo-init.test.js +388 -0
  61. package/server/lib/candidates-tracker.js +210 -0
  62. package/server/lib/candidates-tracker.test.js +300 -0
  63. package/server/lib/checkpoint-manager.js +251 -0
  64. package/server/lib/checkpoint-manager.test.js +474 -0
  65. package/server/lib/circular-detector.js +337 -0
  66. package/server/lib/circular-detector.test.js +353 -0
  67. package/server/lib/cohesion-analyzer.js +310 -0
  68. package/server/lib/cohesion-analyzer.test.js +447 -0
  69. package/server/lib/compliance-checklist.js +866 -0
  70. package/server/lib/compliance-checklist.test.js +476 -0
  71. package/server/lib/compliance-command.js +616 -0
  72. package/server/lib/compliance-command.test.js +551 -0
  73. package/server/lib/compliance-reporter.js +692 -0
  74. package/server/lib/compliance-reporter.test.js +707 -0
  75. package/server/lib/contract-testing.js +625 -0
  76. package/server/lib/contract-testing.test.js +342 -0
  77. package/server/lib/conversion-planner.js +469 -0
  78. package/server/lib/conversion-planner.test.js +361 -0
  79. package/server/lib/convert-command.js +351 -0
  80. package/server/lib/convert-command.test.js +608 -0
  81. package/server/lib/coupling-calculator.js +189 -0
  82. package/server/lib/coupling-calculator.test.js +509 -0
  83. package/server/lib/data-flow-doc.js +665 -0
  84. package/server/lib/data-flow-doc.test.js +659 -0
  85. package/server/lib/dependency-graph.js +367 -0
  86. package/server/lib/dependency-graph.test.js +516 -0
  87. package/server/lib/duplication-detector.js +349 -0
  88. package/server/lib/duplication-detector.test.js +401 -0
  89. package/server/lib/ephemeral-storage.js +249 -0
  90. package/server/lib/ephemeral-storage.test.js +254 -0
  91. package/server/lib/evidence-collector.js +627 -0
  92. package/server/lib/evidence-collector.test.js +901 -0
  93. package/server/lib/example-service.js +616 -0
  94. package/server/lib/example-service.test.js +397 -0
  95. package/server/lib/flow-diagram-generator.js +474 -0
  96. package/server/lib/flow-diagram-generator.test.js +446 -0
  97. package/server/lib/idp-manager.js +626 -0
  98. package/server/lib/idp-manager.test.js +587 -0
  99. package/server/lib/impact-scorer.js +184 -0
  100. package/server/lib/impact-scorer.test.js +211 -0
  101. package/server/lib/memory-exclusion.js +326 -0
  102. package/server/lib/memory-exclusion.test.js +241 -0
  103. package/server/lib/mermaid-generator.js +358 -0
  104. package/server/lib/mermaid-generator.test.js +301 -0
  105. package/server/lib/messaging-patterns.js +750 -0
  106. package/server/lib/messaging-patterns.test.js +213 -0
  107. package/server/lib/mfa-handler.js +452 -0
  108. package/server/lib/mfa-handler.test.js +490 -0
  109. package/server/lib/microservice-template.js +386 -0
  110. package/server/lib/microservice-template.test.js +325 -0
  111. package/server/lib/new-project-microservice.js +450 -0
  112. package/server/lib/new-project-microservice.test.js +600 -0
  113. package/server/lib/oauth-flow.js +375 -0
  114. package/server/lib/oauth-flow.test.js +487 -0
  115. package/server/lib/oauth-registry.js +190 -0
  116. package/server/lib/oauth-registry.test.js +306 -0
  117. package/server/lib/readme-generator.js +490 -0
  118. package/server/lib/readme-generator.test.js +493 -0
  119. package/server/lib/refactor-command.js +326 -0
  120. package/server/lib/refactor-command.test.js +528 -0
  121. package/server/lib/refactor-executor.js +254 -0
  122. package/server/lib/refactor-executor.test.js +305 -0
  123. package/server/lib/refactor-observer.js +292 -0
  124. package/server/lib/refactor-observer.test.js +422 -0
  125. package/server/lib/refactor-progress.js +193 -0
  126. package/server/lib/refactor-progress.test.js +251 -0
  127. package/server/lib/refactor-reporter.js +237 -0
  128. package/server/lib/refactor-reporter.test.js +247 -0
  129. package/server/lib/repo-dependency-tracker.js +261 -0
  130. package/server/lib/repo-dependency-tracker.test.js +350 -0
  131. package/server/lib/retention-policy.js +281 -0
  132. package/server/lib/retention-policy.test.js +486 -0
  133. package/server/lib/role-mapper.js +236 -0
  134. package/server/lib/role-mapper.test.js +395 -0
  135. package/server/lib/saml-provider.js +765 -0
  136. package/server/lib/saml-provider.test.js +643 -0
  137. package/server/lib/security-policy-generator.js +682 -0
  138. package/server/lib/security-policy-generator.test.js +544 -0
  139. package/server/lib/semantic-analyzer.js +198 -0
  140. package/server/lib/semantic-analyzer.test.js +474 -0
  141. package/server/lib/sensitive-detector.js +112 -0
  142. package/server/lib/sensitive-detector.test.js +209 -0
  143. package/server/lib/service-interaction-diagram.js +700 -0
  144. package/server/lib/service-interaction-diagram.test.js +638 -0
  145. package/server/lib/service-scaffold.js +486 -0
  146. package/server/lib/service-scaffold.test.js +373 -0
  147. package/server/lib/service-summary.js +553 -0
  148. package/server/lib/service-summary.test.js +619 -0
  149. package/server/lib/session-purge.js +460 -0
  150. package/server/lib/session-purge.test.js +312 -0
  151. package/server/lib/shared-kernel.js +578 -0
  152. package/server/lib/shared-kernel.test.js +255 -0
  153. package/server/lib/sso-command.js +544 -0
  154. package/server/lib/sso-command.test.js +552 -0
  155. package/server/lib/sso-session.js +492 -0
  156. package/server/lib/sso-session.test.js +670 -0
  157. package/server/lib/traefik-config.js +282 -0
  158. package/server/lib/traefik-config.test.js +312 -0
  159. package/server/lib/usage-command.js +218 -0
  160. package/server/lib/usage-command.test.js +391 -0
  161. package/server/lib/usage-formatter.js +192 -0
  162. package/server/lib/usage-formatter.test.js +267 -0
  163. package/server/lib/usage-history.js +122 -0
  164. package/server/lib/usage-history.test.js +206 -0
  165. package/server/lib/workspace-command.js +249 -0
  166. package/server/lib/workspace-command.test.js +264 -0
  167. package/server/lib/workspace-config.js +270 -0
  168. package/server/lib/workspace-config.test.js +312 -0
  169. package/server/lib/workspace-docs-command.js +547 -0
  170. package/server/lib/workspace-docs-command.test.js +692 -0
  171. package/server/lib/workspace-memory.js +451 -0
  172. package/server/lib/workspace-memory.test.js +403 -0
  173. package/server/lib/workspace-scanner.js +452 -0
  174. package/server/lib/workspace-scanner.test.js +677 -0
  175. package/server/lib/workspace-test-runner.js +315 -0
  176. package/server/lib/workspace-test-runner.test.js +294 -0
  177. package/server/lib/zero-retention-command.js +439 -0
  178. package/server/lib/zero-retention-command.test.js +448 -0
  179. package/server/lib/zero-retention.js +322 -0
  180. package/server/lib/zero-retention.test.js +258 -0
  181. package/server/package-lock.json +14 -0
  182. package/server/package.json +1 -0
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Dependency Graph Builder
3
+ * Build file dependency graph from import/require statements
4
+ */
5
+
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+
9
+ class DependencyGraph {
10
+ constructor(options = {}) {
11
+ this.options = options;
12
+ this.basePath = options.basePath || process.cwd();
13
+ this.extensions = options.extensions || ['.js', '.ts', '.jsx', '.tsx', '.mjs'];
14
+ this.tsConfigPaths = options.tsConfigPaths || {};
15
+ this.graph = new Map(); // file -> { imports: [], importedBy: [] }
16
+ this.external = new Set(); // node_modules dependencies
17
+ }
18
+
19
+ /**
20
+ * Build dependency graph from entry points or directory
21
+ */
22
+ async build(entryPoints) {
23
+ const files = Array.isArray(entryPoints) ? entryPoints : [entryPoints];
24
+ const visited = new Set();
25
+
26
+ for (const file of files) {
27
+ await this.processFile(file, visited);
28
+ }
29
+
30
+ return this.getGraph();
31
+ }
32
+
33
+ /**
34
+ * Build graph from all files in a directory
35
+ */
36
+ async buildFromDirectory(dir, options = {}) {
37
+ const { ignore = ['node_modules', '.git', 'dist', 'build'] } = options;
38
+ const files = await this.findFiles(dir, ignore);
39
+
40
+ for (const file of files) {
41
+ await this.processFile(file, new Set());
42
+ }
43
+
44
+ return this.getGraph();
45
+ }
46
+
47
+ /**
48
+ * Find all source files in directory
49
+ */
50
+ async findFiles(dir, ignore = []) {
51
+ const results = [];
52
+ const readDir = this.options.readDir || fs.promises.readdir;
53
+ const stat = this.options.stat || fs.promises.stat;
54
+
55
+ const scan = async (currentDir) => {
56
+ const entries = await readDir(currentDir, { withFileTypes: true });
57
+
58
+ for (const entry of entries) {
59
+ const fullPath = path.join(currentDir, entry.name);
60
+
61
+ if (ignore.some(pattern => fullPath.includes(pattern))) {
62
+ continue;
63
+ }
64
+
65
+ if (entry.isDirectory()) {
66
+ await scan(fullPath);
67
+ } else if (this.extensions.some(ext => entry.name.endsWith(ext))) {
68
+ results.push(fullPath);
69
+ }
70
+ }
71
+ };
72
+
73
+ await scan(dir);
74
+ return results;
75
+ }
76
+
77
+ /**
78
+ * Process a single file
79
+ */
80
+ async processFile(filePath, visited) {
81
+ const absolutePath = path.isAbsolute(filePath)
82
+ ? filePath
83
+ : path.resolve(this.basePath, filePath);
84
+
85
+ if (visited.has(absolutePath)) {
86
+ return; // Prevent infinite loops on circular deps
87
+ }
88
+
89
+ visited.add(absolutePath);
90
+
91
+ if (!this.graph.has(absolutePath)) {
92
+ this.graph.set(absolutePath, { imports: [], importedBy: [] });
93
+ }
94
+
95
+ try {
96
+ const content = await this.readFile(absolutePath);
97
+ const imports = this.parseImports(content, absolutePath);
98
+
99
+ for (const imp of imports) {
100
+ const resolved = this.resolveImport(imp, absolutePath);
101
+
102
+ if (resolved.external) {
103
+ this.external.add(resolved.module);
104
+ continue;
105
+ }
106
+
107
+ if (resolved.path) {
108
+ // Add to graph
109
+ this.graph.get(absolutePath).imports.push(resolved.path);
110
+
111
+ if (!this.graph.has(resolved.path)) {
112
+ this.graph.set(resolved.path, { imports: [], importedBy: [] });
113
+ }
114
+ this.graph.get(resolved.path).importedBy.push(absolutePath);
115
+
116
+ // Recursively process
117
+ await this.processFile(resolved.path, visited);
118
+ }
119
+ }
120
+ } catch (error) {
121
+ // File doesn't exist or can't be read
122
+ if (this.options.verbose) {
123
+ console.error(`Error processing ${absolutePath}:`, error.message);
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Read file content
130
+ */
131
+ async readFile(filePath) {
132
+ const readFile = this.options.readFile || fs.promises.readFile;
133
+ return await readFile(filePath, 'utf-8');
134
+ }
135
+
136
+ /**
137
+ * Parse import statements from code
138
+ */
139
+ parseImports(code, filePath) {
140
+ const imports = [];
141
+
142
+ // ES6 imports: import x from 'y', import { x } from 'y', import 'y'
143
+ const es6Regex = /import\s+(?:(?:[\w*{}\s,]+)\s+from\s+)?['"]([^'"]+)['"]/g;
144
+ let match;
145
+ while ((match = es6Regex.exec(code)) !== null) {
146
+ imports.push({ type: 'es6', module: match[1], raw: match[0] });
147
+ }
148
+
149
+ // CommonJS: require('x'), require("x")
150
+ const cjsRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
151
+ while ((match = cjsRegex.exec(code)) !== null) {
152
+ imports.push({ type: 'commonjs', module: match[1], raw: match[0] });
153
+ }
154
+
155
+ // Dynamic imports: import('x')
156
+ const dynamicRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
157
+ while ((match = dynamicRegex.exec(code)) !== null) {
158
+ imports.push({ type: 'dynamic', module: match[1], raw: match[0] });
159
+ }
160
+
161
+ // Export from: export { x } from 'y'
162
+ const exportFromRegex = /export\s+(?:[\w*{}\s,]+)\s+from\s+['"]([^'"]+)['"]/g;
163
+ while ((match = exportFromRegex.exec(code)) !== null) {
164
+ imports.push({ type: 'export-from', module: match[1], raw: match[0] });
165
+ }
166
+
167
+ return imports;
168
+ }
169
+
170
+ /**
171
+ * Resolve import path to absolute path
172
+ */
173
+ resolveImport(imp, fromFile) {
174
+ const modulePath = imp.module;
175
+
176
+ // Check if external (node_modules)
177
+ if (!modulePath.startsWith('.') && !modulePath.startsWith('/')) {
178
+ // Check tsconfig paths first
179
+ const aliasResolved = this.resolveAlias(modulePath);
180
+ if (aliasResolved) {
181
+ return { path: aliasResolved, external: false };
182
+ }
183
+
184
+ return { module: modulePath.split('/')[0], external: true };
185
+ }
186
+
187
+ // Relative path
188
+ const fromDir = path.dirname(fromFile);
189
+ let resolved = path.resolve(fromDir, modulePath);
190
+
191
+ // Try adding extensions
192
+ resolved = this.resolveExtension(resolved);
193
+
194
+ return { path: resolved, external: false };
195
+ }
196
+
197
+ /**
198
+ * Resolve TypeScript path aliases
199
+ */
200
+ resolveAlias(modulePath) {
201
+ for (const [alias, paths] of Object.entries(this.tsConfigPaths)) {
202
+ const pattern = alias.replace('*', '(.*)');
203
+ const regex = new RegExp(`^${pattern}$`);
204
+ const match = modulePath.match(regex);
205
+
206
+ if (match) {
207
+ const replacement = paths[0].replace('*', match[1] || '');
208
+ return path.resolve(this.basePath, replacement);
209
+ }
210
+ }
211
+ return null;
212
+ }
213
+
214
+ /**
215
+ * Try resolving with different extensions
216
+ */
217
+ resolveExtension(filePath) {
218
+ // Already has extension
219
+ if (this.extensions.some(ext => filePath.endsWith(ext))) {
220
+ return filePath;
221
+ }
222
+
223
+ // Try each extension
224
+ for (const ext of this.extensions) {
225
+ const withExt = filePath + ext;
226
+ if (this.fileExists(withExt)) {
227
+ return withExt;
228
+ }
229
+ }
230
+
231
+ // Try index files
232
+ for (const ext of this.extensions) {
233
+ const indexFile = path.join(filePath, `index${ext}`);
234
+ if (this.fileExists(indexFile)) {
235
+ return indexFile;
236
+ }
237
+ }
238
+
239
+ // Return original with first extension as fallback
240
+ return filePath + this.extensions[0];
241
+ }
242
+
243
+ /**
244
+ * Check if file exists
245
+ */
246
+ fileExists(filePath) {
247
+ if (this.options.fileExists) {
248
+ return this.options.fileExists(filePath);
249
+ }
250
+ try {
251
+ fs.accessSync(filePath);
252
+ return true;
253
+ } catch {
254
+ return false;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Get the built graph
260
+ */
261
+ getGraph() {
262
+ const nodes = [];
263
+ const edges = [];
264
+
265
+ for (const [file, data] of this.graph.entries()) {
266
+ nodes.push({
267
+ id: file,
268
+ name: path.relative(this.basePath, file),
269
+ imports: data.imports.length,
270
+ importedBy: data.importedBy.length,
271
+ });
272
+
273
+ for (const imp of data.imports) {
274
+ edges.push({
275
+ from: file,
276
+ to: imp,
277
+ fromName: path.relative(this.basePath, file),
278
+ toName: path.relative(this.basePath, imp),
279
+ });
280
+ }
281
+ }
282
+
283
+ return {
284
+ nodes,
285
+ edges,
286
+ external: Array.from(this.external),
287
+ stats: {
288
+ totalFiles: nodes.length,
289
+ totalEdges: edges.length,
290
+ externalDeps: this.external.size,
291
+ },
292
+ };
293
+ }
294
+
295
+ /**
296
+ * Get files that import a given file
297
+ */
298
+ getImporters(filePath) {
299
+ const absolute = path.isAbsolute(filePath)
300
+ ? filePath
301
+ : path.resolve(this.basePath, filePath);
302
+
303
+ const node = this.graph.get(absolute);
304
+ return node ? node.importedBy : [];
305
+ }
306
+
307
+ /**
308
+ * Get files that a given file imports
309
+ */
310
+ getImports(filePath) {
311
+ const absolute = path.isAbsolute(filePath)
312
+ ? filePath
313
+ : path.resolve(this.basePath, filePath);
314
+
315
+ const node = this.graph.get(absolute);
316
+ return node ? node.imports : [];
317
+ }
318
+
319
+ /**
320
+ * Check if graph has circular dependencies
321
+ */
322
+ hasCircular() {
323
+ const visited = new Set();
324
+ const stack = new Set();
325
+
326
+ const dfs = (node) => {
327
+ if (stack.has(node)) return true;
328
+ if (visited.has(node)) return false;
329
+
330
+ visited.add(node);
331
+ stack.add(node);
332
+
333
+ const data = this.graph.get(node);
334
+ if (data) {
335
+ for (const imp of data.imports) {
336
+ if (dfs(imp)) return true;
337
+ }
338
+ }
339
+
340
+ stack.delete(node);
341
+ return false;
342
+ };
343
+
344
+ for (const node of this.graph.keys()) {
345
+ if (dfs(node)) return true;
346
+ }
347
+
348
+ return false;
349
+ }
350
+
351
+ /**
352
+ * Get all files in the graph
353
+ */
354
+ getFiles() {
355
+ return Array.from(this.graph.keys());
356
+ }
357
+
358
+ /**
359
+ * Clear the graph
360
+ */
361
+ clear() {
362
+ this.graph.clear();
363
+ this.external.clear();
364
+ }
365
+ }
366
+
367
+ module.exports = { DependencyGraph };