clawport-ui 0.1.0
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/.env.example +35 -0
- package/BRANDING.md +131 -0
- package/CLAUDE.md +252 -0
- package/README.md +262 -0
- package/SETUP.md +337 -0
- package/app/agents/[id]/page.tsx +727 -0
- package/app/api/agents/route.ts +12 -0
- package/app/api/chat/[id]/route.ts +139 -0
- package/app/api/cron-runs/route.ts +13 -0
- package/app/api/crons/route.ts +12 -0
- package/app/api/kanban/chat/[id]/route.ts +119 -0
- package/app/api/kanban/chat-history/[ticketId]/route.ts +36 -0
- package/app/api/memory/route.ts +12 -0
- package/app/api/transcribe/route.ts +37 -0
- package/app/api/tts/route.ts +42 -0
- package/app/chat/[id]/page.tsx +10 -0
- package/app/chat/page.tsx +200 -0
- package/app/crons/page.tsx +870 -0
- package/app/docs/page.tsx +399 -0
- package/app/favicon.ico +0 -0
- package/app/globals.css +692 -0
- package/app/kanban/page.tsx +327 -0
- package/app/layout.tsx +45 -0
- package/app/memory/page.tsx +685 -0
- package/app/page.tsx +817 -0
- package/app/providers.tsx +37 -0
- package/app/settings/page.tsx +901 -0
- package/app/settings-provider.tsx +209 -0
- package/components/AgentAvatar.tsx +54 -0
- package/components/AgentNode.tsx +122 -0
- package/components/Breadcrumbs.tsx +126 -0
- package/components/DynamicFavicon.tsx +62 -0
- package/components/ErrorState.tsx +97 -0
- package/components/FeedView.tsx +494 -0
- package/components/GlobalSearch.tsx +571 -0
- package/components/GridView.tsx +532 -0
- package/components/ManorMap.tsx +157 -0
- package/components/MobileSidebar.tsx +251 -0
- package/components/NavLinks.tsx +271 -0
- package/components/OnboardingWizard.tsx +1067 -0
- package/components/Sidebar.tsx +115 -0
- package/components/ThemeToggle.tsx +108 -0
- package/components/chat/AgentList.tsx +537 -0
- package/components/chat/ConversationView.tsx +1047 -0
- package/components/chat/FileAttachment.tsx +140 -0
- package/components/chat/MediaPreview.tsx +111 -0
- package/components/chat/VoiceMessage.tsx +139 -0
- package/components/crons/PipelineGraph.tsx +327 -0
- package/components/crons/WeeklySchedule.tsx +630 -0
- package/components/docs/AgentsSection.tsx +209 -0
- package/components/docs/ApiReferenceSection.tsx +256 -0
- package/components/docs/ArchitectureSection.tsx +221 -0
- package/components/docs/ComponentsSection.tsx +253 -0
- package/components/docs/CronSystemSection.tsx +235 -0
- package/components/docs/DocSection.tsx +346 -0
- package/components/docs/GettingStartedSection.tsx +169 -0
- package/components/docs/ThemingSection.tsx +257 -0
- package/components/docs/TroubleshootingSection.tsx +200 -0
- package/components/kanban/AgentPicker.tsx +321 -0
- package/components/kanban/CreateTicketModal.tsx +333 -0
- package/components/kanban/KanbanBoard.tsx +70 -0
- package/components/kanban/KanbanColumn.tsx +166 -0
- package/components/kanban/TicketCard.tsx +245 -0
- package/components/kanban/TicketDetailPanel.tsx +850 -0
- package/components/ui/badge.tsx +48 -0
- package/components/ui/button.tsx +64 -0
- package/components/ui/card.tsx +92 -0
- package/components/ui/dialog.tsx +158 -0
- package/components/ui/scroll-area.tsx +58 -0
- package/components/ui/separator.tsx +28 -0
- package/components/ui/skeleton.tsx +27 -0
- package/components/ui/tabs.tsx +91 -0
- package/components/ui/tooltip.tsx +57 -0
- package/components.json +23 -0
- package/docs/API.md +648 -0
- package/docs/COMPONENTS.md +1059 -0
- package/docs/THEMING.md +795 -0
- package/lib/agents-registry.ts +35 -0
- package/lib/agents.json +282 -0
- package/lib/agents.test.ts +367 -0
- package/lib/agents.ts +32 -0
- package/lib/anthropic.test.ts +422 -0
- package/lib/anthropic.ts +220 -0
- package/lib/api-error.ts +16 -0
- package/lib/audio-recorder.test.ts +72 -0
- package/lib/audio-recorder.ts +169 -0
- package/lib/conversations.test.ts +331 -0
- package/lib/conversations.ts +117 -0
- package/lib/cron-pipelines.test.ts +69 -0
- package/lib/cron-pipelines.ts +58 -0
- package/lib/cron-runs.test.ts +118 -0
- package/lib/cron-runs.ts +67 -0
- package/lib/cron-utils.test.ts +222 -0
- package/lib/cron-utils.ts +160 -0
- package/lib/crons.test.ts +502 -0
- package/lib/crons.ts +114 -0
- package/lib/env.test.ts +44 -0
- package/lib/env.ts +14 -0
- package/lib/kanban/automation.test.ts +245 -0
- package/lib/kanban/automation.ts +143 -0
- package/lib/kanban/chat-store.test.ts +149 -0
- package/lib/kanban/chat-store.ts +81 -0
- package/lib/kanban/store.test.ts +238 -0
- package/lib/kanban/store.ts +98 -0
- package/lib/kanban/types.ts +50 -0
- package/lib/kanban/useAgentWork.ts +78 -0
- package/lib/memory.ts +45 -0
- package/lib/multimodal.test.ts +219 -0
- package/lib/multimodal.ts +68 -0
- package/lib/pipeline.integration.test.ts +343 -0
- package/lib/sanitize.ts +194 -0
- package/lib/settings.test.ts +137 -0
- package/lib/settings.ts +94 -0
- package/lib/styles.ts +24 -0
- package/lib/themes.ts +9 -0
- package/lib/transcribe.test.ts +141 -0
- package/lib/transcribe.ts +111 -0
- package/lib/types.ts +66 -0
- package/lib/utils.ts +6 -0
- package/lib/validation.test.ts +132 -0
- package/lib/validation.ts +80 -0
- package/next.config.ts +7 -0
- package/package.json +56 -0
- package/postcss.config.mjs +7 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/scripts/setup.mjs +215 -0
- package/tsconfig.json +34 -0
- package/vitest.config.ts +17 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Heading,
|
|
3
|
+
SubHeading,
|
|
4
|
+
Paragraph,
|
|
5
|
+
CodeBlock,
|
|
6
|
+
InlineCode,
|
|
7
|
+
Table,
|
|
8
|
+
BulletList,
|
|
9
|
+
InfoCard,
|
|
10
|
+
} from "./DocSection";
|
|
11
|
+
|
|
12
|
+
export function ComponentsSection() {
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
<Heading>Components</Heading>
|
|
16
|
+
<Paragraph>
|
|
17
|
+
ClawPort's component tree follows the standard Next.js App Router
|
|
18
|
+
pattern: providers wrap the entire app, layout components handle the
|
|
19
|
+
sidebar and navigation, and each route renders its own page component.
|
|
20
|
+
</Paragraph>
|
|
21
|
+
|
|
22
|
+
<SubHeading>Component Tree</SubHeading>
|
|
23
|
+
<CodeBlock>
|
|
24
|
+
{`RootLayout (app/layout.tsx)
|
|
25
|
+
ThemeProvider (app/providers.tsx)
|
|
26
|
+
SettingsProvider (app/settings-provider.tsx)
|
|
27
|
+
DynamicFavicon
|
|
28
|
+
OnboardingWizard
|
|
29
|
+
Sidebar
|
|
30
|
+
NavLinks
|
|
31
|
+
ThemeToggle
|
|
32
|
+
MobileSidebar
|
|
33
|
+
GlobalSearch
|
|
34
|
+
<main> (page content)
|
|
35
|
+
HomePage ............. / (org chart, grid, feed)
|
|
36
|
+
OrgMap (React Flow)
|
|
37
|
+
AgentNode
|
|
38
|
+
AgentAvatar
|
|
39
|
+
GridView
|
|
40
|
+
FeedView
|
|
41
|
+
ChatPage .............. /chat
|
|
42
|
+
AgentList
|
|
43
|
+
ConversationView
|
|
44
|
+
VoiceMessage
|
|
45
|
+
FileAttachment
|
|
46
|
+
MediaPreview
|
|
47
|
+
AgentDetailPage ....... /agents/[id]
|
|
48
|
+
KanbanPage ............ /kanban
|
|
49
|
+
KanbanBoard
|
|
50
|
+
KanbanColumn
|
|
51
|
+
TicketCard
|
|
52
|
+
TicketDetailPanel
|
|
53
|
+
CreateTicketModal
|
|
54
|
+
AgentPicker
|
|
55
|
+
CronsPage ............. /crons
|
|
56
|
+
WeeklySchedule
|
|
57
|
+
PipelineGraph
|
|
58
|
+
MemoryPage ............ /memory
|
|
59
|
+
DocsPage .............. /docs
|
|
60
|
+
SettingsPage .......... /settings`}
|
|
61
|
+
</CodeBlock>
|
|
62
|
+
|
|
63
|
+
<SubHeading>Providers</SubHeading>
|
|
64
|
+
<InfoCard title="ThemeProvider">
|
|
65
|
+
<BulletList
|
|
66
|
+
items={[
|
|
67
|
+
<>
|
|
68
|
+
<strong style={{ color: "var(--text-primary)" }}>File:</strong>{" "}
|
|
69
|
+
<InlineCode>app/providers.tsx</InlineCode>
|
|
70
|
+
</>,
|
|
71
|
+
"Manages the active theme and applies it via data-theme attribute on <html>",
|
|
72
|
+
<>
|
|
73
|
+
Consumer hook:{" "}
|
|
74
|
+
<InlineCode>{"const { theme, setTheme } = useTheme()"}</InlineCode>
|
|
75
|
+
</>,
|
|
76
|
+
<>
|
|
77
|
+
Persists to <InlineCode>localStorage('clawport-theme')</InlineCode>,
|
|
78
|
+
defaults to 'dark'
|
|
79
|
+
</>,
|
|
80
|
+
]}
|
|
81
|
+
/>
|
|
82
|
+
</InfoCard>
|
|
83
|
+
|
|
84
|
+
<InfoCard title="SettingsProvider">
|
|
85
|
+
<BulletList
|
|
86
|
+
items={[
|
|
87
|
+
<>
|
|
88
|
+
<strong style={{ color: "var(--text-primary)" }}>File:</strong>{" "}
|
|
89
|
+
<InlineCode>app/settings-provider.tsx</InlineCode>
|
|
90
|
+
</>,
|
|
91
|
+
"Central state management for all user-configurable settings",
|
|
92
|
+
<>
|
|
93
|
+
Consumer hook:{" "}
|
|
94
|
+
<InlineCode>{"const { settings, setAccentColor, ... } = useSettings()"}</InlineCode>
|
|
95
|
+
</>,
|
|
96
|
+
"Applies accent color CSS variables directly to document.documentElement",
|
|
97
|
+
<>
|
|
98
|
+
Persists to{" "}
|
|
99
|
+
<InlineCode>localStorage('clawport-settings')</InlineCode>
|
|
100
|
+
</>,
|
|
101
|
+
]}
|
|
102
|
+
/>
|
|
103
|
+
</InfoCard>
|
|
104
|
+
|
|
105
|
+
<SubHeading>Layout Components</SubHeading>
|
|
106
|
+
<Table
|
|
107
|
+
headers={["Component", "File", "Purpose"]}
|
|
108
|
+
rows={[
|
|
109
|
+
[
|
|
110
|
+
"Sidebar",
|
|
111
|
+
<InlineCode key="s">components/Sidebar.tsx</InlineCode>,
|
|
112
|
+
"Desktop sidebar wrapper. Renders NavLinks, ThemeToggle, MobileSidebar, GlobalSearch.",
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"NavLinks",
|
|
116
|
+
<InlineCode key="n">components/NavLinks.tsx</InlineCode>,
|
|
117
|
+
"Sidebar nav links with icons, badges, and operator identity footer.",
|
|
118
|
+
],
|
|
119
|
+
[
|
|
120
|
+
"MobileSidebar",
|
|
121
|
+
<InlineCode key="m">components/MobileSidebar.tsx</InlineCode>,
|
|
122
|
+
"Fixed mobile header bar with hamburger menu and slide-out sidebar panel.",
|
|
123
|
+
],
|
|
124
|
+
[
|
|
125
|
+
"GlobalSearch",
|
|
126
|
+
<InlineCode key="g">components/GlobalSearch.tsx</InlineCode>,
|
|
127
|
+
"Cmd+K search palette with fuzzy search across agents, pages, and crons.",
|
|
128
|
+
],
|
|
129
|
+
[
|
|
130
|
+
"ThemeToggle",
|
|
131
|
+
<InlineCode key="t">components/ThemeToggle.tsx</InlineCode>,
|
|
132
|
+
"Theme selector rendered as a row of emoji buttons with radiogroup semantics.",
|
|
133
|
+
],
|
|
134
|
+
]}
|
|
135
|
+
/>
|
|
136
|
+
|
|
137
|
+
<SubHeading>Chat Components</SubHeading>
|
|
138
|
+
<Table
|
|
139
|
+
headers={["Component", "Purpose"]}
|
|
140
|
+
rows={[
|
|
141
|
+
[
|
|
142
|
+
"ConversationView",
|
|
143
|
+
"Main chat: messages, SSE streaming, file attachments, TTS playback, voice recording, markdown rendering.",
|
|
144
|
+
],
|
|
145
|
+
[
|
|
146
|
+
"AgentList",
|
|
147
|
+
"Agent selection sidebar for chat. Desktop (300px fixed) and mobile (full-width) variants.",
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"VoiceMessage",
|
|
151
|
+
"Audio waveform playback with play/pause toggle and animated progress bars.",
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
"FileAttachment",
|
|
155
|
+
"File attachment bubble with type-specific icon and download button.",
|
|
156
|
+
],
|
|
157
|
+
[
|
|
158
|
+
"MediaPreview",
|
|
159
|
+
"Horizontal strip of staged attachment thumbnails before sending.",
|
|
160
|
+
],
|
|
161
|
+
]}
|
|
162
|
+
/>
|
|
163
|
+
|
|
164
|
+
<SubHeading>Map Components</SubHeading>
|
|
165
|
+
<Table
|
|
166
|
+
headers={["Component", "Purpose"]}
|
|
167
|
+
rows={[
|
|
168
|
+
[
|
|
169
|
+
"OrgMap",
|
|
170
|
+
"React Flow org chart with BFS-based hierarchical layout, edge highlighting, and interactive zoom.",
|
|
171
|
+
],
|
|
172
|
+
[
|
|
173
|
+
"AgentNode",
|
|
174
|
+
"Custom React Flow node: avatar, name, title, cron health indicator, selection state.",
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
"GridView",
|
|
178
|
+
"Card-based grid with team grouping hierarchy. Responsive: 1/2/3 columns.",
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
"FeedView",
|
|
182
|
+
"Activity feed focused on cron status with stat cards and filter pills.",
|
|
183
|
+
],
|
|
184
|
+
]}
|
|
185
|
+
/>
|
|
186
|
+
|
|
187
|
+
<SubHeading>Kanban Components</SubHeading>
|
|
188
|
+
<Table
|
|
189
|
+
headers={["Component", "Purpose"]}
|
|
190
|
+
rows={[
|
|
191
|
+
[
|
|
192
|
+
"KanbanBoard",
|
|
193
|
+
"Four-column board (Backlog, In Progress, Review, Done) with agent filter.",
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"KanbanColumn",
|
|
197
|
+
"Single column with HTML5 drag-and-drop support and drop zone highlight.",
|
|
198
|
+
],
|
|
199
|
+
[
|
|
200
|
+
"TicketCard",
|
|
201
|
+
"Draggable card: priority dot, title, agent avatar, work state indicator.",
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
"TicketDetailPanel",
|
|
205
|
+
"Slide-in side panel for ticket details and inline agent chat.",
|
|
206
|
+
],
|
|
207
|
+
[
|
|
208
|
+
"CreateTicketModal",
|
|
209
|
+
"Modal for creating tickets with title, description, priority, agent assignment.",
|
|
210
|
+
],
|
|
211
|
+
]}
|
|
212
|
+
/>
|
|
213
|
+
|
|
214
|
+
<SubHeading>Other Key Components</SubHeading>
|
|
215
|
+
<Table
|
|
216
|
+
headers={["Component", "Purpose"]}
|
|
217
|
+
rows={[
|
|
218
|
+
[
|
|
219
|
+
"OnboardingWizard",
|
|
220
|
+
"5-step first-run setup wizard (name, theme, accent, voice, overview). Re-runnable from Settings.",
|
|
221
|
+
],
|
|
222
|
+
[
|
|
223
|
+
"AgentAvatar",
|
|
224
|
+
"Agent avatar: profile image, emoji on colored background, or emoji-only mode.",
|
|
225
|
+
],
|
|
226
|
+
[
|
|
227
|
+
"DynamicFavicon",
|
|
228
|
+
"Generates favicon from portal emoji/icon using Canvas API.",
|
|
229
|
+
],
|
|
230
|
+
[
|
|
231
|
+
"ErrorState",
|
|
232
|
+
"Full-screen error display with optional retry button.",
|
|
233
|
+
],
|
|
234
|
+
[
|
|
235
|
+
"Breadcrumbs",
|
|
236
|
+
"Breadcrumb navigation bar with Lucide ChevronRight separators.",
|
|
237
|
+
],
|
|
238
|
+
]}
|
|
239
|
+
/>
|
|
240
|
+
|
|
241
|
+
<SubHeading>UI Primitives</SubHeading>
|
|
242
|
+
<Paragraph>
|
|
243
|
+
Radix-based primitive components in{" "}
|
|
244
|
+
<InlineCode>components/ui/</InlineCode> (shadcn/ui-style wrappers):
|
|
245
|
+
</Paragraph>
|
|
246
|
+
<BulletList
|
|
247
|
+
items={[
|
|
248
|
+
"Badge, Button, Card, Dialog, ScrollArea, Separator, Skeleton, Tabs, Tooltip",
|
|
249
|
+
]}
|
|
250
|
+
/>
|
|
251
|
+
</>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Heading,
|
|
3
|
+
SubHeading,
|
|
4
|
+
Paragraph,
|
|
5
|
+
CodeBlock,
|
|
6
|
+
InlineCode,
|
|
7
|
+
Table,
|
|
8
|
+
BulletList,
|
|
9
|
+
Callout,
|
|
10
|
+
} from "./DocSection";
|
|
11
|
+
|
|
12
|
+
export function CronSystemSection() {
|
|
13
|
+
return (
|
|
14
|
+
<>
|
|
15
|
+
<Heading>Cron System</Heading>
|
|
16
|
+
<Paragraph>
|
|
17
|
+
ClawPort provides a full cron monitoring dashboard with three views:
|
|
18
|
+
overview (health donut, attention cards, error banners), weekly schedule
|
|
19
|
+
(7-day calendar grid), and pipeline graph (React Flow dependency
|
|
20
|
+
visualization). Data is fetched from the OpenClaw CLI and auto-refreshes
|
|
21
|
+
every 60 seconds.
|
|
22
|
+
</Paragraph>
|
|
23
|
+
|
|
24
|
+
<SubHeading>CronJob Schema</SubHeading>
|
|
25
|
+
<Table
|
|
26
|
+
headers={["Field", "Type", "Description"]}
|
|
27
|
+
rows={[
|
|
28
|
+
[<InlineCode key="id">id</InlineCode>, "string", "Job identifier"],
|
|
29
|
+
[
|
|
30
|
+
<InlineCode key="n">name</InlineCode>,
|
|
31
|
+
"string",
|
|
32
|
+
"Job name (used to match owning agent by prefix)",
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
<InlineCode key="s">schedule</InlineCode>,
|
|
36
|
+
"string",
|
|
37
|
+
"Raw cron expression",
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
<InlineCode key="sd">scheduleDescription</InlineCode>,
|
|
41
|
+
"string",
|
|
42
|
+
'Human-readable (e.g., "Daily at 8 AM")',
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
<InlineCode key="tz">timezone</InlineCode>,
|
|
46
|
+
"string | null",
|
|
47
|
+
"Timezone from schedule object, if present",
|
|
48
|
+
],
|
|
49
|
+
[
|
|
50
|
+
<InlineCode key="st">status</InlineCode>,
|
|
51
|
+
'"ok" | "error" | "idle"',
|
|
52
|
+
"Last run outcome",
|
|
53
|
+
],
|
|
54
|
+
[
|
|
55
|
+
<InlineCode key="lr">lastRun</InlineCode>,
|
|
56
|
+
"string | null",
|
|
57
|
+
"ISO 8601 timestamp of last execution",
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
<InlineCode key="nr">nextRun</InlineCode>,
|
|
61
|
+
"string | null",
|
|
62
|
+
"ISO 8601 timestamp of next scheduled run",
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
<InlineCode key="le">lastError</InlineCode>,
|
|
66
|
+
"string | null",
|
|
67
|
+
"Error message from last failed run",
|
|
68
|
+
],
|
|
69
|
+
[
|
|
70
|
+
<InlineCode key="ai">agentId</InlineCode>,
|
|
71
|
+
"string | null",
|
|
72
|
+
"Owning agent ID (matched by job name prefix)",
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
<InlineCode key="en">enabled</InlineCode>,
|
|
76
|
+
"boolean",
|
|
77
|
+
"Whether the job is active",
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
<InlineCode key="dl">delivery</InlineCode>,
|
|
81
|
+
"CronDelivery | null",
|
|
82
|
+
"Delivery config (mode, channel, to)",
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
<InlineCode key="ld">lastDurationMs</InlineCode>,
|
|
86
|
+
"number | null",
|
|
87
|
+
"Duration of last run in milliseconds",
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
<InlineCode key="ce">consecutiveErrors</InlineCode>,
|
|
91
|
+
"number",
|
|
92
|
+
"Count of consecutive failed runs",
|
|
93
|
+
],
|
|
94
|
+
]}
|
|
95
|
+
/>
|
|
96
|
+
|
|
97
|
+
<SubHeading>CronRun Schema</SubHeading>
|
|
98
|
+
<Paragraph>
|
|
99
|
+
Run history is parsed from JSONL log files at{" "}
|
|
100
|
+
<InlineCode>$WORKSPACE_PATH/../cron/runs/</InlineCode>. Each line in the
|
|
101
|
+
JSONL file represents one run.
|
|
102
|
+
</Paragraph>
|
|
103
|
+
<Table
|
|
104
|
+
headers={["Field", "Type", "Description"]}
|
|
105
|
+
rows={[
|
|
106
|
+
[
|
|
107
|
+
<InlineCode key="ts">ts</InlineCode>,
|
|
108
|
+
"number",
|
|
109
|
+
"Unix timestamp (milliseconds) of the run",
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
<InlineCode key="j">jobId</InlineCode>,
|
|
113
|
+
"string",
|
|
114
|
+
"Job identifier",
|
|
115
|
+
],
|
|
116
|
+
[
|
|
117
|
+
<InlineCode key="s">status</InlineCode>,
|
|
118
|
+
'"ok" | "error"',
|
|
119
|
+
"Run outcome",
|
|
120
|
+
],
|
|
121
|
+
[
|
|
122
|
+
<InlineCode key="su">summary</InlineCode>,
|
|
123
|
+
"string | null",
|
|
124
|
+
"Summary of what the run produced",
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
<InlineCode key="e">error</InlineCode>,
|
|
128
|
+
"string | null",
|
|
129
|
+
"Error message if the run failed",
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
<InlineCode key="d">durationMs</InlineCode>,
|
|
133
|
+
"number",
|
|
134
|
+
"Duration in milliseconds",
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
<InlineCode key="ds">deliveryStatus</InlineCode>,
|
|
138
|
+
"string | null",
|
|
139
|
+
"Delivery outcome",
|
|
140
|
+
],
|
|
141
|
+
]}
|
|
142
|
+
/>
|
|
143
|
+
|
|
144
|
+
<SubHeading>Agent Ownership</SubHeading>
|
|
145
|
+
<Paragraph>
|
|
146
|
+
Cron jobs are matched to agents by job name prefix. When the API fetches
|
|
147
|
+
crons via <InlineCode>openclaw cron list --json</InlineCode>, it
|
|
148
|
+
enriches each job with an <InlineCode>agentId</InlineCode> field by
|
|
149
|
+
checking whether the job name starts with an agent's id. This enables
|
|
150
|
+
the UI to show agent avatars next to cron entries and filter crons by
|
|
151
|
+
agent.
|
|
152
|
+
</Paragraph>
|
|
153
|
+
|
|
154
|
+
<SubHeading>Delivery Configuration</SubHeading>
|
|
155
|
+
<Table
|
|
156
|
+
headers={["Field", "Type", "Description"]}
|
|
157
|
+
rows={[
|
|
158
|
+
[
|
|
159
|
+
<InlineCode key="m">mode</InlineCode>,
|
|
160
|
+
"string",
|
|
161
|
+
"Delivery mode",
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
<InlineCode key="c">channel</InlineCode>,
|
|
165
|
+
"string",
|
|
166
|
+
"Delivery channel",
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
<InlineCode key="t">to</InlineCode>,
|
|
170
|
+
"string | null",
|
|
171
|
+
"Delivery recipient",
|
|
172
|
+
],
|
|
173
|
+
]}
|
|
174
|
+
/>
|
|
175
|
+
|
|
176
|
+
<SubHeading>Status Types</SubHeading>
|
|
177
|
+
<BulletList
|
|
178
|
+
items={[
|
|
179
|
+
<>
|
|
180
|
+
<strong style={{ color: "var(--system-green)" }}>ok</strong> -- Last
|
|
181
|
+
run completed successfully
|
|
182
|
+
</>,
|
|
183
|
+
<>
|
|
184
|
+
<strong style={{ color: "var(--system-red)" }}>error</strong> -- Last
|
|
185
|
+
run failed (error details in lastError)
|
|
186
|
+
</>,
|
|
187
|
+
<>
|
|
188
|
+
<strong style={{ color: "var(--text-tertiary)" }}>idle</strong> --
|
|
189
|
+
Job has never run or has no recent activity
|
|
190
|
+
</>,
|
|
191
|
+
]}
|
|
192
|
+
/>
|
|
193
|
+
|
|
194
|
+
<SubHeading>Monitoring Views</SubHeading>
|
|
195
|
+
<BulletList
|
|
196
|
+
items={[
|
|
197
|
+
<>
|
|
198
|
+
<strong style={{ color: "var(--text-primary)" }}>Overview</strong>{" "}
|
|
199
|
+
-- Health donut chart (SVG), attention-needed cards for errored
|
|
200
|
+
crons, delivery stats, error banners with expandable details, recent
|
|
201
|
+
runs list
|
|
202
|
+
</>,
|
|
203
|
+
<>
|
|
204
|
+
<strong style={{ color: "var(--text-primary)" }}>Schedule</strong>{" "}
|
|
205
|
+
-- Seven-day calendar grid showing when cron jobs are scheduled to
|
|
206
|
+
run. Current time indicator as a red horizontal line.
|
|
207
|
+
</>,
|
|
208
|
+
<>
|
|
209
|
+
<strong style={{ color: "var(--text-primary)" }}>Pipelines</strong>{" "}
|
|
210
|
+
-- React Flow visualization of cron job pipelines showing
|
|
211
|
+
dependencies between stages
|
|
212
|
+
</>,
|
|
213
|
+
]}
|
|
214
|
+
/>
|
|
215
|
+
|
|
216
|
+
<Callout type="note">
|
|
217
|
+
The cron page auto-refreshes every 60 seconds. The sidebar also fetches
|
|
218
|
+
cron error counts on mount and displays a red pulsing dot badge when
|
|
219
|
+
errors are present.
|
|
220
|
+
</Callout>
|
|
221
|
+
|
|
222
|
+
<SubHeading>API Endpoint</SubHeading>
|
|
223
|
+
<CodeBlock title="terminal">
|
|
224
|
+
{`# Fetch all crons
|
|
225
|
+
curl http://localhost:3000/api/crons
|
|
226
|
+
|
|
227
|
+
# Fetch run history for a specific job
|
|
228
|
+
curl "http://localhost:3000/api/cron-runs?jobId=pulse-daily-digest"
|
|
229
|
+
|
|
230
|
+
# Fetch all run history
|
|
231
|
+
curl http://localhost:3000/api/cron-runs`}
|
|
232
|
+
</CodeBlock>
|
|
233
|
+
</>
|
|
234
|
+
);
|
|
235
|
+
}
|