Add shared type definitions and sensitive content redactor
Shared module consumed by both the Express server and the React client: types.ts: - ParsedMessage: the normalized message unit (uuid, category, content, toolName, toolInput, timestamp, rawIndex) that the parser emits and every downstream consumer (viewer, filter, export) operates on - MessageCategory: 9-value union covering user_message, assistant_text, thinking, tool_call, tool_result, system_message, hook_progress, file_snapshot, and summary - SessionEntry / SessionListResponse / SessionDetailResponse / ExportRequest: API contract types for the sessions list, session detail, and HTML export endpoints - ALL_CATEGORIES, CATEGORY_LABELS, DEFAULT_HIDDEN_CATEGORIES: constants for the filter panel UI and presets (thinking + hook_progress hidden by default) sensitive-redactor.ts: - 34 regex patterns derived from gitleaks production config, organized into Tier 1 (known secret formats: AWS, GitHub, GitLab, OpenAI, Anthropic, HuggingFace, Perplexity, Stripe, Slack, SendGrid, Twilio, GCP, Azure AD, Heroku, npm, PyPI, Sentry, JWT, PEM private keys, generic API key assignments) and Tier 2 (PII/system info: home directory paths, connection strings, URLs with credentials, email addresses, IPv4 addresses, Bearer tokens, env var secret assignments) - Keyword pre-filtering: each pattern declares keywords that must appear in the text before the expensive regex is evaluated, following the gitleaks performance optimization approach - False-positive allowlists: example/test email domains, localhost/ documentation IPs (RFC 5737), noreply@anthropic.com - Pure functions: redactSensitiveContent returns {sanitized, count, categories}, redactString returns just the string, redactMessage returns a new ParsedMessage with content and toolInput redacted Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
77
src/shared/types.ts
Normal file
77
src/shared/types.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
export type MessageCategory =
|
||||
| "user_message"
|
||||
| "assistant_text"
|
||||
| "thinking"
|
||||
| "tool_call"
|
||||
| "tool_result"
|
||||
| "system_message"
|
||||
| "hook_progress"
|
||||
| "file_snapshot"
|
||||
| "summary";
|
||||
|
||||
export interface ParsedMessage {
|
||||
uuid: string;
|
||||
category: MessageCategory;
|
||||
content: string;
|
||||
toolName?: string;
|
||||
toolInput?: string;
|
||||
timestamp?: string;
|
||||
rawIndex: number;
|
||||
}
|
||||
|
||||
export interface SessionEntry {
|
||||
id: string;
|
||||
summary: string;
|
||||
firstPrompt: string;
|
||||
project: string;
|
||||
created: string;
|
||||
modified: string;
|
||||
messageCount: number;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface SessionListResponse {
|
||||
sessions: SessionEntry[];
|
||||
}
|
||||
|
||||
export interface SessionDetailResponse {
|
||||
id: string;
|
||||
project: string;
|
||||
messages: ParsedMessage[];
|
||||
}
|
||||
|
||||
export interface ExportRequest {
|
||||
session: SessionDetailResponse;
|
||||
visibleMessageUuids: string[];
|
||||
redactedMessageUuids: string[];
|
||||
autoRedactEnabled?: boolean;
|
||||
}
|
||||
|
||||
export const ALL_CATEGORIES: MessageCategory[] = [
|
||||
"user_message",
|
||||
"assistant_text",
|
||||
"thinking",
|
||||
"tool_call",
|
||||
"tool_result",
|
||||
"system_message",
|
||||
"hook_progress",
|
||||
"file_snapshot",
|
||||
"summary",
|
||||
];
|
||||
|
||||
export const CATEGORY_LABELS: Record<MessageCategory, string> = {
|
||||
user_message: "User Messages",
|
||||
assistant_text: "Assistant Text",
|
||||
thinking: "Thinking Blocks",
|
||||
tool_call: "Tool Calls",
|
||||
tool_result: "Tool Results",
|
||||
system_message: "System Messages",
|
||||
hook_progress: "Hook/Progress",
|
||||
file_snapshot: "File Snapshots",
|
||||
summary: "Summaries",
|
||||
};
|
||||
|
||||
export const DEFAULT_HIDDEN_CATEGORIES: MessageCategory[] = [
|
||||
"thinking",
|
||||
"hook_progress",
|
||||
];
|
||||
Reference in New Issue
Block a user