diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5cc79a3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[*.{md,mdx}] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 9d0774b..626e38e 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -68,7 +68,6 @@ jobs: platforms: linux/amd64 tags: kaiohz/pickpro:composable-ui-scan cache-from: type=gha - cache-to: type=gha,mode=max - name: Trivy Image Scan (report) uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0bf6e04 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": false, + "trailingComma": "all", + "printWidth": 100, + "tabWidth": 2, + "endOfLine": "lf" +} diff --git a/src/application/App.tsx b/src/application/App.tsx index 12671ae..8c59090 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -1,7 +1,20 @@ +import { Suspense, lazy } from "react"; import { Routes, Route, Navigate } from "react-router-dom"; -import AgentsPage from "@/application/pages/AgentsPage"; import ChatPage from "@/application/pages/ChatPage"; -import RagPage from "@/application/pages/RagPage"; + +// Lazy-load secondary routes for code-splitting / smaller initial bundle. +const AgentsPage = lazy(() => import("@/application/pages/AgentsPage")); +const RagPage = lazy(() => import("@/application/pages/RagPage")); + +function PageFallback() { + return ( +
+

Loading…

+
+ ); +} + +export { PageFallback }; function App() { return ( @@ -14,4 +27,10 @@ function App() { ); } -export default App; +export default function AppRoot() { + return ( + }> + + + ); +} diff --git a/src/application/components/agent/AgentCard.tsx b/src/application/components/agent/AgentCard.tsx index fd318a3..7fe6363 100644 --- a/src/application/components/agent/AgentCard.tsx +++ b/src/application/components/agent/AgentCard.tsx @@ -40,10 +40,7 @@ function getAgentIcon(name: string): string { return AGENT_ICONS[firstLetter] ?? "smart_toy"; } -export default function AgentCard({ - agent, - onConfigure, -}: Readonly) { +export default function AgentCard({ agent, onConfigure }: Readonly) { return (
{/* Header: icon + status */} @@ -57,9 +54,7 @@ export default function AgentCard({
{/* Name */} -

- {agent.name} -

+

{agent.name}

{/* Model */}

{agent.model}

@@ -70,10 +65,7 @@ export default function AgentCard({ onClick={() => onConfigure(agent.name)} className="flex items-center gap-2 text-secondary-brand font-headline text-xs font-bold uppercase tracking-widest hover:opacity-80 transition-opacity" > - Configure{" "} - - arrow_forward - + Configure arrow_forward ); diff --git a/src/application/components/agent/AgentConfigForm.tsx b/src/application/components/agent/AgentConfigForm.tsx index bb24f65..21e4de4 100644 --- a/src/application/components/agent/AgentConfigForm.tsx +++ b/src/application/components/agent/AgentConfigForm.tsx @@ -26,26 +26,40 @@ import { SelectTrigger, SelectValue, } from "@/application/components/ui/select"; -import { Separator } from "@/application/components/ui/separator"; import StringListEditor from "./StringListEditor"; import McpServerEditor from "./McpServerEditor"; import SubAgentEditor from "./SubAgentEditor"; import HITLEditor from "./HITLEditor"; import ResponseFormatEditor from "./ResponseFormatEditor"; +import { AGENT_CONFIG_FORM_ID as FORM_ID } from "./formConstants"; // ─── Constants ────────────────────────────────────────────────────────────── -const ACCORDION_SECTIONS = [ - "general", - "system-prompt", - "tools-middleware", - "backend", - "hitl", - "memory-skills", - "mcp-servers", - "subagents", - "response-format", -] as const; +type SectionValue = + | "general" + | "system-prompt" + | "tools-middleware" + | "backend" + | "hitl" + | "memory-skills" + | "mcp-servers" + | "subagents" + | "response-format"; + +// Only essential sections are open by default, others can be revealed on demand. +const DEFAULT_OPEN_SECTIONS: SectionValue[] = ["general", "system-prompt"]; + +const SECTION_META: Record = { + general: { label: "General", icon: "tune" }, + "system-prompt": { label: "System Prompt", icon: "description" }, + "tools-middleware": { label: "Tools & Middleware", icon: "build" }, + backend: { label: "Backend", icon: "storage" }, + hitl: { label: "HITL", icon: "verified_user" }, + "memory-skills": { label: "Memory & Skills", icon: "psychology" }, + "mcp-servers": { label: "MCP Servers", icon: "hub" }, + subagents: { label: "Subagents", icon: "group" }, + "response-format": { label: "Response Format", icon: "data_object" }, +}; const MIDDLEWARE_OPTIONS: { label: string; value: MiddlewareType }[] = [ { value: MiddlewareType.TODO_LIST, label: "todo_list" }, @@ -99,10 +113,7 @@ const DEFAULT_FORM_VALUES: AgentConfigFormData = { debug: false, }; -function getDefaultValues( - mode: "create" | "edit", - initialData?: AgentConfig, -): AgentConfigFormData { +function getDefaultValues(mode: "create" | "edit", initialData?: AgentConfig): AgentConfigFormData { if (mode === "edit" && initialData) { return { ...DEFAULT_FORM_VALUES, @@ -121,15 +132,18 @@ function cn(...classes: (string | false | undefined)[]): string { return classes.filter(Boolean).join(" "); } -function buildAccordionTriggerClass(active?: boolean): string { +function buildAccordionTriggerClass(): string { return cn( - "text-xs font-bold font-headline uppercase tracking-widest hover:no-underline", - active - ? "text-secondary-brand" - : "text-on-surface-variant", + "text-xs font-bold font-headline uppercase tracking-widest", + "text-on-surface hover:text-secondary-brand", + "data-[state=open]:text-secondary-brand", ); } +function showRootDir(type: BackendType): boolean { + return type === BackendType.FILESYSTEM || type === BackendType.COMPOSITE; +} + // ─── Props ────────────────────────────────────────────────────────────────── interface AgentConfigFormProps { @@ -199,267 +213,239 @@ export default function AgentConfigForm({ } } - function renderSubmitLabel(): string { - if (isPending) return "Saving..."; - return mode === "create" ? "Create" : "Update"; - } - return (
-
-
- - {/* General */} - - - General - - - - - - - - -
- - setValue("debug", v)} - /> -
-
-
- - {/* System Prompt */} - - - System Prompt - - - -