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,112 @@
1
+ /**
2
+ * Sensitive Data Detector Module
3
+ * Detects and classifies sensitive data types like API keys, PII, and secrets
4
+ */
5
+
6
+ /**
7
+ * Patterns for detecting sensitive data
8
+ */
9
+ const PATTERNS = {
10
+ // API Keys and Tokens
11
+ openai_api_key: /sk-[a-zA-Z0-9]{32,}/g,
12
+ aws_access_key: /AKIA[0-9A-Z]{16}/g,
13
+ github_token: /ghp_[a-zA-Z0-9]{36,}/g,
14
+ github_pat: /github_pat_[a-zA-Z0-9_]{22,}/g,
15
+
16
+ // Private Keys
17
+ private_key: /-----BEGIN (RSA |OPENSSH |EC |DSA |PGP )?PRIVATE KEY-----/g,
18
+
19
+ // Passwords in config files
20
+ password: /(?:password|passwd|pwd|secret|api_key|apikey|auth_token|access_token)[=:]\s*["']?([^"'\s\n]+)["']?/gi,
21
+
22
+ // PII
23
+ ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
24
+ credit_card: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
25
+ email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
26
+ phone_number: /(?:\(\d{3}\)\s*|\b\d{3}[-.])\d{3}[-.]?\d{4}\b/g,
27
+ };
28
+
29
+ /**
30
+ * Sensitivity levels for different data types
31
+ */
32
+ const SENSITIVITY_LEVELS = {
33
+ // Critical - secrets that can lead to unauthorized access
34
+ openai_api_key: 'critical',
35
+ aws_access_key: 'critical',
36
+ github_token: 'critical',
37
+ github_pat: 'critical',
38
+ private_key: 'critical',
39
+ password: 'critical',
40
+
41
+ // High - sensitive PII
42
+ ssn: 'high',
43
+ credit_card: 'high',
44
+
45
+ // Medium - contact information
46
+ email: 'medium',
47
+ phone_number: 'medium',
48
+ };
49
+
50
+ /**
51
+ * Detect sensitive data in content
52
+ * @param {string} content - The content to scan
53
+ * @returns {Array<{type: string, match: string, index: number}>} Array of detected sensitive items
54
+ */
55
+ function detectSensitive(content) {
56
+ const results = [];
57
+
58
+ for (const [type, pattern] of Object.entries(PATTERNS)) {
59
+ // Reset regex lastIndex for global patterns
60
+ pattern.lastIndex = 0;
61
+
62
+ let match;
63
+ while ((match = pattern.exec(content)) !== null) {
64
+ results.push({
65
+ type,
66
+ match: match[0],
67
+ index: match.index,
68
+ });
69
+ }
70
+ }
71
+
72
+ // Sort by index for consistent ordering
73
+ results.sort((a, b) => a.index - b.index);
74
+
75
+ return results;
76
+ }
77
+
78
+ /**
79
+ * Get the sensitivity level for a given data type
80
+ * @param {string} type - The type of sensitive data
81
+ * @returns {string} Sensitivity level: 'critical', 'high', 'medium', or 'low'
82
+ */
83
+ function getSensitivityLevel(type) {
84
+ return SENSITIVITY_LEVELS[type] || 'low';
85
+ }
86
+
87
+ /**
88
+ * Classify a string to determine its sensitive data type
89
+ * @param {string} value - The string to classify
90
+ * @returns {string|null} The type of sensitive data, or null if not sensitive
91
+ */
92
+ function classifyType(value) {
93
+ // Check each pattern to find a match
94
+ for (const [type, pattern] of Object.entries(PATTERNS)) {
95
+ // Reset regex lastIndex
96
+ pattern.lastIndex = 0;
97
+
98
+ if (pattern.test(value)) {
99
+ return type;
100
+ }
101
+ }
102
+
103
+ return null;
104
+ }
105
+
106
+ module.exports = {
107
+ detectSensitive,
108
+ getSensitivityLevel,
109
+ classifyType,
110
+ PATTERNS,
111
+ SENSITIVITY_LEVELS,
112
+ };
@@ -0,0 +1,209 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ detectSensitive,
4
+ getSensitivityLevel,
5
+ classifyType,
6
+ } from './sensitive-detector.js';
7
+
8
+ describe('sensitive-detector', () => {
9
+ describe('detectSensitive', () => {
10
+ it('identifies OpenAI API keys (sk-...)', () => {
11
+ const content = 'OPENAI_KEY=sk-1234567890abcdefghijklmnopqrstuvwxyz12345678';
12
+ const result = detectSensitive(content);
13
+
14
+ expect(result).toHaveLength(1);
15
+ expect(result[0].type).toBe('openai_api_key');
16
+ expect(result[0].match).toContain('sk-');
17
+ });
18
+
19
+ it('identifies AWS credentials (AKIA...)', () => {
20
+ const content = 'aws_access_key_id = AKIAIOSFODNN7EXAMPLE';
21
+ const result = detectSensitive(content);
22
+
23
+ expect(result).toHaveLength(1);
24
+ expect(result[0].type).toBe('aws_access_key');
25
+ expect(result[0].match).toContain('AKIA');
26
+ });
27
+
28
+ it('identifies GitHub tokens (ghp_...)', () => {
29
+ const content = 'GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
30
+ const result = detectSensitive(content);
31
+
32
+ expect(result).toHaveLength(1);
33
+ expect(result[0].type).toBe('github_token');
34
+ expect(result[0].match).toContain('ghp_');
35
+ });
36
+
37
+ it('identifies GitHub personal access tokens (github_pat_...)', () => {
38
+ const content = 'TOKEN=github_pat_11ABCDEFG_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
39
+ const result = detectSensitive(content);
40
+
41
+ expect(result).toHaveLength(1);
42
+ expect(result[0].type).toBe('github_pat');
43
+ expect(result[0].match).toContain('github_pat_');
44
+ });
45
+
46
+ it('identifies passwords in config', () => {
47
+ const content = `
48
+ db_password: "super_secret_123"
49
+ password=mysecretpassword
50
+ MYSQL_ROOT_PASSWORD=rootpass
51
+ `;
52
+ const result = detectSensitive(content);
53
+
54
+ expect(result.length).toBeGreaterThanOrEqual(3);
55
+ const passwordMatches = result.filter(r => r.type === 'password');
56
+ expect(passwordMatches.length).toBeGreaterThanOrEqual(3);
57
+ });
58
+
59
+ it('identifies email addresses', () => {
60
+ const content = 'Contact us at user@example.com or support@company.org';
61
+ const result = detectSensitive(content);
62
+
63
+ expect(result.length).toBeGreaterThanOrEqual(2);
64
+ const emails = result.filter(r => r.type === 'email');
65
+ expect(emails.length).toBeGreaterThanOrEqual(2);
66
+ expect(emails.some(e => e.match.includes('user@example.com'))).toBe(true);
67
+ expect(emails.some(e => e.match.includes('support@company.org'))).toBe(true);
68
+ });
69
+
70
+ it('identifies phone numbers', () => {
71
+ const content = 'Call us at 555-123-4567 or (555) 987-6543';
72
+ const result = detectSensitive(content);
73
+
74
+ expect(result.length).toBeGreaterThanOrEqual(2);
75
+ const phones = result.filter(r => r.type === 'phone_number');
76
+ expect(phones.length).toBeGreaterThanOrEqual(2);
77
+ });
78
+
79
+ it('identifies SSN patterns (XXX-XX-XXXX)', () => {
80
+ const content = 'SSN: 123-45-6789';
81
+ const result = detectSensitive(content);
82
+
83
+ expect(result).toHaveLength(1);
84
+ expect(result[0].type).toBe('ssn');
85
+ expect(result[0].match).toContain('123-45-6789');
86
+ });
87
+
88
+ it('identifies credit card numbers', () => {
89
+ const content = 'Card: 4111-1111-1111-1111 or 5500 0000 0000 0004';
90
+ const result = detectSensitive(content);
91
+
92
+ expect(result.length).toBeGreaterThanOrEqual(2);
93
+ const cards = result.filter(r => r.type === 'credit_card');
94
+ expect(cards.length).toBeGreaterThanOrEqual(2);
95
+ });
96
+
97
+ it('identifies RSA private keys', () => {
98
+ const content = `
99
+ -----BEGIN RSA PRIVATE KEY-----
100
+ MIIEpAIBAAKCAQEAx...
101
+ -----END RSA PRIVATE KEY-----
102
+ `;
103
+ const result = detectSensitive(content);
104
+
105
+ expect(result).toHaveLength(1);
106
+ expect(result[0].type).toBe('private_key');
107
+ expect(result[0].match).toContain('BEGIN RSA PRIVATE KEY');
108
+ });
109
+
110
+ it('identifies SSH private keys', () => {
111
+ const content = `
112
+ -----BEGIN OPENSSH PRIVATE KEY-----
113
+ b3BlbnNzaC1rZXktdjEAAAAA...
114
+ -----END OPENSSH PRIVATE KEY-----
115
+ `;
116
+ const result = detectSensitive(content);
117
+
118
+ expect(result).toHaveLength(1);
119
+ expect(result[0].type).toBe('private_key');
120
+ expect(result[0].match).toContain('BEGIN OPENSSH PRIVATE KEY');
121
+ });
122
+
123
+ it('returns empty array for content with no sensitive data', () => {
124
+ const content = 'This is just regular text with no secrets.';
125
+ const result = detectSensitive(content);
126
+
127
+ expect(result).toHaveLength(0);
128
+ });
129
+
130
+ it('identifies multiple sensitive items in same content', () => {
131
+ const content = `
132
+ API_KEY=sk-1234567890abcdefghijklmnopqrstuvwxyz12345678
133
+ EMAIL=user@example.com
134
+ SSN: 123-45-6789
135
+ `;
136
+ const result = detectSensitive(content);
137
+
138
+ expect(result.length).toBeGreaterThanOrEqual(3);
139
+ });
140
+ });
141
+
142
+ describe('getSensitivityLevel', () => {
143
+ it("returns 'critical' for secrets", () => {
144
+ expect(getSensitivityLevel('openai_api_key')).toBe('critical');
145
+ expect(getSensitivityLevel('aws_access_key')).toBe('critical');
146
+ expect(getSensitivityLevel('github_token')).toBe('critical');
147
+ expect(getSensitivityLevel('github_pat')).toBe('critical');
148
+ expect(getSensitivityLevel('private_key')).toBe('critical');
149
+ expect(getSensitivityLevel('password')).toBe('critical');
150
+ });
151
+
152
+ it("returns 'high' for PII", () => {
153
+ expect(getSensitivityLevel('ssn')).toBe('high');
154
+ expect(getSensitivityLevel('credit_card')).toBe('high');
155
+ });
156
+
157
+ it("returns 'medium' for contact info", () => {
158
+ expect(getSensitivityLevel('email')).toBe('medium');
159
+ expect(getSensitivityLevel('phone_number')).toBe('medium');
160
+ });
161
+
162
+ it("returns 'low' for unknown types", () => {
163
+ expect(getSensitivityLevel('unknown_type')).toBe('low');
164
+ });
165
+ });
166
+
167
+ describe('classifyType', () => {
168
+ it('returns correct type for OpenAI API key', () => {
169
+ expect(classifyType('sk-1234567890abcdefghijklmnopqrstuvwxyz12345678')).toBe('openai_api_key');
170
+ });
171
+
172
+ it('returns correct type for AWS access key', () => {
173
+ expect(classifyType('AKIAIOSFODNN7EXAMPLE')).toBe('aws_access_key');
174
+ });
175
+
176
+ it('returns correct type for GitHub token', () => {
177
+ expect(classifyType('ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')).toBe('github_token');
178
+ });
179
+
180
+ it('returns correct type for GitHub PAT', () => {
181
+ expect(classifyType('github_pat_11ABCDEFG_xxxxxxxxxxxxxxxx')).toBe('github_pat');
182
+ });
183
+
184
+ it('returns correct type for email', () => {
185
+ expect(classifyType('user@example.com')).toBe('email');
186
+ });
187
+
188
+ it('returns correct type for phone number', () => {
189
+ expect(classifyType('555-123-4567')).toBe('phone_number');
190
+ });
191
+
192
+ it('returns correct type for SSN', () => {
193
+ expect(classifyType('123-45-6789')).toBe('ssn');
194
+ });
195
+
196
+ it('returns correct type for credit card', () => {
197
+ expect(classifyType('4111-1111-1111-1111')).toBe('credit_card');
198
+ });
199
+
200
+ it('returns correct type for private key header', () => {
201
+ expect(classifyType('-----BEGIN RSA PRIVATE KEY-----')).toBe('private_key');
202
+ expect(classifyType('-----BEGIN OPENSSH PRIVATE KEY-----')).toBe('private_key');
203
+ });
204
+
205
+ it('returns null for non-sensitive content', () => {
206
+ expect(classifyType('just normal text')).toBeNull();
207
+ });
208
+ });
209
+ });