feat: Enhance knowledge base cards with inline editing and smart navigation#659
Conversation
…gation Implements comprehensive knowledge base card improvements addressing GitHub issue #658: - **Inline tag management**: Display, add, edit, and delete tags directly on cards - **Inline title editing**: Click titles to edit with keyboard shortcuts and auto-save - **Inline type editing**: Click technical/business badges to change type via dropdown - **Description tooltips**: Show database summaries via info icons with type-matched styling - **Smart navigation**: Click stat pills to open inspector to correct tab (documents/code examples) - **Responsive design**: Tags collapse after 6 items with "show more" functionality - **Enhanced UX**: Proper error handling, optimistic updates, and visual feedback Backend improvements: - Return summary field in knowledge item API responses - Support updating tags, titles, and knowledge types Frontend improvements: - Created reusable components: KnowledgeCardTags, KnowledgeCardTitle, KnowledgeCardType - Fixed React ref warnings with forwardRef in Badge component - Improved TanStack Query cache management for optimistic updates - Added proper error toast notifications and loading states - Color-themed tooltips matching card accent colors - Protected user input from being overwritten during editing Fixes #658 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
|
Warning Rate limit exceeded@leex279 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 38 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (2)
WalkthroughRefactors Badge to forward refs; adds modular, inline-editable KnowledgeCard subcomponents (Title, Tags, Type); wires list/view/inspector to open Documents or Code tabs; extends optimistic updates to sync summaries cache; minor import reorder in apiWithEtag. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Card as KnowledgeCard
participant Sub as Title/Tags/Type
participant Mut as useUpdateKnowledgeItem
participant QC as QueryClient (detail + summaries)
participant API as Backend
User->>Card: Click edit on Title/Tag/Type
Card->>Sub: enter edit mode
User->>Sub: Save (Enter/blur)
Sub->>Mut: mutate({ sourceId, updates })
Mut->>QC: cancel detail + summaries
Mut->>QC: snapshot previous detail + summaries
Mut->>QC: optimistic update detail & summaries
Mut->>API: PATCH /knowledge
alt success
API-->>Mut: 200 OK
Mut->>QC: invalidate detail, lists, summaries
Sub->>User: exit edit (updated)
else error
API-->>Mut: Error
Mut->>QC: rollback detail + summaries
Sub->>User: exit edit (reverted)
end
sequenceDiagram
autonumber
actor User
participant List as KnowledgeList
participant Card as KnowledgeCard
participant View as KnowledgeView
participant Insp as KnowledgeInspector
User->>Card: Click "Document" pill
Card-->>List: onViewDocument(sourceId)
List-->>View: forward event
View->>View: set inspectorInitialTab = "documents"
View-->>Insp: open(initialTab="documents")
User->>Card: Click "Code Examples" pill
Card-->>List: onViewCodeExamples(sourceId)
List-->>View: forward event
View->>View: set inspectorInitialTab = "code"
View-->>Insp: open(initialTab="code")
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (10)
archon-ui-main/src/features/projects/shared/apiWithEtag.ts (2)
83-84: Add fallback for AbortSignal.timeout for broader browser support.Older runtimes may lack AbortSignal.timeout; provide a small fallback to avoid a ReferenceError.
Example helper to use outside the shown lines:
function withTimeout(signal: AbortSignal | undefined, ms: number): AbortSignal { if (signal) return signal; if (typeof AbortSignal?.timeout === "function") return AbortSignal.timeout(ms); const c = new AbortController(); setTimeout(() => c.abort(), ms); return c.signal; }Then replace:
- signal: options.signal ?? AbortSignal.timeout(10000), + signal: withTimeout(options.signal as AbortSignal | undefined, 10000),
69-72: Avoid sending Content-Type on GET requests.Not harmful, but unnecessary and can confuse proxies. Consider omitting it when method === "GET".
- const headers: Record<string, string> = { - "Content-Type": "application/json", - ...((options.headers as Record<string, string>) || {}), - }; + const headers: Record<string, string> = { + ...((options.headers as Record<string, string>) || {}), + }; + if (method !== "GET") headers["Content-Type"] = headers["Content-Type"] ?? "application/json";archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
559-570: Consider extracting tag update logic to avoid duplication.The tag update logic is duplicated between detail and summary updates. Consider extracting it to a helper function for better maintainability.
+const updateItemTags = (item: any, tags: string[]): any => { + const updatedItem = { ...item }; + updatedItem.tags = tags; + updatedItem.metadata = { ...updatedItem.metadata, tags }; + return updatedItem; +}; // Optimistically update the detail item if (previousItem) { - const updatedItem = { ...previousItem }; - - // Handle metadata updates properly - if ('tags' in updates) { - const newTags = updates.tags as string[]; - // Update both top-level tags and metadata.tags for consistency - (updatedItem as any).tags = newTags; - updatedItem.metadata = { ...updatedItem.metadata, tags: newTags }; - } - - queryClient.setQueryData<KnowledgeItem>(knowledgeKeys.detail(sourceId), updatedItem); + const updatedItem = 'tags' in updates + ? updateItemTags(previousItem, updates.tags as string[]) + : { ...previousItem }; + queryClient.setQueryData<KnowledgeItem>(knowledgeKeys.detail(sourceId), updatedItem); }And similarly update the summaries cache logic:
items: old.items.map((item: any) => { if (item.source_id === sourceId) { - const updatedItem = { ...item }; - if ('tags' in updates) { - const newTags = updates.tags as string[]; - // Update both top-level tags and metadata.tags for consistency with summary API - updatedItem.tags = newTags; - updatedItem.metadata = { ...updatedItem.metadata, tags: newTags }; - } - return updatedItem; + return 'tags' in updates + ? updateItemTags(item, updates.tags as string[]) + : { ...item }; } return item; }),archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (1)
34-39: Consider preserving selected item when switching between tabs.Currently, the selected item is cleared when switching tabs via
initialTabchanges. For better UX, consider preserving the selected item if it exists in both tabs (unlikely but possible with mixed content).The current behavior of clearing the selected item is reasonable for most cases since documents and code examples are typically distinct. However, if you want to support edge cases where content might be relevant across tabs, you could check if the selected item exists in the new tab before clearing it.
archon-ui-main/src/features/knowledge/views/KnowledgeView.tsx (1)
26-26: Consider a more specific type for tab state.While the current type works, using a union type directly for state is fine, but you might want to consider an enum or const assertion for better maintainability as more tabs are added.
- const [inspectorInitialTab, setInspectorInitialTab] = useState<"documents" | "code">("documents"); + type InspectorTab = "documents" | "code"; + const [inspectorInitialTab, setInspectorInitialTab] = useState<InspectorTab>("documents");archon-ui-main/src/features/knowledge/components/KnowledgeCard.tsx (1)
238-238: Type assertion with(item as any).summaryshould be avoided.Using
(item as any)bypasses TypeScript's type safety. Thesummaryfield should be properly typed in theKnowledgeIteminterface.- description={(item as any).summary} + description={item.summary}Ensure the
KnowledgeItemtype includes thesummaryfield:interface KnowledgeItem { // ... existing fields summary?: string; }archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx (1)
126-167: Consider extracting repetitive event handlers.The Input component has many repetitive
stopPropagationhandlers. Consider creating a wrapper component or utility to reduce duplication.+ const stopPropagationProps = { + onClick: (e: React.MouseEvent) => e.stopPropagation(), + onMouseDown: (e: React.MouseEvent) => e.stopPropagation(), + onKeyUp: (e: React.KeyboardEvent) => e.stopPropagation(), + onInput: (e: React.FormEvent) => e.stopPropagation(), + onFocus: (e: React.FocusEvent) => e.stopPropagation(), + }; <Input ref={inputRef} value={editValue} onChange={(e) => setEditValue(e.target.value)} onBlur={handleSave} onKeyDown={handleKeyDown} - onClick={(e) => e.stopPropagation()} - onMouseDown={(e) => e.stopPropagation()} - onKeyUp={(e) => e.stopPropagation()} - onInput={(e) => e.stopPropagation()} - onFocus={(e) => e.stopPropagation()} + {...stopPropagationProps} disabled={updateMutation.isPending}archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (3)
124-128: Unused functionhandleTagClick.The
handleTagClickfunction is defined but never called. Consider removing it if not needed.- const handleTagClick = () => { - if (!isEditing) { - setIsEditing(true); - } - };
136-141: Avoid using setTimeout for focus management.Using
setTimeoutfor focus management can be unreliable. Consider usinguseLayoutEffector React'sflushSyncfor more predictable behavior.- // Focus the input - setTimeout(() => { - if (inputRef.current) { - inputRef.current.focus(); - inputRef.current.select(); // Select all text for easy editing - } - }, 0); + // Focus will be handled by the isEditing effect + // which already handles focus managementSince you already have a
useEffectthat focuses the input whenisEditingchanges (lines 37-41), you might not need this additional setTimeout.
152-216: Consider extracting tag badge rendering to reduce duplication.The tag rendering logic for editing and non-editing modes is very similar. Consider extracting a common component to reduce code duplication.
You could create a helper component:
const TagBadge = ({ tag, isEditing, onEdit, onRemove, isPending }) => { const content = ( <> <Tag className="w-2.5 h-2.5" /> <span>{tag}</span> <button type="button" onClick={(e) => { e.stopPropagation(); onRemove(tag); }} className="opacity-0 group-hover:opacity-100 transition-opacity ml-0.5 hover:text-red-500" aria-label={`${isEditing ? 'Remove' : 'Delete'} ${tag} tag`} disabled={isPending} > <X className="w-2.5 h-2.5" /> </button> </> ); return ( <SimpleTooltip content={`Click to edit "${tag}" or hover to ${isEditing ? 'remove' : 'delete'}`}> <Badge color="gray" variant="outline" className="flex items-center gap-1 text-[10px] cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors group pr-0.5 px-1.5 py-0.5 h-5" onClick={() => onEdit(tag)} > {content} </Badge> </SimpleTooltip> ); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
archon-ui-main/src/components/ui/Badge.tsx(2 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeCard.tsx(6 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx(1 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx(1 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx(1 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeList.tsx(3 hunks)archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts(1 hunks)archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx(1 hunks)archon-ui-main/src/features/knowledge/views/KnowledgeView.tsx(4 hunks)archon-ui-main/src/features/projects/shared/apiWithEtag.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
archon-ui-main/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend
archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsxarchon-ui-main/src/features/projects/shared/apiWithEtag.tsarchon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsxarchon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.tsarchon-ui-main/src/components/ui/Badge.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCard.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeList.tsxarchon-ui-main/src/features/knowledge/views/KnowledgeView.tsx
archon-ui-main/src/features/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas
archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsxarchon-ui-main/src/features/projects/shared/apiWithEtag.tsarchon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsxarchon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.tsarchon-ui-main/src/features/knowledge/components/KnowledgeCard.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeList.tsxarchon-ui-main/src/features/knowledge/views/KnowledgeView.tsx
**/*.{py,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Never return None/null to indicate failure; raise an exception with details instead
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsxarchon-ui-main/src/features/projects/shared/apiWithEtag.tsarchon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsxarchon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.tsarchon-ui-main/src/components/ui/Badge.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeCard.tsxarchon-ui-main/src/features/knowledge/components/KnowledgeList.tsxarchon-ui-main/src/features/knowledge/views/KnowledgeView.tsx
archon-ui-main/src/components/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Legacy UI code should adhere to standard React ESLint rules
Files:
archon-ui-main/src/components/ui/Badge.tsx
archon-ui-main/src/components/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Legacy UI under /components should follow ESLint standard React rules
Files:
archon-ui-main/src/components/ui/Badge.tsx
🧠 Learnings (4)
📚 Learning: 2025-09-12T13:47:04.535Z
Learnt from: CR
PR: coleam00/Archon#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:47:04.535Z
Learning: Applies to archon-ui-main/src/**/*.{ts,tsx} : Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend
Applied to files:
archon-ui-main/src/features/projects/shared/apiWithEtag.ts
📚 Learning: 2025-09-13T15:53:40.741Z
Learnt from: CR
PR: coleam00/Archon#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-13T15:53:40.741Z
Learning: Applies to archon-ui-main/src/**/*.{ts,tsx} : Service method names: get[Resource]sByProject(projectId), get[Resource](id), create/update/delete patterns
Applied to files:
archon-ui-main/src/features/projects/shared/apiWithEtag.ts
📚 Learning: 2025-09-12T13:47:04.534Z
Learnt from: CR
PR: coleam00/Archon#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:47:04.534Z
Learning: Applies to archon-ui-main/src/features/**/*.{ts,tsx} : Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Applied to files:
archon-ui-main/src/features/projects/shared/apiWithEtag.tsarchon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts
📚 Learning: 2025-08-28T13:07:24.810Z
Learnt from: Wirasm
PR: coleam00/Archon#514
File: archon-ui-main/src/services/crawlProgressService.ts:35-39
Timestamp: 2025-08-28T13:07:24.810Z
Learning: The crawlProgressService.ts in the Archon codebase should be deprecated in favor of the existing useCrawlProgressPolling hook from usePolling.ts, which already includes ETag support, 304 handling, tab visibility detection, and proper React lifecycle integration. This consolidation reduces code duplication and improves performance.
Applied to files:
archon-ui-main/src/features/projects/shared/apiWithEtag.ts
🧬 Code graph analysis (6)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (5)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
useUpdateKnowledgeItem(541-620)archon-ui-main/src/features/ui/primitives/tooltip.tsx (1)
SimpleTooltip(62-77)archon-ui-main/src/components/ui/Badge.tsx (1)
Badge(7-43)archon-ui-main/src/features/ui/primitives/input.tsx (1)
Input(8-29)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(139-141)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (5)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
useUpdateKnowledgeItem(541-620)archon-ui-main/src/features/ui/hooks/useToast.ts (1)
useToast(25-31)archon-ui-main/src/features/ui/primitives/select.tsx (5)
Select(7-7)SelectTrigger(11-40)SelectValue(8-8)SelectContent(44-79)SelectItem(83-121)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(139-141)archon-ui-main/src/features/ui/primitives/tooltip.tsx (1)
SimpleTooltip(62-77)
archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (1)
archon-ui-main/src/features/knowledge/types/knowledge.ts (1)
InspectorSelectedItem(161-166)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx (4)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
useUpdateKnowledgeItem(541-620)archon-ui-main/src/features/ui/primitives/input.tsx (1)
Input(8-29)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(139-141)archon-ui-main/src/features/ui/primitives/tooltip.tsx (4)
Tooltip(9-9)TooltipTrigger(12-12)TooltipContent(15-50)SimpleTooltip(62-77)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
archon-ui-main/src/features/knowledge/types/knowledge.ts (1)
KnowledgeItem(26-39)
archon-ui-main/src/features/knowledge/components/KnowledgeCard.tsx (3)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (1)
KnowledgeCardType(19-155)archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx (1)
KnowledgeCardTitle(41-200)archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (1)
KnowledgeCardTags(19-322)
🔇 Additional comments (14)
archon-ui-main/src/features/projects/shared/apiWithEtag.ts (1)
7-7: Import reorder LGTM.No functional change; aligns with local import grouping.
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
551-551: LGTM! Optimistic updates now properly handle summaries cache.The changes correctly extend the optimistic update mechanism to include the summaries cache alongside the detail cache, ensuring UI consistency when items are updated inline. This prevents UI staleness when toggling between list and detail views.
Also applies to: 617-617
archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx (1)
18-19: LGTM! Smart navigation enhancement with initialTab prop.The addition of the
initialTabprop enables the inspector to open directly to the appropriate tab based on user interaction context (e.g., clicking on code examples opens the Code Examples tab).Also applies to: 23-28
archon-ui-main/src/components/ui/Badge.tsx (1)
7-13: LGTM! Proper forwardRef implementation resolves React warnings.The conversion to
forwardRefcorrectly addresses React ref warnings that would occur when the Badge component is used within other components that need ref access. The implementation properly forwards the ref to the underlying span element and includes the displayName for better debugging.Also applies to: 32-45
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (1)
29-48: LGTM! Robust outside-click handling with proper Radix UI exclusions.The implementation correctly handles clicks outside the select component, including proper exclusion of Radix UI's portal elements to prevent premature closing when interacting with the dropdown.
archon-ui-main/src/features/knowledge/components/KnowledgeList.tsx (1)
21-21: LGTM! Clean integration of code examples navigation.The optional
onViewCodeExamplesprop is properly threaded through to the KnowledgeCard component, enabling smart navigation to the Code Examples tab when triggered. The conditional passing ensures backward compatibility.Also applies to: 58-58, 173-173
archon-ui-main/src/features/knowledge/views/KnowledgeView.tsx (1)
99-115: Good implementation of smart navigation.The smart navigation implementation correctly finds the item and sets the appropriate tab before opening the inspector. This provides a good user experience by contextually showing the relevant content.
archon-ui-main/src/features/knowledge/components/KnowledgeCard.tsx (4)
303-319: Interactive stat pills implementation looks good.The document stat pill correctly implements click-to-view functionality with proper event propagation control and hover effects. Good UX with the tooltip indicating the action.
320-343: Code examples pill interaction is well-implemented.Good conditional handling where the pill is only clickable when
onViewCodeExamplesis provided. The tooltip correctly indicates whether examples are available or not.
205-208: Clean integration of KnowledgeCardType component.The type badge has been cleanly replaced with the modular component, maintaining consistency while adding inline editing functionality.
264-275: Tags section properly handles event propagation.Good use of event propagation control to prevent card clicks when interacting with tags. The data source fallback
item.tags || item.metadata?.tags || []ensures backward compatibility.archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx (2)
71-98: Solid save logic with proper validation.The save handler correctly:
- Trims whitespace and checks for changes
- Prevents empty titles
- Handles errors by reverting to original value
- Updates state appropriately
Good defensive programming.
14-32: Color mappings are well-organized.The centralized color class mappings provide good maintainability and consistency across different accent colors. The fallback to default ensures robustness.
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (1)
83-102: Tag deduplication logic is correct.The
handleAddTagfunction properly:
- Removes the original tag when editing
- Prevents duplicate tags
- Updates state correctly
Good implementation of the edit/replace flow.
- Remove duplicate showToast call from KnowledgeCardType catch block - useUpdateKnowledgeItem mutation already handles error toasts in onError - Use finally block to ensure editing state is cleared regardless of outcome - Remove unused useToast import 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Remove verbose 'or hover to delete' text from tag tooltips. Tooltips now show clean 'Click to edit "tagname"' message. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 3
♻️ Duplicate comments (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (1)
56-67: Nice: duplicate error toasts removed.Switching to try/finally and relying on mutation.onError avoids double toasts noted earlier.
🧹 Nitpick comments (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (1)
97-106: Also disable the Select trigger during mutation.Passing disabled only to Root may not reflect on the Trigger’s disabled styles/semantics. Propagate disabled to the Trigger.
- <SelectTrigger + <SelectTrigger + disabled={updateMutation.isPending} + aria-busy={updateMutation.isPending} className={cn( "w-auto h-auto text-xs font-medium px-2 py-1 rounded-md", "border-cyan-400 dark:border-cyan-600", "focus:ring-1 focus:ring-cyan-400",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
archon-ui-main/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend
archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx
archon-ui-main/src/features/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas
archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx
**/*.{py,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Never return None/null to indicate failure; raise an exception with details instead
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx
🧬 Code graph analysis (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx (4)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
useUpdateKnowledgeItem(541-620)archon-ui-main/src/features/ui/primitives/select.tsx (5)
Select(7-7)SelectTrigger(11-40)SelectValue(8-8)SelectContent(44-79)SelectItem(83-121)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(139-141)archon-ui-main/src/features/ui/primitives/tooltip.tsx (1)
SimpleTooltip(62-77)
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (6)
104-106: Clear edit state if the removed tag is the one being edited.Removing the tag currently loaded into the input leaves stale
newTagValue/originalTagBeingEdited, which can accidentally re‑add it.Apply this diff:
-const handleRemoveTag = (tagToRemove: string) => { - setEditingTags(editingTags.filter((tag) => tag !== tagToRemove)); -}; +const handleRemoveTag = (tagToRemove: string) => { + setEditingTags((prev) => prev.filter((tag) => tag !== tagToRemove)); + if (originalTagBeingEdited === tagToRemove) { + setOriginalTagBeingEdited(null); + setNewTagValue(""); + } +};
152-154: Use stable, unique keys to handle duplicate tags.
key={tag}breaks if duplicates exist (React warning, misrenders). Include index to guarantee uniqueness.Apply this diff:
-{visibleTags.map((tag) => ( - <div key={tag} className="relative"> +{visibleTags.map((tag, idx) => ( + <div key={`${tag}-${idx}`} className="relative">
219-237: Improve a11y: reflect disclosure state on “Show more/less”.Expose state to AT with
aria-expanded.Apply this diff:
-<button +<button type="button" onClick={() => setShowAllTags(!showAllTags)} className="flex items-center gap-0.5 text-[10px] text-gray-500 dark:text-gray-400 hover:text-cyan-600 dark:hover:text-cyan-400 transition-colors px-1 py-0.5 rounded" + aria-expanded={showAllTags} >
28-30: Hoist constant out of render.Move
MAX_TAGS_COLLAPSEDto module scope to avoid re‑alloc each render and align the comment with the actual value.Apply this diff to remove the in‑component declaration:
-// Determine how many tags to show (2 rows worth, approximately 6-8 tags depending on length) -const MAX_TAGS_COLLAPSED = 6;Then add this near the top (after imports):
// Approx. two rows when collapsed const MAX_TAGS_COLLAPSED = 6;
136-141: Avoid duplicate focus logic; rely on theisEditingeffect.You already focus the input in the
isEditingeffect. The extrasetTimeout(...focus/select)s are redundant and can cause jitter.Apply this diff to remove the timeouts:
- // Focus the input - setTimeout(() => { - if (inputRef.current) { - inputRef.current.focus(); - inputRef.current.select(); // Select all text for easy editing - } - }, 0);- setTimeout(() => { - if (inputRef.current) { - inputRef.current.focus(); - inputRef.current.select(); - } - }, 0);Also applies to: 189-195
124-129: Remove unused handler.
handleTagClickisn’t referenced. Drop it to reduce noise.Apply this diff:
-const handleTagClick = () => { - if (!isEditing) { - setIsEditing(true); - } -};
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
archon-ui-main/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend
archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx
archon-ui-main/src/features/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas
archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx
**/*.{py,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Never return None/null to indicate failure; raise an exception with details instead
Files:
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx
🧬 Code graph analysis (1)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx (5)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
useUpdateKnowledgeItem(541-620)archon-ui-main/src/features/ui/primitives/tooltip.tsx (1)
SimpleTooltip(62-77)archon-ui-main/src/components/ui/Badge.tsx (1)
Badge(7-43)archon-ui-main/src/features/ui/primitives/input.tsx (1)
Input(8-29)archon-ui-main/src/features/ui/primitives/styles.ts (1)
cn(139-141)
- Add optimistic updates for knowledge_type changes in useUpdateKnowledgeItem - Update both detail and summary caches to prevent visual reversion - Refactor KnowledgeCardType to use controlled Radix Select component - Remove manual click-outside detection in favor of Radix onOpenChange - Protect tag editing state from being overwritten by external updates - Ensure user input is preserved during active editing sessions 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (4)
553-556: Type the summaries snapshot for safe rollback.-const previousSummaries = queryClient.getQueriesData({ queryKey: knowledgeKeys.summary() }); +const previousSummaries = queryClient.getQueriesData<KnowledgeItemsResponse>({ + queryKey: knowledgeKeys.summary(), +});
45-46: Reject withErrorobjects, not strings.React Query preserves error types; returning a string hampers error handling and stack traces.
-: Promise.reject("No source ID") +: Promise.reject(new Error("No source ID"))Apply in all fallback queryFns shown in the selected ranges.
Also applies to: 56-58, 69-71, 758-766, 781-787
696-704: Align polling intervals with guidelines (1–2s active, 5–10s background).Current intervals are 5s/30s. Recommend tightening for faster UI during active ops and less stale background data.
- const { refetchInterval } = useSmartPolling(hasActiveOperations ? 5000 : 30000); + const { refetchInterval } = useSmartPolling(hasActiveOperations ? 1500 : 7000);
54-63: Reduce duplication between chunk hooks.Two chunk hooks hit the same service with divergent options. Consider a single hook with optional pagination/domain filter, or make one a thin alias to the other to cut maintenance.
Also applies to: 750-768
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx(1 hunks)archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx(1 hunks)archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- archon-ui-main/src/features/knowledge/components/KnowledgeCardTags.tsx
- archon-ui-main/src/features/knowledge/components/KnowledgeCardType.tsx
🧰 Additional context used
📓 Path-based instructions (3)
archon-ui-main/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/**/*.{ts,tsx}: Use TanStack Query for all data fetching; avoid prop drilling
TypeScript: strict mode with no implicit any in frontend code
State naming: is[Action]ing for loading flags, [resource]Error for errors, selected[Resource] for current selection
Use HTTP polling with ETag caching; do not introduce WebSocket-based updates in the frontend
archon-ui-main/src/**/*.{ts,tsx}: WebSocket event failures (if any) should be logged and not crash the client; continue serving others
Frontend data fetching must use TanStack Query (no prop drilling) with query key factories, smart polling, and optimistic updates with rollback
Use vertical slice architecture: place UI under src/features/[feature]/(components|hooks|services|types)
State naming: use is[Action]ing for loading, [resource]Error for errors, selected[Resource] for selections
Service method names: get[Resource]sByProject(projectId), getResource, create/update/delete patterns
Frontend TypeScript should be strict (no implicit any)
Files:
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts
archon-ui-main/src/features/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
archon-ui-main/src/features/**/*.{ts,tsx}: Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Biome formatting in features: 120-character lines, double quotes, trailing commas
archon-ui-main/src/features/**/*.{ts,tsx}: Use Biome formatting/conventions in /src/features: 120-char lines, double quotes, trailing commas
Use useSmartPolling and polling intervals (1–2s active, 5–10s background) with smart pausing on tab inactivity
Expose progress via dedicated hooks (e.g., useCrawlProgressPolling, useProjectTasks) instead of ad-hoc timers
Do not use prop drilling for data fetching/state; rely on TanStack Query caches/selectors
Files:
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts
**/*.{py,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Never return None/null to indicate failure; raise an exception with details instead
Files:
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts
🧠 Learnings (1)
📚 Learning: 2025-09-12T13:47:04.534Z
Learnt from: CR
PR: coleam00/Archon#0
File: AGENTS.md:0-0
Timestamp: 2025-09-12T13:47:04.534Z
Learning: Applies to archon-ui-main/src/features/**/*.{ts,tsx} : Follow TanStack Query patterns: query-keys factory, smart polling via useSmartPolling, optimistic updates with rollback
Applied to files:
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts
🧬 Code graph analysis (1)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (1)
archon-ui-main/src/features/knowledge/types/knowledge.ts (1)
KnowledgeItem(26-39)
🔇 Additional comments (3)
archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (3)
614-619: Rollback loop LGTM.
627-631: Invalidate detail, lists, and summaries — LGTM.
545-576: Fix optimistic update: remove unnecessaryany, reflecttitle, and tighten property checksKnowledgeItem already has a top-level
tags?: string[]— the claim that accessingupdates.tagsbreaks is incorrect. Change the optimistic patch to assignupdatedItem.tags = newTags(noas any), addif (Object.prototype.hasOwnProperty.call(updates, 'title')) updatedItem.title = updates.title!, and preferhasOwnProperty(or a narrowKnowledgeItemUpdatetype) instead of relying on'prop' in updates+ casts. File: archon-ui-main/src/features/knowledge/hooks/useKnowledgeQueries.ts (onMutate).
- Optional: define
type KnowledgeItemUpdate = { title?: KnowledgeItem['title']; knowledge_type?: KnowledgeItem['knowledge_type']; tags?: string[] }and use it for the mutation payload to remove remaining casts.Likely an incorrect or invalid review comment.
- Replace any types with proper KnowledgeItemsResponse typing - Add support for title field updates in optimistic cache updates - Ensure metadata synchronization with top-level fields (tags, knowledge_type) - Add type guards for all update fields (string, array validation) - Initialize metadata if missing to prevent undefined errors - Maintain immutability with proper object spreading - Protect tag editing state from external prop updates during editing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add handleAddTagAndSave function that combines tag addition with immediate persistence - Update handleKeyDown to auto-save when Enter is pressed with tag input - Prevent tags from being lost when user cancels after using Enter - Maintain existing behavior for empty input (save current state) - Improve user experience with immediate persistence on Enter 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
…dup-dbid chore: deduplicate setConversationDbId pattern across adapters
…e-651-dedup-dbid chore: deduplicate setConversationDbId pattern across adapters
…e-651-dedup-dbid chore: deduplicate setConversationDbId pattern across adapters
Summary
Implements comprehensive knowledge base card improvements addressing all requirements from issue #658:
• Inline tag management: Display, add, edit, and delete tags directly on cards with smart UI (max 6 visible, expandable)
• Inline title editing: Click titles to edit with keyboard shortcuts, auto-save, and protected user input
• Inline type editing: Click technical/business badges to change type via dropdown with outside-click cancellation
• Description tooltips: Show database summaries via info icons with type-matched theming
• Smart navigation: Click stat pills to open inspector to correct tab (documents/code examples)
• Enhanced error handling: Proper toast notifications for all operations with detailed error messages
2025-09-14_15h20_41.mp4
Frontend Enhancements
Backend Improvements
Test Plan
Fixes #658
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Improvements
Refactor
Chores