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.
- package/dashboard/dist/components/AuditPane.d.ts +30 -0
- package/dashboard/dist/components/AuditPane.js +127 -0
- package/dashboard/dist/components/AuditPane.test.d.ts +1 -0
- package/dashboard/dist/components/AuditPane.test.js +339 -0
- package/dashboard/dist/components/CompliancePane.d.ts +39 -0
- package/dashboard/dist/components/CompliancePane.js +96 -0
- package/dashboard/dist/components/CompliancePane.test.d.ts +1 -0
- package/dashboard/dist/components/CompliancePane.test.js +183 -0
- package/dashboard/dist/components/SSOPane.d.ts +36 -0
- package/dashboard/dist/components/SSOPane.js +71 -0
- package/dashboard/dist/components/SSOPane.test.d.ts +1 -0
- package/dashboard/dist/components/SSOPane.test.js +155 -0
- package/dashboard/dist/components/UsagePane.d.ts +13 -0
- package/dashboard/dist/components/UsagePane.js +51 -0
- package/dashboard/dist/components/UsagePane.test.d.ts +1 -0
- package/dashboard/dist/components/UsagePane.test.js +142 -0
- package/dashboard/dist/components/WorkspaceDocsPane.d.ts +19 -0
- package/dashboard/dist/components/WorkspaceDocsPane.js +130 -0
- package/dashboard/dist/components/WorkspaceDocsPane.test.d.ts +1 -0
- package/dashboard/dist/components/WorkspaceDocsPane.test.js +242 -0
- package/dashboard/dist/components/WorkspacePane.d.ts +18 -0
- package/dashboard/dist/components/WorkspacePane.js +17 -0
- package/dashboard/dist/components/WorkspacePane.test.d.ts +1 -0
- package/dashboard/dist/components/WorkspacePane.test.js +84 -0
- package/dashboard/dist/components/ZeroRetentionPane.d.ts +44 -0
- package/dashboard/dist/components/ZeroRetentionPane.js +83 -0
- package/dashboard/dist/components/ZeroRetentionPane.test.d.ts +1 -0
- package/dashboard/dist/components/ZeroRetentionPane.test.js +160 -0
- package/package.json +1 -1
- package/server/lib/access-control-doc.js +541 -0
- package/server/lib/access-control-doc.test.js +672 -0
- package/server/lib/adr-generator.js +423 -0
- package/server/lib/adr-generator.test.js +586 -0
- package/server/lib/agent-progress-monitor.js +223 -0
- package/server/lib/agent-progress-monitor.test.js +202 -0
- package/server/lib/architecture-command.js +450 -0
- package/server/lib/architecture-command.test.js +754 -0
- package/server/lib/ast-analyzer.js +324 -0
- package/server/lib/ast-analyzer.test.js +437 -0
- package/server/lib/audit-attribution.js +191 -0
- package/server/lib/audit-attribution.test.js +359 -0
- package/server/lib/audit-classifier.js +202 -0
- package/server/lib/audit-classifier.test.js +209 -0
- package/server/lib/audit-command.js +275 -0
- package/server/lib/audit-command.test.js +325 -0
- package/server/lib/audit-exporter.js +380 -0
- package/server/lib/audit-exporter.test.js +464 -0
- package/server/lib/audit-logger.js +236 -0
- package/server/lib/audit-logger.test.js +364 -0
- package/server/lib/audit-query.js +257 -0
- package/server/lib/audit-query.test.js +352 -0
- package/server/lib/audit-storage.js +269 -0
- package/server/lib/audit-storage.test.js +272 -0
- package/server/lib/auth-system.test.js +4 -1
- package/server/lib/boundary-detector.js +427 -0
- package/server/lib/boundary-detector.test.js +320 -0
- package/server/lib/budget-alerts.js +138 -0
- package/server/lib/budget-alerts.test.js +235 -0
- package/server/lib/bulk-repo-init.js +342 -0
- package/server/lib/bulk-repo-init.test.js +388 -0
- package/server/lib/candidates-tracker.js +210 -0
- package/server/lib/candidates-tracker.test.js +300 -0
- package/server/lib/checkpoint-manager.js +251 -0
- package/server/lib/checkpoint-manager.test.js +474 -0
- package/server/lib/circular-detector.js +337 -0
- package/server/lib/circular-detector.test.js +353 -0
- package/server/lib/cohesion-analyzer.js +310 -0
- package/server/lib/cohesion-analyzer.test.js +447 -0
- package/server/lib/compliance-checklist.js +866 -0
- package/server/lib/compliance-checklist.test.js +476 -0
- package/server/lib/compliance-command.js +616 -0
- package/server/lib/compliance-command.test.js +551 -0
- package/server/lib/compliance-reporter.js +692 -0
- package/server/lib/compliance-reporter.test.js +707 -0
- package/server/lib/contract-testing.js +625 -0
- package/server/lib/contract-testing.test.js +342 -0
- package/server/lib/conversion-planner.js +469 -0
- package/server/lib/conversion-planner.test.js +361 -0
- package/server/lib/convert-command.js +351 -0
- package/server/lib/convert-command.test.js +608 -0
- package/server/lib/coupling-calculator.js +189 -0
- package/server/lib/coupling-calculator.test.js +509 -0
- package/server/lib/data-flow-doc.js +665 -0
- package/server/lib/data-flow-doc.test.js +659 -0
- package/server/lib/dependency-graph.js +367 -0
- package/server/lib/dependency-graph.test.js +516 -0
- package/server/lib/duplication-detector.js +349 -0
- package/server/lib/duplication-detector.test.js +401 -0
- package/server/lib/ephemeral-storage.js +249 -0
- package/server/lib/ephemeral-storage.test.js +254 -0
- package/server/lib/evidence-collector.js +627 -0
- package/server/lib/evidence-collector.test.js +901 -0
- package/server/lib/example-service.js +616 -0
- package/server/lib/example-service.test.js +397 -0
- package/server/lib/flow-diagram-generator.js +474 -0
- package/server/lib/flow-diagram-generator.test.js +446 -0
- package/server/lib/idp-manager.js +626 -0
- package/server/lib/idp-manager.test.js +587 -0
- package/server/lib/impact-scorer.js +184 -0
- package/server/lib/impact-scorer.test.js +211 -0
- package/server/lib/memory-exclusion.js +326 -0
- package/server/lib/memory-exclusion.test.js +241 -0
- package/server/lib/mermaid-generator.js +358 -0
- package/server/lib/mermaid-generator.test.js +301 -0
- package/server/lib/messaging-patterns.js +750 -0
- package/server/lib/messaging-patterns.test.js +213 -0
- package/server/lib/mfa-handler.js +452 -0
- package/server/lib/mfa-handler.test.js +490 -0
- package/server/lib/microservice-template.js +386 -0
- package/server/lib/microservice-template.test.js +325 -0
- package/server/lib/new-project-microservice.js +450 -0
- package/server/lib/new-project-microservice.test.js +600 -0
- package/server/lib/oauth-flow.js +375 -0
- package/server/lib/oauth-flow.test.js +487 -0
- package/server/lib/oauth-registry.js +190 -0
- package/server/lib/oauth-registry.test.js +306 -0
- package/server/lib/readme-generator.js +490 -0
- package/server/lib/readme-generator.test.js +493 -0
- package/server/lib/refactor-command.js +326 -0
- package/server/lib/refactor-command.test.js +528 -0
- package/server/lib/refactor-executor.js +254 -0
- package/server/lib/refactor-executor.test.js +305 -0
- package/server/lib/refactor-observer.js +292 -0
- package/server/lib/refactor-observer.test.js +422 -0
- package/server/lib/refactor-progress.js +193 -0
- package/server/lib/refactor-progress.test.js +251 -0
- package/server/lib/refactor-reporter.js +237 -0
- package/server/lib/refactor-reporter.test.js +247 -0
- package/server/lib/repo-dependency-tracker.js +261 -0
- package/server/lib/repo-dependency-tracker.test.js +350 -0
- package/server/lib/retention-policy.js +281 -0
- package/server/lib/retention-policy.test.js +486 -0
- package/server/lib/role-mapper.js +236 -0
- package/server/lib/role-mapper.test.js +395 -0
- package/server/lib/saml-provider.js +765 -0
- package/server/lib/saml-provider.test.js +643 -0
- package/server/lib/security-policy-generator.js +682 -0
- package/server/lib/security-policy-generator.test.js +544 -0
- package/server/lib/semantic-analyzer.js +198 -0
- package/server/lib/semantic-analyzer.test.js +474 -0
- package/server/lib/sensitive-detector.js +112 -0
- package/server/lib/sensitive-detector.test.js +209 -0
- package/server/lib/service-interaction-diagram.js +700 -0
- package/server/lib/service-interaction-diagram.test.js +638 -0
- package/server/lib/service-scaffold.js +486 -0
- package/server/lib/service-scaffold.test.js +373 -0
- package/server/lib/service-summary.js +553 -0
- package/server/lib/service-summary.test.js +619 -0
- package/server/lib/session-purge.js +460 -0
- package/server/lib/session-purge.test.js +312 -0
- package/server/lib/shared-kernel.js +578 -0
- package/server/lib/shared-kernel.test.js +255 -0
- package/server/lib/sso-command.js +544 -0
- package/server/lib/sso-command.test.js +552 -0
- package/server/lib/sso-session.js +492 -0
- package/server/lib/sso-session.test.js +670 -0
- package/server/lib/traefik-config.js +282 -0
- package/server/lib/traefik-config.test.js +312 -0
- package/server/lib/usage-command.js +218 -0
- package/server/lib/usage-command.test.js +391 -0
- package/server/lib/usage-formatter.js +192 -0
- package/server/lib/usage-formatter.test.js +267 -0
- package/server/lib/usage-history.js +122 -0
- package/server/lib/usage-history.test.js +206 -0
- package/server/lib/workspace-command.js +249 -0
- package/server/lib/workspace-command.test.js +264 -0
- package/server/lib/workspace-config.js +270 -0
- package/server/lib/workspace-config.test.js +312 -0
- package/server/lib/workspace-docs-command.js +547 -0
- package/server/lib/workspace-docs-command.test.js +692 -0
- package/server/lib/workspace-memory.js +451 -0
- package/server/lib/workspace-memory.test.js +403 -0
- package/server/lib/workspace-scanner.js +452 -0
- package/server/lib/workspace-scanner.test.js +677 -0
- package/server/lib/workspace-test-runner.js +315 -0
- package/server/lib/workspace-test-runner.test.js +294 -0
- package/server/lib/zero-retention-command.js +439 -0
- package/server/lib/zero-retention-command.test.js +448 -0
- package/server/lib/zero-retention.js +322 -0
- package/server/lib/zero-retention.test.js +258 -0
- package/server/package-lock.json +14 -0
- package/server/package.json +1 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface RetentionRule {
|
|
2
|
+
retention: string;
|
|
3
|
+
persist: boolean;
|
|
4
|
+
}
|
|
5
|
+
export interface RetentionPolicy {
|
|
6
|
+
retention?: string;
|
|
7
|
+
persist?: boolean;
|
|
8
|
+
sensitivityLevels?: Record<string, RetentionRule>;
|
|
9
|
+
dataTypes?: Record<string, RetentionRule>;
|
|
10
|
+
}
|
|
11
|
+
export interface PurgeEntry {
|
|
12
|
+
id: string;
|
|
13
|
+
timestamp: string;
|
|
14
|
+
itemCount: number;
|
|
15
|
+
dataTypes: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface SensitiveDataInfo {
|
|
18
|
+
detected: boolean;
|
|
19
|
+
count: number;
|
|
20
|
+
types: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface SubsystemStatus {
|
|
23
|
+
ephemeralStorage?: boolean;
|
|
24
|
+
sessionPurge?: boolean;
|
|
25
|
+
memoryExclusion?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export interface ValidationResult {
|
|
28
|
+
valid: boolean;
|
|
29
|
+
conflicts: string[];
|
|
30
|
+
warnings: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface ZeroRetentionPaneProps {
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
policy?: RetentionPolicy;
|
|
35
|
+
purgeHistory?: PurgeEntry[];
|
|
36
|
+
sensitiveDataDetected?: SensitiveDataInfo;
|
|
37
|
+
subsystems?: SubsystemStatus;
|
|
38
|
+
validation?: ValidationResult;
|
|
39
|
+
isActive?: boolean;
|
|
40
|
+
onToggle?: () => void;
|
|
41
|
+
onPurge?: () => void;
|
|
42
|
+
}
|
|
43
|
+
export declare function ZeroRetentionPane({ enabled, policy, purgeHistory, sensitiveDataDetected, subsystems, validation, isActive, onToggle, onPurge, }: ZeroRetentionPaneProps): import("react/jsx-runtime").JSX.Element;
|
|
44
|
+
export default ZeroRetentionPane;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useInput } from 'ink';
|
|
3
|
+
function formatTimestamp(ts) {
|
|
4
|
+
if (!ts)
|
|
5
|
+
return '';
|
|
6
|
+
try {
|
|
7
|
+
const date = new Date(ts);
|
|
8
|
+
if (isNaN(date.getTime()))
|
|
9
|
+
return '';
|
|
10
|
+
const hours = String(date.getUTCHours()).padStart(2, '0');
|
|
11
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
|
12
|
+
const seconds = String(date.getUTCSeconds()).padStart(2, '0');
|
|
13
|
+
return `${hours}:${minutes}:${seconds}`;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function StatusIndicator({ enabled }) {
|
|
20
|
+
return (_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Status: " }), _jsx(Text, { color: enabled ? 'green' : 'gray', bold: true, children: enabled ? 'ENABLED' : 'DISABLED' })] }));
|
|
21
|
+
}
|
|
22
|
+
function SubsystemsList({ subsystems }) {
|
|
23
|
+
const items = [
|
|
24
|
+
{ key: 'ephemeralStorage', label: 'Ephemeral Storage' },
|
|
25
|
+
{ key: 'sessionPurge', label: 'Session Purge' },
|
|
26
|
+
{ key: 'memoryExclusion', label: 'Memory Exclusion' },
|
|
27
|
+
];
|
|
28
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: "Subsystems:" }), items.map((item) => {
|
|
29
|
+
const active = subsystems[item.key];
|
|
30
|
+
return (_jsx(Box, { children: _jsxs(Text, { color: active ? 'green' : 'gray', children: [active ? ' [x]' : ' [ ]', " ", item.label] }) }, item.key));
|
|
31
|
+
})] }));
|
|
32
|
+
}
|
|
33
|
+
function PolicySummary({ policy }) {
|
|
34
|
+
const rules = [];
|
|
35
|
+
if (policy.retention) {
|
|
36
|
+
rules.push({ label: 'Default', value: policy.retention });
|
|
37
|
+
}
|
|
38
|
+
if (policy.sensitivityLevels) {
|
|
39
|
+
Object.entries(policy.sensitivityLevels).forEach(([level, rule]) => {
|
|
40
|
+
rules.push({ label: level, value: rule.retention });
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (policy.dataTypes) {
|
|
44
|
+
Object.entries(policy.dataTypes).forEach(([type, rule]) => {
|
|
45
|
+
rules.push({ label: type, value: rule.retention });
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: "Policy:" }), rules.length === 0 ? (_jsx(Text, { color: "gray", children: " No policy rules configured" })) : (rules.slice(0, 5).map((rule, idx) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: true, children: [" ", rule.label, ": "] }), _jsx(Text, { color: rule.value === 'immediate' ? 'cyan' : 'white', children: rule.value })] }, idx)))), rules.length > 5 && (_jsxs(Text, { dimColor: true, children: [" ... and ", rules.length - 5, " more rules"] }))] }));
|
|
49
|
+
}
|
|
50
|
+
function PurgeHistory({ entries }) {
|
|
51
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, dimColor: true, children: "Recent Purge Activity:" }), entries.length === 0 ? (_jsx(Text, { color: "gray", children: " No purge history - none yet" })) : (entries.slice(0, 5).map((entry) => {
|
|
52
|
+
const timestamp = formatTimestamp(entry.timestamp);
|
|
53
|
+
return (_jsxs(Box, { children: [timestamp && _jsxs(Text, { dimColor: true, children: [" [", timestamp, "] "] }), _jsxs(Text, { children: ["Purged ", entry.itemCount, " items "] }), _jsxs(Text, { dimColor: true, children: ["(", entry.dataTypes.join(', '), ")"] })] }, entry.id));
|
|
54
|
+
}))] }));
|
|
55
|
+
}
|
|
56
|
+
function SensitiveWarning({ info }) {
|
|
57
|
+
if (!info.detected || info.count === 0) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "yellow", paddingX: 1, children: [_jsx(Box, { children: _jsx(Text, { color: "yellow", bold: true, children: "Warning: Sensitive Data Detected" }) }), _jsx(Box, { children: _jsxs(Text, { color: "yellow", children: ["Found ", info.count, " sensitive item(s): ", info.types.join(', ')] }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: "Enable zero-retention mode to protect this data" }) })] }));
|
|
61
|
+
}
|
|
62
|
+
function ValidationStatus({ validation }) {
|
|
63
|
+
if (validation.valid && validation.warnings.length === 0) {
|
|
64
|
+
return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", children: "Configuration: Valid and OK" }) }));
|
|
65
|
+
}
|
|
66
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [validation.conflicts.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "red", bold: true, children: "Conflicts:" }), validation.conflicts.map((conflict, idx) => (_jsxs(Text, { color: "red", children: [" - ", conflict] }, idx)))] })), validation.warnings.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "yellow", bold: true, children: "Warnings:" }), validation.warnings.map((warning, idx) => (_jsxs(Text, { color: "yellow", children: [" - ", warning] }, idx)))] }))] }));
|
|
67
|
+
}
|
|
68
|
+
export function ZeroRetentionPane({ enabled = false, policy, purgeHistory = [], sensitiveDataDetected, subsystems, validation, isActive = false, onToggle, onPurge, }) {
|
|
69
|
+
useInput((input, _key) => {
|
|
70
|
+
if (!isActive)
|
|
71
|
+
return;
|
|
72
|
+
// Toggle with 't'
|
|
73
|
+
if (input === 't' && onToggle) {
|
|
74
|
+
onToggle();
|
|
75
|
+
}
|
|
76
|
+
// Force purge with 'p'
|
|
77
|
+
if (input === 'p' && onPurge) {
|
|
78
|
+
onPurge();
|
|
79
|
+
}
|
|
80
|
+
}, { isActive });
|
|
81
|
+
return (_jsxs(Box, { padding: 1, flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Zero-Retention Mode" }) }), _jsx(StatusIndicator, { enabled: enabled }), sensitiveDataDetected && (_jsx(SensitiveWarning, { info: sensitiveDataDetected })), validation && _jsx(ValidationStatus, { validation: validation }), subsystems && _jsx(SubsystemsList, { subsystems: subsystems }), policy && _jsx(PolicySummary, { policy: policy }), _jsx(PurgeHistory, { entries: purgeHistory }), isActive && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["[t] Toggle ", enabled ? 'disable' : 'enable', enabled && ' [p] Force purge'] }) }))] }));
|
|
82
|
+
}
|
|
83
|
+
export default ZeroRetentionPane;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
+
import { render } from 'ink-testing-library';
|
|
4
|
+
import { ZeroRetentionPane } from './ZeroRetentionPane.js';
|
|
5
|
+
describe('ZeroRetentionPane', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
vi.useFakeTimers();
|
|
8
|
+
});
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
vi.useRealTimers();
|
|
11
|
+
});
|
|
12
|
+
describe('enabled state', () => {
|
|
13
|
+
it('renders enabled state correctly', () => {
|
|
14
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true }));
|
|
15
|
+
const output = lastFrame();
|
|
16
|
+
expect(output).toContain('Zero-Retention');
|
|
17
|
+
expect(output).toMatch(/enabled|active|on/i);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('disabled state', () => {
|
|
21
|
+
it('renders disabled state correctly', () => {
|
|
22
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: false }));
|
|
23
|
+
const output = lastFrame();
|
|
24
|
+
expect(output).toContain('Zero-Retention');
|
|
25
|
+
expect(output).toMatch(/disabled|inactive|off/i);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
describe('toggle callback', () => {
|
|
29
|
+
it('toggle calls onToggle callback', () => {
|
|
30
|
+
const onToggle = vi.fn();
|
|
31
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: false, isActive: true, onToggle: onToggle }));
|
|
32
|
+
// Verify toggle control is shown when active and onToggle is provided
|
|
33
|
+
const output = lastFrame();
|
|
34
|
+
expect(output).toMatch(/\[t\]|toggle/i);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('retention policy summary', () => {
|
|
38
|
+
it('shows retention policy summary', () => {
|
|
39
|
+
const policy = {
|
|
40
|
+
retention: 'immediate',
|
|
41
|
+
persist: false,
|
|
42
|
+
sensitivityLevels: {
|
|
43
|
+
critical: { retention: 'immediate', persist: false },
|
|
44
|
+
high: { retention: 'immediate', persist: false },
|
|
45
|
+
medium: { retention: 'session', persist: false },
|
|
46
|
+
low: { retention: '24h', persist: true },
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, policy: policy }));
|
|
50
|
+
const output = lastFrame();
|
|
51
|
+
expect(output).toContain('Policy');
|
|
52
|
+
expect(output).toMatch(/immediate|session|purge/i);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('purge activity list', () => {
|
|
56
|
+
it('shows purge activity list', () => {
|
|
57
|
+
const purgeHistory = [
|
|
58
|
+
{
|
|
59
|
+
id: '1',
|
|
60
|
+
timestamp: '2024-01-15T10:30:00.000Z',
|
|
61
|
+
itemCount: 5,
|
|
62
|
+
dataTypes: ['secrets', 'pii'],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: '2',
|
|
66
|
+
timestamp: '2024-01-15T10:35:00.000Z',
|
|
67
|
+
itemCount: 3,
|
|
68
|
+
dataTypes: ['general'],
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, purgeHistory: purgeHistory }));
|
|
72
|
+
const output = lastFrame();
|
|
73
|
+
expect(output).toContain('Purge');
|
|
74
|
+
expect(output).toContain('5');
|
|
75
|
+
expect(output).toContain('3');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe('sensitive data warning', () => {
|
|
79
|
+
it('shows warning for sensitive data', () => {
|
|
80
|
+
const sensitiveDataDetected = {
|
|
81
|
+
detected: true,
|
|
82
|
+
count: 3,
|
|
83
|
+
types: ['api_key', 'password', 'pii'],
|
|
84
|
+
};
|
|
85
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, sensitiveDataDetected: sensitiveDataDetected }));
|
|
86
|
+
const output = lastFrame();
|
|
87
|
+
expect(output).toMatch(/warning|sensitive|detected/i);
|
|
88
|
+
expect(output).toContain('3');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe('empty purge history', () => {
|
|
92
|
+
it('handles empty purge history', () => {
|
|
93
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, purgeHistory: [] }));
|
|
94
|
+
const output = lastFrame();
|
|
95
|
+
expect(output).toContain('Zero-Retention');
|
|
96
|
+
expect(output).toMatch(/no.*purge|empty|none/i);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
describe('policy formatting', () => {
|
|
100
|
+
it('formats policy for display', () => {
|
|
101
|
+
const policy = {
|
|
102
|
+
retention: 'immediate',
|
|
103
|
+
persist: false,
|
|
104
|
+
dataTypes: {
|
|
105
|
+
secrets: { retention: 'immediate', persist: false },
|
|
106
|
+
pii: { retention: 'session', persist: false },
|
|
107
|
+
general: { retention: '7d', persist: true },
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, policy: policy }));
|
|
111
|
+
const output = lastFrame();
|
|
112
|
+
// Should display policy rules in a readable format
|
|
113
|
+
expect(output).toContain('Policy');
|
|
114
|
+
expect(output).toBeDefined();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
describe('subsystem status', () => {
|
|
118
|
+
it('shows subsystem status when provided', () => {
|
|
119
|
+
const subsystems = {
|
|
120
|
+
ephemeralStorage: true,
|
|
121
|
+
sessionPurge: true,
|
|
122
|
+
memoryExclusion: true,
|
|
123
|
+
};
|
|
124
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, subsystems: subsystems }));
|
|
125
|
+
const output = lastFrame();
|
|
126
|
+
expect(output).toMatch(/ephemeral|storage/i);
|
|
127
|
+
expect(output).toMatch(/session|purge/i);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('configuration validation', () => {
|
|
131
|
+
it('shows validation warnings when present', () => {
|
|
132
|
+
const validation = {
|
|
133
|
+
valid: false,
|
|
134
|
+
conflicts: ['Ephemeral storage has basePath set'],
|
|
135
|
+
warnings: ['Audit logging conflicts with zero-retention'],
|
|
136
|
+
};
|
|
137
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, validation: validation }));
|
|
138
|
+
const output = lastFrame();
|
|
139
|
+
expect(output).toMatch(/conflict|warning/i);
|
|
140
|
+
});
|
|
141
|
+
it('shows valid status when no conflicts', () => {
|
|
142
|
+
const validation = {
|
|
143
|
+
valid: true,
|
|
144
|
+
conflicts: [],
|
|
145
|
+
warnings: [],
|
|
146
|
+
};
|
|
147
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: true, validation: validation }));
|
|
148
|
+
const output = lastFrame();
|
|
149
|
+
expect(output).toMatch(/valid|ok|configured/i);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('keyboard controls', () => {
|
|
153
|
+
it('shows controls when active', () => {
|
|
154
|
+
const { lastFrame } = render(_jsx(ZeroRetentionPane, { enabled: false, isActive: true }));
|
|
155
|
+
const output = lastFrame();
|
|
156
|
+
// Should show control hints
|
|
157
|
+
expect(output).toMatch(/\[t\]|toggle|enable|disable/i);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
});
|