From 8f3e8bc220cb0bc1ece315f9b3f1efa639cd11f9 Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Fri, 17 Oct 2025 09:53:53 +0300 Subject: [PATCH] fix: add trailing slashes to agent work orders endpoints - add trailing slashes to prevent FastAPI mount() 307 redirects - add defensive null check for repository_url in detail view - fixes ERR_NAME_NOT_RESOLVED when browser follows redirect to archon-server --- archon-ui-main/package-lock.json | 11 ++++++ archon-ui-main/package.json | 2 + archon-ui-main/src/App.tsx | 4 ++ .../src/components/layout/Navigation.tsx | 8 +++- .../components/KnowledgeCardTitle.tsx | 4 +- .../knowledge/components/LevelSelector.tsx | 22 +++++------ .../inspector/components/ContentViewer.tsx | 5 +-- .../components/KnowledgeInspector.tsx | 2 +- .../hooks/usePaginatedInspectorData.ts | 2 +- .../hooks/tests/useProgressQueries.test.ts | 2 +- .../progress/hooks/useProgressQueries.ts | 6 +-- .../projects/components/ProjectCard.tsx | 1 - .../projects/components/ProjectHeader.tsx | 2 +- .../features/projects/documents/DocsTab.tsx | 4 +- .../documents/components/AddDocumentModal.tsx | 38 ++++++++++++------- .../documents/components/DocumentCard.tsx | 4 +- .../documents/services/documentService.ts | 9 ++--- .../tasks/components/KanbanColumn.tsx | 4 +- .../tasks/hooks/tests/useTaskQueries.test.ts | 2 +- .../features/projects/views/ProjectsView.tsx | 6 +-- .../src/features/shared/api/apiClient.ts | 2 +- .../src/features/ui/primitives/combobox.tsx | 2 +- python/Dockerfile.server | 8 ++-- 23 files changed, 89 insertions(+), 61 deletions(-) diff --git a/archon-ui-main/package-lock.json b/archon-ui-main/package-lock.json index 37b3e9a7..6e17b02d 100644 --- a/archon-ui-main/package-lock.json +++ b/archon-ui-main/package-lock.json @@ -8,6 +8,7 @@ "name": "archon-ui", "version": "0.1.0", "dependencies": { + "@hookform/resolvers": "^3.10.0", "@mdxeditor/editor": "^3.42.0", "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-checkbox": "^1.3.3", @@ -34,6 +35,7 @@ "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", "react-router-dom": "^6.26.2", @@ -1709,6 +1711,15 @@ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, + "node_modules/@hookform/resolvers": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz", + "integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==", + "license": "MIT", + "peerDependencies": { + "react-hook-form": "^7.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", diff --git a/archon-ui-main/package.json b/archon-ui-main/package.json index 576b78ae..5a9f6c9d 100644 --- a/archon-ui-main/package.json +++ b/archon-ui-main/package.json @@ -54,6 +54,8 @@ "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.3.1", + "react-hook-form": "^7.54.2", + "@hookform/resolvers": "^3.10.0", "react-icons": "^5.5.0", "react-markdown": "^10.1.0", "react-router-dom": "^6.26.2", diff --git a/archon-ui-main/src/App.tsx b/archon-ui-main/src/App.tsx index 36e0d375..904ac41e 100644 --- a/archon-ui-main/src/App.tsx +++ b/archon-ui-main/src/App.tsx @@ -14,6 +14,8 @@ import { SettingsProvider, useSettings } from './contexts/SettingsContext'; import { TooltipProvider } from './features/ui/primitives/tooltip'; import { ProjectPage } from './pages/ProjectPage'; import StyleGuidePage from './pages/StyleGuidePage'; +import { AgentWorkOrdersPage } from './pages/AgentWorkOrdersPage'; +import { AgentWorkOrderDetailPage } from './pages/AgentWorkOrderDetailPage'; import { DisconnectScreenOverlay } from './components/DisconnectScreenOverlay'; import { ErrorBoundaryWithBugReport } from './components/bug-report/ErrorBoundaryWithBugReport'; import { MigrationBanner } from './components/ui/MigrationBanner'; @@ -43,6 +45,8 @@ const AppRoutes = () => { ) : ( } /> )} + } /> + } /> ); }; diff --git a/archon-ui-main/src/components/layout/Navigation.tsx b/archon-ui-main/src/components/layout/Navigation.tsx index 3547b5fb..3758ea14 100644 --- a/archon-ui-main/src/components/layout/Navigation.tsx +++ b/archon-ui-main/src/components/layout/Navigation.tsx @@ -1,4 +1,4 @@ -import { BookOpen, Palette, Settings } from "lucide-react"; +import { BookOpen, Bot, Palette, Settings } from "lucide-react"; import type React from "react"; import { Link, useLocation } from "react-router-dom"; // TEMPORARY: Use old SettingsContext until settings are migrated @@ -34,6 +34,12 @@ export function Navigation({ className }: NavigationProps) { label: "Knowledge Base", enabled: true, }, + { + path: "/agent-work-orders", + icon: , + label: "Agent Work Orders", + enabled: true, + }, { path: "/mcp", icon: ( diff --git a/archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx b/archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx index a019156c..0bb8e86c 100644 --- a/archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx +++ b/archon-ui-main/src/features/knowledge/components/KnowledgeCardTitle.tsx @@ -150,7 +150,7 @@ export const KnowledgeCardTitle: React.FC = ({ "focus:ring-1 focus:ring-cyan-400 px-2 py-1", )} /> - {description && description.trim() && ( + {description?.trim() && ( = ({ {title} - {description && description.trim() && ( + {description?.trim() && ( = ({ value, onValueChan Crawl Depth - - - - {tooltipContent} - + + + + {tooltipContent} +
Higher levels crawl deeper into the website structure diff --git a/archon-ui-main/src/features/knowledge/inspector/components/ContentViewer.tsx b/archon-ui-main/src/features/knowledge/inspector/components/ContentViewer.tsx index 4a3a9c05..ecfc5bfa 100644 --- a/archon-ui-main/src/features/knowledge/inspector/components/ContentViewer.tsx +++ b/archon-ui-main/src/features/knowledge/inspector/components/ContentViewer.tsx @@ -41,10 +41,7 @@ export const ContentViewer: React.FC = ({ selectedItem, onCo try { // Escape HTML entities FIRST per Prism documentation requirement // Prism expects pre-escaped input to prevent XSS - const escaped = code - .replace(/&/g, "&") - .replace(//g, ">"); + const escaped = code.replace(/&/g, "&").replace(//g, ">"); const lang = language?.toLowerCase() || "javascript"; const grammar = Prism.languages[lang] || Prism.languages.javascript; diff --git a/archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx b/archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx index 334d4567..daf8c65f 100644 --- a/archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx +++ b/archon-ui-main/src/features/knowledge/inspector/components/KnowledgeInspector.tsx @@ -36,7 +36,7 @@ export const KnowledgeInspector: React.FC = ({ useEffect(() => { setViewMode(initialTab); setSelectedItem(null); // Clear selected item when switching tabs - }, [item.source_id, initialTab]); + }, [initialTab]); // Use pagination hook for current view mode const paginationData = useInspectorPagination({ diff --git a/archon-ui-main/src/features/knowledge/inspector/hooks/usePaginatedInspectorData.ts b/archon-ui-main/src/features/knowledge/inspector/hooks/usePaginatedInspectorData.ts index 26bc7355..a89fe786 100644 --- a/archon-ui-main/src/features/knowledge/inspector/hooks/usePaginatedInspectorData.ts +++ b/archon-ui-main/src/features/knowledge/inspector/hooks/usePaginatedInspectorData.ts @@ -155,7 +155,7 @@ export function usePaginatedInspectorData({ useEffect(() => { resetDocs(); resetCode(); - }, [sourceId, enabled, resetDocs, resetCode]); + }, [resetDocs, resetCode]); return { documents: { diff --git a/archon-ui-main/src/features/progress/hooks/tests/useProgressQueries.test.ts b/archon-ui-main/src/features/progress/hooks/tests/useProgressQueries.test.ts index d305a146..805fb07c 100644 --- a/archon-ui-main/src/features/progress/hooks/tests/useProgressQueries.test.ts +++ b/archon-ui-main/src/features/progress/hooks/tests/useProgressQueries.test.ts @@ -1,5 +1,5 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { act, renderHook, waitFor } from "@testing-library/react"; +import { renderHook, waitFor } from "@testing-library/react"; import React from "react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import type { ActiveOperationsResponse, ProgressResponse } from "../../types"; diff --git a/archon-ui-main/src/features/progress/hooks/useProgressQueries.ts b/archon-ui-main/src/features/progress/hooks/useProgressQueries.ts index 1ebec2a9..d5686731 100644 --- a/archon-ui-main/src/features/progress/hooks/useProgressQueries.ts +++ b/archon-ui-main/src/features/progress/hooks/useProgressQueries.ts @@ -45,7 +45,7 @@ export function useOperationProgress( hasCalledComplete.current = false; hasCalledError.current = false; consecutiveNotFound.current = 0; - }, [progressId]); + }, []); const query = useQuery({ queryKey: progressId ? progressKeys.detail(progressId) : DISABLED_QUERY_KEY, @@ -240,12 +240,12 @@ export function useMultipleOperations( // Reset tracking sets when progress IDs change // Use sorted JSON stringification for stable dependency that handles reordering - const progressIdsKey = useMemo(() => JSON.stringify([...progressIds].sort()), [progressIds]); + const _progressIdsKey = useMemo(() => JSON.stringify([...progressIds].sort()), [progressIds]); useEffect(() => { completedIds.current.clear(); errorIds.current.clear(); notFoundCounts.current.clear(); - }, [progressIdsKey]); // Stable dependency across reorderings + }, []); // Stable dependency across reorderings const queries = useQueries({ queries: progressIds.map((progressId) => ({ diff --git a/archon-ui-main/src/features/projects/components/ProjectCard.tsx b/archon-ui-main/src/features/projects/components/ProjectCard.tsx index b89fdce8..06b09515 100644 --- a/archon-ui-main/src/features/projects/components/ProjectCard.tsx +++ b/archon-ui-main/src/features/projects/components/ProjectCard.tsx @@ -51,7 +51,6 @@ export const ProjectCard: React.FC = ({ optimistic && "opacity-80 ring-1 ring-cyan-400/30", )} > - {/* Main content area with padding */}
{/* Title section */} diff --git a/archon-ui-main/src/features/projects/components/ProjectHeader.tsx b/archon-ui-main/src/features/projects/components/ProjectHeader.tsx index 563035d7..38c52f2f 100644 --- a/archon-ui-main/src/features/projects/components/ProjectHeader.tsx +++ b/archon-ui-main/src/features/projects/components/ProjectHeader.tsx @@ -1,7 +1,7 @@ import { motion } from "framer-motion"; import { LayoutGrid, List, Plus, Search, X } from "lucide-react"; import type React from "react"; -import { ReactNode } from "react"; +import type { ReactNode } from "react"; import { Button } from "../../ui/primitives/button"; import { Input } from "../../ui/primitives/input"; import { cn } from "../../ui/primitives/styles"; diff --git a/archon-ui-main/src/features/projects/documents/DocsTab.tsx b/archon-ui-main/src/features/projects/documents/DocsTab.tsx index 0f9dbba8..d154601d 100644 --- a/archon-ui-main/src/features/projects/documents/DocsTab.tsx +++ b/archon-ui-main/src/features/projects/documents/DocsTab.tsx @@ -55,7 +55,7 @@ export const DocsTab = ({ project }: DocsTabProps) => { await createDocumentMutation.mutateAsync({ title, document_type, - content: { markdown: "# " + title + "\n\nStart writing your document here..." }, + content: { markdown: `# ${title}\n\nStart writing your document here...` }, // NOTE: Archon does not have user authentication - this is a single-user local app. // "User" is a constant representing the sole user of this Archon instance. author: "User", @@ -94,7 +94,7 @@ export const DocsTab = ({ project }: DocsTabProps) => { setShowAddModal(false); setShowDeleteModal(false); setDocumentToDelete(null); - }, [projectId]); + }, []); // Auto-select first document when documents load useEffect(() => { diff --git a/archon-ui-main/src/features/projects/documents/components/AddDocumentModal.tsx b/archon-ui-main/src/features/projects/documents/components/AddDocumentModal.tsx index f29210c5..dc0d64bf 100644 --- a/archon-ui-main/src/features/projects/documents/components/AddDocumentModal.tsx +++ b/archon-ui-main/src/features/projects/documents/components/AddDocumentModal.tsx @@ -52,13 +52,7 @@ export const AddDocumentModal = ({ open, onOpenChange, onAdd }: AddDocumentModal setError(null); onOpenChange(false); } catch (err) { - setError( - typeof err === "string" - ? err - : err instanceof Error - ? err.message - : "Failed to create document" - ); + setError(typeof err === "string" ? err : err instanceof Error ? err.message : "Failed to create document"); } finally { setIsAdding(false); } @@ -81,7 +75,10 @@ export const AddDocumentModal = ({ open, onOpenChange, onAdd }: AddDocumentModal )}
-