apteva 0.2.7 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.m4hg4bxq.js +218 -0
- package/dist/index.html +4 -2
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/auth/index.ts +386 -0
- package/src/auth/middleware.ts +183 -0
- package/src/binary.ts +19 -1
- package/src/db.ts +688 -45
- package/src/integrations/composio.ts +437 -0
- package/src/integrations/index.ts +80 -0
- package/src/openapi.ts +1724 -0
- package/src/routes/api.ts +1476 -118
- package/src/routes/auth.ts +242 -0
- package/src/server.ts +121 -11
- package/src/web/App.tsx +64 -19
- package/src/web/components/agents/AgentCard.tsx +24 -22
- package/src/web/components/agents/AgentPanel.tsx +810 -45
- package/src/web/components/agents/AgentsView.tsx +81 -9
- package/src/web/components/agents/CreateAgentModal.tsx +28 -1
- package/src/web/components/api/ApiDocsPage.tsx +583 -0
- package/src/web/components/auth/CreateAccountStep.tsx +176 -0
- package/src/web/components/auth/LoginPage.tsx +91 -0
- package/src/web/components/auth/index.ts +2 -0
- package/src/web/components/common/Icons.tsx +56 -0
- package/src/web/components/common/Modal.tsx +184 -1
- package/src/web/components/dashboard/Dashboard.tsx +70 -22
- package/src/web/components/index.ts +3 -0
- package/src/web/components/layout/Header.tsx +135 -18
- package/src/web/components/layout/Sidebar.tsx +87 -43
- package/src/web/components/mcp/IntegrationsPanel.tsx +743 -0
- package/src/web/components/mcp/McpPage.tsx +451 -63
- package/src/web/components/onboarding/OnboardingWizard.tsx +64 -8
- package/src/web/components/settings/SettingsPage.tsx +340 -26
- package/src/web/components/tasks/TasksPage.tsx +22 -20
- package/src/web/components/telemetry/TelemetryPage.tsx +163 -61
- package/src/web/context/AuthContext.tsx +230 -0
- package/src/web/context/ProjectContext.tsx +182 -0
- package/src/web/context/index.ts +5 -0
- package/src/web/hooks/useAgents.ts +18 -6
- package/src/web/hooks/useOnboarding.ts +20 -4
- package/src/web/hooks/useProviders.ts +15 -5
- package/src/web/icon.png +0 -0
- package/src/web/index.html +1 -1
- package/src/web/styles.css +12 -0
- package/src/web/types.ts +10 -1
- package/dist/App.3kb50qa3.js +0 -213
|
@@ -4,6 +4,9 @@ export { LoadingSpinner, Modal, Select, CheckIcon, CloseIcon, DashboardIcon, Age
|
|
|
4
4
|
// Layout components
|
|
5
5
|
export { Header, Sidebar, ErrorBanner } from "./layout";
|
|
6
6
|
|
|
7
|
+
// Auth components
|
|
8
|
+
export { LoginPage, CreateAccountStep } from "./auth";
|
|
9
|
+
|
|
7
10
|
// Feature components
|
|
8
11
|
export { OnboardingWizard } from "./onboarding";
|
|
9
12
|
export { SettingsPage } from "./settings";
|
|
@@ -1,37 +1,154 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { useTelemetryContext } from "../../context";
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { useTelemetryContext, useAuth, useProjects } from "../../context";
|
|
3
|
+
import { MenuIcon, ChevronDownIcon } from "../common/Icons";
|
|
3
4
|
|
|
4
5
|
interface HeaderProps {
|
|
5
|
-
|
|
6
|
-
canCreateAgent: boolean;
|
|
6
|
+
onMenuClick?: () => void;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export function Header({
|
|
9
|
+
export function Header({ onMenuClick }: HeaderProps) {
|
|
10
10
|
const { connected } = useTelemetryContext();
|
|
11
|
+
const { user, logout } = useAuth();
|
|
12
|
+
const { projects, currentProjectId, currentProject, setCurrentProjectId, unassignedCount } = useProjects();
|
|
13
|
+
const [showUserMenu, setShowUserMenu] = useState(false);
|
|
14
|
+
const [showProjectMenu, setShowProjectMenu] = useState(false);
|
|
15
|
+
|
|
16
|
+
const handleLogout = async () => {
|
|
17
|
+
await logout();
|
|
18
|
+
setShowUserMenu(false);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const handleProjectSelect = (projectId: string | null) => {
|
|
22
|
+
setCurrentProjectId(projectId);
|
|
23
|
+
setShowProjectMenu(false);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const getProjectLabel = () => {
|
|
27
|
+
if (currentProjectId === null) return "All Projects";
|
|
28
|
+
if (currentProjectId === "unassigned") return "Unassigned";
|
|
29
|
+
return currentProject?.name || "Select Project";
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const getProjectColor = () => {
|
|
33
|
+
if (currentProjectId === null) return "#666";
|
|
34
|
+
if (currentProjectId === "unassigned") return "#888";
|
|
35
|
+
return currentProject?.color || "#6366f1";
|
|
36
|
+
};
|
|
11
37
|
|
|
12
38
|
return (
|
|
13
|
-
<header className="border-b border-[#1a1a1a] px-6 py-4 flex-shrink-0">
|
|
39
|
+
<header className="border-b border-[#1a1a1a] px-4 md:px-6 py-4 flex-shrink-0">
|
|
14
40
|
<div className="flex items-center justify-between">
|
|
15
|
-
<div className="flex items-center gap-
|
|
16
|
-
|
|
17
|
-
<
|
|
41
|
+
<div className="flex items-center gap-3">
|
|
42
|
+
{/* Hamburger menu button - mobile only */}
|
|
43
|
+
<button
|
|
44
|
+
onClick={onMenuClick}
|
|
45
|
+
className="p-2 -ml-2 text-[#666] hover:text-[#e0e0e0] transition md:hidden"
|
|
46
|
+
>
|
|
47
|
+
<MenuIcon />
|
|
48
|
+
</button>
|
|
49
|
+
<div className="flex items-center gap-2">
|
|
50
|
+
<span className="text-[#f97316]">>_</span>
|
|
51
|
+
<span className="text-xl tracking-wider">apteva</span>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
{/* Project Selector */}
|
|
55
|
+
{projects.length > 0 && (
|
|
56
|
+
<div className="relative ml-2 md:ml-4">
|
|
57
|
+
<button
|
|
58
|
+
onClick={() => setShowProjectMenu(!showProjectMenu)}
|
|
59
|
+
className="flex items-center gap-2 px-3 py-1.5 rounded border border-[#222] bg-[#111] hover:bg-[#1a1a1a] transition text-sm"
|
|
60
|
+
>
|
|
61
|
+
<span
|
|
62
|
+
className="w-2.5 h-2.5 rounded-full"
|
|
63
|
+
style={{ backgroundColor: getProjectColor() }}
|
|
64
|
+
/>
|
|
65
|
+
<span className="hidden sm:inline max-w-[120px] md:max-w-[180px] truncate">
|
|
66
|
+
{getProjectLabel()}
|
|
67
|
+
</span>
|
|
68
|
+
<ChevronDownIcon />
|
|
69
|
+
</button>
|
|
70
|
+
{showProjectMenu && (
|
|
71
|
+
<div className="absolute left-0 top-full mt-1 w-56 bg-[#111] border border-[#222] rounded-lg shadow-xl z-50">
|
|
72
|
+
<div className="py-1 max-h-64 overflow-y-auto">
|
|
73
|
+
<button
|
|
74
|
+
onClick={() => handleProjectSelect(null)}
|
|
75
|
+
className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
|
|
76
|
+
currentProjectId === null ? "bg-[#1a1a1a] text-[#f97316]" : ""
|
|
77
|
+
}`}
|
|
78
|
+
>
|
|
79
|
+
<span className="w-2.5 h-2.5 rounded-full bg-[#666]" />
|
|
80
|
+
All Projects
|
|
81
|
+
</button>
|
|
82
|
+
{projects.map(project => (
|
|
83
|
+
<button
|
|
84
|
+
key={project.id}
|
|
85
|
+
onClick={() => handleProjectSelect(project.id)}
|
|
86
|
+
className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
|
|
87
|
+
currentProjectId === project.id ? "bg-[#1a1a1a] text-[#f97316]" : ""
|
|
88
|
+
}`}
|
|
89
|
+
>
|
|
90
|
+
<span
|
|
91
|
+
className="w-2.5 h-2.5 rounded-full flex-shrink-0"
|
|
92
|
+
style={{ backgroundColor: project.color }}
|
|
93
|
+
/>
|
|
94
|
+
<span className="truncate">{project.name}</span>
|
|
95
|
+
<span className="ml-auto text-xs text-[#666]">{project.agentCount}</span>
|
|
96
|
+
</button>
|
|
97
|
+
))}
|
|
98
|
+
{unassignedCount > 0 && (
|
|
99
|
+
<button
|
|
100
|
+
onClick={() => handleProjectSelect("unassigned")}
|
|
101
|
+
className={`w-full px-4 py-2 text-left text-sm flex items-center gap-2 hover:bg-[#1a1a1a] transition ${
|
|
102
|
+
currentProjectId === "unassigned" ? "bg-[#1a1a1a] text-[#f97316]" : ""
|
|
103
|
+
}`}
|
|
104
|
+
>
|
|
105
|
+
<span className="w-2.5 h-2.5 rounded-full bg-[#888]" />
|
|
106
|
+
<span className="truncate">Unassigned</span>
|
|
107
|
+
<span className="ml-auto text-xs text-[#666]">{unassignedCount}</span>
|
|
108
|
+
</button>
|
|
109
|
+
)}
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
)}
|
|
18
115
|
</div>
|
|
19
|
-
<div className="flex items-center gap-4">
|
|
116
|
+
<div className="flex items-center gap-3 md:gap-4">
|
|
20
117
|
<div className="flex items-center gap-2">
|
|
21
118
|
<span
|
|
22
119
|
className={`w-2 h-2 rounded-full ${connected ? "bg-green-400" : "bg-red-400"}`}
|
|
23
120
|
/>
|
|
24
|
-
<span className="text-xs text-[#666]">
|
|
121
|
+
<span className="text-xs text-[#666] hidden sm:inline">
|
|
25
122
|
{connected ? "Live" : "Offline"}
|
|
26
123
|
</span>
|
|
27
124
|
</div>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
125
|
+
{user && (
|
|
126
|
+
<div className="relative">
|
|
127
|
+
<button
|
|
128
|
+
onClick={() => setShowUserMenu(!showUserMenu)}
|
|
129
|
+
className="flex items-center gap-2 px-2 md:px-3 py-2 rounded hover:bg-[#1a1a1a] transition"
|
|
130
|
+
>
|
|
131
|
+
<div className="w-8 h-8 rounded-full bg-[#f97316] flex items-center justify-center text-black font-medium text-sm">
|
|
132
|
+
{user.username.charAt(0).toUpperCase()}
|
|
133
|
+
</div>
|
|
134
|
+
<span className="text-sm text-[#888] hidden sm:block">{user.username}</span>
|
|
135
|
+
</button>
|
|
136
|
+
{showUserMenu && (
|
|
137
|
+
<div className="absolute right-0 top-full mt-1 w-48 bg-[#111] border border-[#222] rounded-lg shadow-xl z-50">
|
|
138
|
+
<div className="px-4 py-3 border-b border-[#222]">
|
|
139
|
+
<p className="text-sm font-medium">{user.username}</p>
|
|
140
|
+
<p className="text-xs text-[#f97316] mt-1">{user.role}</p>
|
|
141
|
+
</div>
|
|
142
|
+
<button
|
|
143
|
+
onClick={handleLogout}
|
|
144
|
+
className="w-full px-4 py-2 text-left text-sm text-red-400 hover:bg-[#1a1a1a] transition"
|
|
145
|
+
>
|
|
146
|
+
Sign out
|
|
147
|
+
</button>
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
150
|
+
</div>
|
|
151
|
+
)}
|
|
35
152
|
</div>
|
|
36
153
|
</div>
|
|
37
154
|
</header>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { DashboardIcon, AgentsIcon, TasksIcon, McpIcon, TelemetryIcon, SettingsIcon } from "../common/Icons";
|
|
2
|
+
import { DashboardIcon, AgentsIcon, TasksIcon, McpIcon, TelemetryIcon, ApiIcon, SettingsIcon, CloseIcon } from "../common/Icons";
|
|
3
3
|
import type { Route } from "../../types";
|
|
4
4
|
|
|
5
5
|
interface SidebarProps {
|
|
@@ -7,52 +7,96 @@ interface SidebarProps {
|
|
|
7
7
|
agentCount: number;
|
|
8
8
|
taskCount?: number;
|
|
9
9
|
onNavigate: (route: Route) => void;
|
|
10
|
+
isOpen?: boolean;
|
|
11
|
+
onClose?: () => void;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
export function Sidebar({ route, agentCount, taskCount, onNavigate }: SidebarProps) {
|
|
14
|
+
export function Sidebar({ route, agentCount, taskCount, onNavigate, isOpen, onClose }: SidebarProps) {
|
|
15
|
+
const handleNavigate = (newRoute: Route) => {
|
|
16
|
+
onNavigate(newRoute);
|
|
17
|
+
onClose?.();
|
|
18
|
+
};
|
|
19
|
+
|
|
13
20
|
return (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
onClick={() => onNavigate("dashboard")}
|
|
21
|
-
/>
|
|
22
|
-
<NavButton
|
|
23
|
-
icon={<AgentsIcon />}
|
|
24
|
-
label="Agents"
|
|
25
|
-
active={route === "agents"}
|
|
26
|
-
onClick={() => onNavigate("agents")}
|
|
27
|
-
badge={agentCount > 0 ? String(agentCount) : undefined}
|
|
28
|
-
/>
|
|
29
|
-
<NavButton
|
|
30
|
-
icon={<TasksIcon />}
|
|
31
|
-
label="Tasks"
|
|
32
|
-
active={route === "tasks"}
|
|
33
|
-
onClick={() => onNavigate("tasks")}
|
|
34
|
-
badge={taskCount && taskCount > 0 ? String(taskCount) : undefined}
|
|
35
|
-
/>
|
|
36
|
-
<NavButton
|
|
37
|
-
icon={<McpIcon />}
|
|
38
|
-
label="MCP"
|
|
39
|
-
active={route === "mcp"}
|
|
40
|
-
onClick={() => onNavigate("mcp")}
|
|
41
|
-
/>
|
|
42
|
-
<NavButton
|
|
43
|
-
icon={<TelemetryIcon />}
|
|
44
|
-
label="Telemetry"
|
|
45
|
-
active={route === "telemetry"}
|
|
46
|
-
onClick={() => onNavigate("telemetry")}
|
|
21
|
+
<>
|
|
22
|
+
{/* Mobile overlay backdrop */}
|
|
23
|
+
{isOpen && (
|
|
24
|
+
<div
|
|
25
|
+
className="fixed inset-0 bg-black/60 z-40 md:hidden"
|
|
26
|
+
onClick={onClose}
|
|
47
27
|
/>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
28
|
+
)}
|
|
29
|
+
|
|
30
|
+
{/* Sidebar - hidden on mobile unless open, always visible on md+ */}
|
|
31
|
+
<aside
|
|
32
|
+
className={`
|
|
33
|
+
fixed inset-y-0 left-0 z-50 w-64 bg-[#0a0a0a] border-r border-[#1a1a1a] p-4 transform transition-transform duration-200 ease-in-out
|
|
34
|
+
md:relative md:w-56 md:translate-x-0 md:z-auto
|
|
35
|
+
${isOpen ? "translate-x-0" : "-translate-x-full"}
|
|
36
|
+
`}
|
|
37
|
+
>
|
|
38
|
+
{/* Mobile header with close button */}
|
|
39
|
+
<div className="flex items-center justify-between mb-4 md:hidden">
|
|
40
|
+
<div className="flex items-center gap-2">
|
|
41
|
+
<span className="text-[#f97316]">>_</span>
|
|
42
|
+
<span className="text-lg tracking-wider">apteva</span>
|
|
43
|
+
</div>
|
|
44
|
+
<button
|
|
45
|
+
onClick={onClose}
|
|
46
|
+
className="p-2 text-[#666] hover:text-[#e0e0e0] transition"
|
|
47
|
+
>
|
|
48
|
+
<CloseIcon />
|
|
49
|
+
</button>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<nav className="space-y-1">
|
|
53
|
+
<NavButton
|
|
54
|
+
icon={<DashboardIcon />}
|
|
55
|
+
label="Dashboard"
|
|
56
|
+
active={route === "dashboard"}
|
|
57
|
+
onClick={() => handleNavigate("dashboard")}
|
|
58
|
+
/>
|
|
59
|
+
<NavButton
|
|
60
|
+
icon={<AgentsIcon />}
|
|
61
|
+
label="Agents"
|
|
62
|
+
active={route === "agents"}
|
|
63
|
+
onClick={() => handleNavigate("agents")}
|
|
64
|
+
badge={agentCount > 0 ? String(agentCount) : undefined}
|
|
65
|
+
/>
|
|
66
|
+
<NavButton
|
|
67
|
+
icon={<TasksIcon />}
|
|
68
|
+
label="Tasks"
|
|
69
|
+
active={route === "tasks"}
|
|
70
|
+
onClick={() => handleNavigate("tasks")}
|
|
71
|
+
badge={taskCount && taskCount > 0 ? String(taskCount) : undefined}
|
|
72
|
+
/>
|
|
73
|
+
<NavButton
|
|
74
|
+
icon={<McpIcon />}
|
|
75
|
+
label="MCP"
|
|
76
|
+
active={route === "mcp"}
|
|
77
|
+
onClick={() => handleNavigate("mcp")}
|
|
78
|
+
/>
|
|
79
|
+
<NavButton
|
|
80
|
+
icon={<TelemetryIcon />}
|
|
81
|
+
label="Telemetry"
|
|
82
|
+
active={route === "telemetry"}
|
|
83
|
+
onClick={() => handleNavigate("telemetry")}
|
|
84
|
+
/>
|
|
85
|
+
<NavButton
|
|
86
|
+
icon={<ApiIcon />}
|
|
87
|
+
label="API"
|
|
88
|
+
active={route === "api"}
|
|
89
|
+
onClick={() => handleNavigate("api")}
|
|
90
|
+
/>
|
|
91
|
+
<NavButton
|
|
92
|
+
icon={<SettingsIcon />}
|
|
93
|
+
label="Settings"
|
|
94
|
+
active={route === "settings"}
|
|
95
|
+
onClick={() => handleNavigate("settings")}
|
|
96
|
+
/>
|
|
97
|
+
</nav>
|
|
98
|
+
</aside>
|
|
99
|
+
</>
|
|
56
100
|
);
|
|
57
101
|
}
|
|
58
102
|
|