refactor: extract shared AI chat components and hooks from views#59
Merged
2witstudios merged 4 commits intomasterfrom Nov 27, 2025
Merged
Conversation
Major refactoring to consolidate duplicated code between GlobalAssistantView and AiChatView into shared infrastructure: Shared Hooks (lib/ai/shared/hooks/): - useMCPTools: MCP tool fetching and state management - useConversations: Conversation CRUD operations - useMessageActions: Edit, delete, retry message handlers - useProviderSettings: AI provider configuration loading Shared Components (components/ai/chat/): - MCPToggle: MCP enable/disable toggle - ChatMessagesArea: Scrollable message display with loading skeleton - ChatInputArea: Input area with error display and send/stop buttons - StreamingIndicator: "Thinking..." indicator during AI response - ProviderSetupCard: API key setup prompt Shared Types (lib/ai/shared/): - ProviderSettings, MCPToolSchema, ConversationData types - getAIErrorMessage utility for user-friendly error messages Results: - GlobalAssistantView: 1377 → 746 lines (46% reduction) - AiChatView: 985 → 451 lines (54% reduction) - Total saved: ~1165 lines of duplicated code This establishes an engine-centric architecture where Agent (AI_CHAT pages) and Global Assistant engines share common chat infrastructure while maintaining their distinct behaviors.
Enable rich message rendering (todo lists, socket updates) in Global Assistant by using ConversationMessageRenderer instead of plain MessageRenderer. Both agent mode and global mode now have the same rendering capabilities as AiChatView.
- Change useConversationRenderer default from false to true
- ConversationMessageRenderer provides todo list support and socket
real-time updates, which should be the standard for all chat views
- Remove redundant explicit useConversationRenderer={true} props
from GlobalAssistantView and AiChatView
- Update prop documentation to clarify the default behavior
Eliminates the wrapper pattern by merging todo list support and socket real-time updates directly into the base renderers: - MessageRenderer now handles both standard and todo_list messages - CompactMessageRenderer now handles both standard and todo_list messages - Delete ConversationMessageRenderer.tsx (was wrapper around MessageRenderer) - Delete CompactConversationMessageRenderer.tsx (was wrapper around CompactMessageRenderer) - Update ChatMessagesArea to use MessageRenderer directly (remove toggle) - Update AssistantChatTab to use CompactMessageRenderer directly This simplifies the architecture by having a single renderer per size variant (full-size and compact) instead of base + wrapper pattern.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
2witstudios
added a commit
that referenced
this pull request
Jan 27, 2026
Zero-trust security hardening across 25 files following defense-in-depth principles. Fixes by category: - Path traversal (CWE-022/073): assertPathWithin() containment checks in content-store, upload, computeFileHash - Prototype pollution (CWE-1321/250): isSafePropertyKey() blocklist, hasOwnProperty.call() guards in content-store, optimize, mcp-tool-converter - Log injection (CWE-117/134): sanitizeLogValue() + format strings in image-processor, mcp-tool-converter, notification-email-service - ReDoS (CWE-1333): Bounded quantifiers in mention-processor, safe RFC 5322 email regex in account route - SSRF prevention (CWE-918): validateRequestUrl() in auth-fetch, hardcoded API URLs in file-processor - XSS prevention (CWE-079): URL protocol validation in web-preview iframe, offline.html redirect - Rate limiting (CWE-770): rateLimitUpload middleware on avatar routes - Origin verification (CWE-346): event.origin check in service worker postMessage handler - TOCTOU elimination (CWE-367): Atomic readFile replacing stat-then-read in avatar route - Input validation (CWE-807): Format regex for entryId, agentId, email token, URL construction - Regex injection (CWE-730): Pattern length limit + try/catch in drive-search-service - Incomplete sanitization (CWE-116): Full regex metachar escaping in prettier.ts - Insecure temp files (CWE-377): fs.mkdtemp() in path-validator tests - Session validation (CWE-073): Type checks + 8KB size limit in auth-storage Also fixes pre-existing TypeScript error in drive-search-service.ts (RegexSearchResponse type mismatch). Alerts: #1-75 (73 total, no #49 or #59 in CodeQL) See CODEQL_ALERT_LOG.md for full remediation details. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2witstudios
added a commit
that referenced
this pull request
Jan 27, 2026
* fix(security): remediate all 73 CodeQL vulnerability alerts Zero-trust security hardening across 25 files following defense-in-depth principles. Fixes by category: - Path traversal (CWE-022/073): assertPathWithin() containment checks in content-store, upload, computeFileHash - Prototype pollution (CWE-1321/250): isSafePropertyKey() blocklist, hasOwnProperty.call() guards in content-store, optimize, mcp-tool-converter - Log injection (CWE-117/134): sanitizeLogValue() + format strings in image-processor, mcp-tool-converter, notification-email-service - ReDoS (CWE-1333): Bounded quantifiers in mention-processor, safe RFC 5322 email regex in account route - SSRF prevention (CWE-918): validateRequestUrl() in auth-fetch, hardcoded API URLs in file-processor - XSS prevention (CWE-079): URL protocol validation in web-preview iframe, offline.html redirect - Rate limiting (CWE-770): rateLimitUpload middleware on avatar routes - Origin verification (CWE-346): event.origin check in service worker postMessage handler - TOCTOU elimination (CWE-367): Atomic readFile replacing stat-then-read in avatar route - Input validation (CWE-807): Format regex for entryId, agentId, email token, URL construction - Regex injection (CWE-730): Pattern length limit + try/catch in drive-search-service - Incomplete sanitization (CWE-116): Full regex metachar escaping in prettier.ts - Insecure temp files (CWE-377): fs.mkdtemp() in path-validator tests - Session validation (CWE-073): Type checks + 8KB size limit in auth-storage Also fixes pre-existing TypeScript error in drive-search-service.ts (RegexSearchResponse type mismatch). Alerts: #1-75 (73 total, no #49 or #59 in CodeQL) See CODEQL_ALERT_LOG.md for full remediation details. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address 6 new CodeQL alerts from initial fix round Fixes root causes that the first pass missed: - optimize.ts: Use Map for results instead of user-controlled property keys (alert 78) - content-store.ts: Use Object.create(null) + isValidPreset() for metadata object (alert 79) - verify-email/route.ts: Revert unnecessary format check that created a new alert — verifyToken() already validates cryptographically (alert 80) - web-preview.tsx: Reconstruct URL from parsed.href to break taint chain (alert 76) - drive-search-service.ts: Escape user pattern for JS line matching — PG handles actual regex (alert 77) - mcp-tool-converter.ts: Coerce mcpTools.length through Number() to break taint (alert 81) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update CODEQL_ALERT_LOG with round 2 alert fixes (76-81) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address CodeRabbit review feedback on CodeQL fixes - optimize.ts: validate presets is array of strings before iterating - audit-logs/integrity: use centralized isValidId() for CUID2 validation instead of hex-only regex pattern - auth-fetch.ts: block protocol-relative URLs (//evil.com) that bypass relative URL allowance - usePageAgentDashboardStore: use CUID2 format pattern for agent ID validation (lowercase letter + lowercase alphanumeric, max 32 chars) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address round 4 CodeRabbit review feedback - optimize.ts: replace Map<string, any> with strict BatchPresetResult union type for type safety - sw.js: fail-closed origin/source checks - reject empty origin and null source instead of allowing them through - mcp-tool-converter.ts: use RegExp constructor for control char regex to satisfy Biome noControlCharactersInRegex rule - drive-search-service.ts: document that line previews use literal matching (escaped for ReDoS prevention) vs PG regex semantics - CODEQL_ALERT_LOG.md: escape pipe in markdown table regex cell Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): validate preset param in serve route before cache lookup Prevents invalid presets from reaching contentStore.getCache() where they'd throw and return a generic 500 — now returns proper 400 response. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address code review findings and add unit tests - Extract IIFE to named sanitizeIframeSrc function for testability - Apply prototype-safe JSON parsing (Object.create(null)) in getCache and cleanupOldCache for consistency with saveCache - Allow dots in isValidPreset regex for existing presets like extracted-text.txt, ocr-text.txt, thumbnail.webp - Use format string logging in serve.ts to prevent log injection - Restore original regex pattern for drive search line matching to maintain semantic consistency with PostgreSQL regex - Remove overly restrictive origin allowlist from desktop offline page to support localhost and self-hosted app URLs - Move CODEQL_ALERT_LOG.md and PROGRESS_NOTES.md to docs/security/ - Add 59 unit tests across 4 test files covering isValidPreset, isValidContentHash, sanitizeIframeSrc, mention processor regex bounds, and AuthFetch URL validation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Major refactoring to consolidate duplicated code between GlobalAssistantView
and AiChatView into shared infrastructure:
Shared Hooks (lib/ai/shared/hooks/):
Shared Components (components/ai/chat/):
Shared Types (lib/ai/shared/):
Results:
This establishes an engine-centric architecture where Agent (AI_CHAT pages)
and Global Assistant engines share common chat infrastructure while
maintaining their distinct behaviors.