@polpo-ai/dashboard 0.1.3 → 0.15.8

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.
Files changed (184) hide show
  1. package/LICENSE +3 -1
  2. package/README.md +13 -40
  3. package/dist/components.d.ts +53 -0
  4. package/dist/components.d.ts.map +1 -0
  5. package/dist/components.js +81 -0
  6. package/dist/components.js.map +1 -0
  7. package/dist/host.d.ts +24 -0
  8. package/dist/host.d.ts.map +1 -0
  9. package/dist/host.js +18 -0
  10. package/dist/host.js.map +1 -0
  11. package/dist/index.d.ts +13 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +11 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/test/setup.d.ts +2 -0
  16. package/dist/test/setup.d.ts.map +1 -0
  17. package/dist/test/setup.js +2 -0
  18. package/dist/test/setup.js.map +1 -0
  19. package/dist/views/agent-detail.d.ts +4 -0
  20. package/dist/views/agent-detail.d.ts.map +1 -0
  21. package/dist/views/agent-detail.js +31 -0
  22. package/dist/views/agent-detail.js.map +1 -0
  23. package/dist/views/agents.d.ts +2 -0
  24. package/dist/views/agents.d.ts.map +1 -0
  25. package/dist/views/agents.js +81 -0
  26. package/dist/views/agents.js.map +1 -0
  27. package/dist/views/files.d.ts +2 -0
  28. package/dist/views/files.d.ts.map +1 -0
  29. package/dist/views/files.js +30 -0
  30. package/dist/views/files.js.map +1 -0
  31. package/dist/views/memory.d.ts +2 -0
  32. package/dist/views/memory.d.ts.map +1 -0
  33. package/dist/views/memory.js +19 -0
  34. package/dist/views/memory.js.map +1 -0
  35. package/dist/views/playground.d.ts +4 -0
  36. package/dist/views/playground.d.ts.map +1 -0
  37. package/dist/views/playground.js +43 -0
  38. package/dist/views/playground.js.map +1 -0
  39. package/dist/views/session-detail.d.ts +4 -0
  40. package/dist/views/session-detail.d.ts.map +1 -0
  41. package/dist/views/session-detail.js +23 -0
  42. package/dist/views/session-detail.js.map +1 -0
  43. package/dist/views/sessions.d.ts +2 -0
  44. package/dist/views/sessions.d.ts.map +1 -0
  45. package/dist/views/sessions.js +17 -0
  46. package/dist/views/sessions.js.map +1 -0
  47. package/dist/views/skills.d.ts +2 -0
  48. package/dist/views/skills.d.ts.map +1 -0
  49. package/dist/views/skills.js +16 -0
  50. package/dist/views/skills.js.map +1 -0
  51. package/package.json +47 -83
  52. package/src/styles.css +169 -0
  53. package/app/(dashboard)/error.tsx +0 -47
  54. package/app/(dashboard)/layout.tsx +0 -41
  55. package/app/(dashboard)/loading.tsx +0 -30
  56. package/app/(dashboard)/projects/[id]/agents/[name]/memory/view.tsx +0 -36
  57. package/app/(dashboard)/projects/[id]/agents/[name]/models-view.tsx +0 -30
  58. package/app/(dashboard)/projects/[id]/agents/[name]/page.tsx +0 -51
  59. package/app/(dashboard)/projects/[id]/agents/[name]/prompt/view.tsx +0 -211
  60. package/app/(dashboard)/projects/[id]/agents/[name]/skills/view.tsx +0 -84
  61. package/app/(dashboard)/projects/[id]/agents/[name]/tools/view.tsx +0 -525
  62. package/app/(dashboard)/projects/[id]/agents/[name]/vault/view.tsx +0 -61
  63. package/app/(dashboard)/projects/[id]/agents/page.tsx +0 -39
  64. package/app/(dashboard)/projects/[id]/agents/view.tsx +0 -283
  65. package/app/(dashboard)/projects/[id]/layout.tsx +0 -11
  66. package/app/(dashboard)/projects/[id]/logs/page.tsx +0 -27
  67. package/app/(dashboard)/projects/[id]/logs/view.tsx +0 -184
  68. package/app/(dashboard)/projects/[id]/memory/page.tsx +0 -40
  69. package/app/(dashboard)/projects/[id]/memory/view.tsx +0 -17
  70. package/app/(dashboard)/projects/[id]/missions/[missionId]/page.tsx +0 -88
  71. package/app/(dashboard)/projects/[id]/missions/[missionId]/view.tsx +0 -569
  72. package/app/(dashboard)/projects/[id]/missions/page.tsx +0 -32
  73. package/app/(dashboard)/projects/[id]/missions/view.tsx +0 -282
  74. package/app/(dashboard)/projects/[id]/onboarding-checklist.tsx +0 -359
  75. package/app/(dashboard)/projects/[id]/page.tsx +0 -68
  76. package/app/(dashboard)/projects/[id]/playbooks/[name]/page.tsx +0 -5
  77. package/app/(dashboard)/projects/[id]/playbooks/[name]/view.tsx +0 -433
  78. package/app/(dashboard)/projects/[id]/playbooks/page.tsx +0 -5
  79. package/app/(dashboard)/projects/[id]/playbooks/view.tsx +0 -222
  80. package/app/(dashboard)/projects/[id]/schedules/page.tsx +0 -44
  81. package/app/(dashboard)/projects/[id]/schedules/view.tsx +0 -385
  82. package/app/(dashboard)/projects/[id]/sessions/[sessionId]/page.tsx +0 -55
  83. package/app/(dashboard)/projects/[id]/sessions/[sessionId]/raw-view.tsx +0 -373
  84. package/app/(dashboard)/projects/[id]/sessions/[sessionId]/view.tsx +0 -124
  85. package/app/(dashboard)/projects/[id]/sessions/page.tsx +0 -31
  86. package/app/(dashboard)/projects/[id]/sessions/view.tsx +0 -242
  87. package/app/(dashboard)/projects/[id]/settings/page.tsx +0 -52
  88. package/app/(dashboard)/projects/[id]/skills/[name]/page.tsx +0 -65
  89. package/app/(dashboard)/projects/[id]/skills/[name]/view.tsx +0 -227
  90. package/app/(dashboard)/projects/[id]/skills/page.tsx +0 -31
  91. package/app/(dashboard)/projects/[id]/skills/view.tsx +0 -243
  92. package/app/(dashboard)/projects/[id]/storage/page.tsx +0 -5
  93. package/app/(dashboard)/projects/[id]/storage/view.tsx +0 -385
  94. package/app/(dashboard)/projects/[id]/tasks/[taskId]/activity/view.tsx +0 -336
  95. package/app/(dashboard)/projects/[id]/tasks/[taskId]/assessment/view.tsx +0 -113
  96. package/app/(dashboard)/projects/[id]/tasks/[taskId]/blueprint.ts +0 -72
  97. package/app/(dashboard)/projects/[id]/tasks/[taskId]/output/view.tsx +0 -90
  98. package/app/(dashboard)/projects/[id]/tasks/[taskId]/page.tsx +0 -63
  99. package/app/(dashboard)/projects/[id]/tasks/[taskId]/view.tsx +0 -137
  100. package/app/(dashboard)/projects/[id]/tasks/page.tsx +0 -40
  101. package/app/(dashboard)/projects/[id]/tasks/view.tsx +0 -421
  102. package/app/(dashboard)/projects/[id]/view.tsx +0 -421
  103. package/app/(dashboard)/projects/[id]/welcome-banner.tsx +0 -156
  104. package/app/(dashboard)/projects/projects-list.tsx +0 -126
  105. package/app/(playground)/error.tsx +0 -42
  106. package/app/(playground)/layout.tsx +0 -27
  107. package/app/(playground)/projects/[id]/playground/page.tsx +0 -57
  108. package/app/(playground)/projects/[id]/playground/view.tsx +0 -167
  109. package/app/(playground)/projects/[id]/playground-legacy/page.tsx +0 -47
  110. package/app/(playground)/projects/[id]/playground-legacy/skeleton.tsx +0 -63
  111. package/app/(playground)/projects/[id]/playground-legacy/view.tsx +0 -237
  112. package/app/favicon.ico +0 -0
  113. package/app/globals.css +0 -385
  114. package/app/icon.svg +0 -6
  115. package/app/layout.tsx +0 -39
  116. package/app/page.tsx +0 -11
  117. package/components/ai-elements/code-block.tsx +0 -562
  118. package/components/dashboard/agent-capabilities.tsx +0 -326
  119. package/components/dashboard/agent-identity-header.tsx +0 -50
  120. package/components/dashboard/agent-model-picker.tsx +0 -195
  121. package/components/dashboard/agent-model-selector.tsx +0 -121
  122. package/components/dashboard/agent-picker-card.tsx +0 -46
  123. package/components/dashboard/agent-studio.tsx +0 -242
  124. package/components/dashboard/agents-table.tsx +0 -48
  125. package/components/dashboard/breadcrumb.tsx +0 -70
  126. package/components/dashboard/builder-chat.tsx +0 -418
  127. package/components/dashboard/chat-shell.tsx +0 -40
  128. package/components/dashboard/client-picker.tsx +0 -63
  129. package/components/dashboard/command-snippet.tsx +0 -77
  130. package/components/dashboard/connect-dialog.tsx +0 -680
  131. package/components/dashboard/copy-button.tsx +0 -45
  132. package/components/dashboard/copy-card.tsx +0 -48
  133. package/components/dashboard/file-browser.tsx +0 -161
  134. package/components/dashboard/hint.tsx +0 -22
  135. package/components/dashboard/inference-mode.tsx +0 -15
  136. package/components/dashboard/manual-refresh-button.tsx +0 -52
  137. package/components/dashboard/markdown.tsx +0 -31
  138. package/components/dashboard/mcp-install-panel.tsx +0 -196
  139. package/components/dashboard/mission-graph.tsx +0 -262
  140. package/components/dashboard/nav-tabs.tsx +0 -86
  141. package/components/dashboard/polpo-chat.tsx +0 -468
  142. package/components/dashboard/project-copilot.tsx +0 -253
  143. package/components/dashboard/sdk-snippet-panel.tsx +0 -194
  144. package/components/dashboard/section-header.tsx +0 -37
  145. package/components/dashboard/settings-form.tsx +0 -2477
  146. package/components/dashboard/sidebar.tsx +0 -385
  147. package/components/dashboard/skeletons.tsx +0 -1054
  148. package/components/dashboard/skills-install-wizard.tsx +0 -294
  149. package/components/dashboard/swarm-runs.tsx +0 -316
  150. package/components/dashboard/tab-toggle.tsx +0 -35
  151. package/components/dashboard/task-studio.tsx +0 -224
  152. package/components/dashboard/top-header.tsx +0 -203
  153. package/components/dashboard/webhook-deliveries.tsx +0 -234
  154. package/components/icons/coding-agents.tsx +0 -151
  155. package/components/json-ld.tsx +0 -8
  156. package/components/providers.tsx +0 -25
  157. package/components/ui/badge.tsx +0 -52
  158. package/components/ui/button.tsx +0 -60
  159. package/components/ui/card.tsx +0 -103
  160. package/components/ui/chart.tsx +0 -356
  161. package/components/ui/command.tsx +0 -196
  162. package/components/ui/dialog.tsx +0 -157
  163. package/components/ui/input-group.tsx +0 -158
  164. package/components/ui/input.tsx +0 -20
  165. package/components/ui/multi-select.tsx +0 -161
  166. package/components/ui/popover.tsx +0 -90
  167. package/components/ui/select.tsx +0 -201
  168. package/components/ui/separator.tsx +0 -25
  169. package/components/ui/sheet.tsx +0 -135
  170. package/components/ui/skeleton.tsx +0 -13
  171. package/components/ui/tabs.tsx +0 -56
  172. package/components/ui/textarea.tsx +0 -18
  173. package/components/ui/tooltip.tsx +0 -66
  174. package/hooks/use-desktop-sidebar.tsx +0 -50
  175. package/hooks/use-mobile-sidebar.tsx +0 -37
  176. package/index.ts +0 -17
  177. package/lib/api.ts +0 -194
  178. package/lib/builder-context.ts +0 -60
  179. package/lib/data-client.ts +0 -68
  180. package/lib/get-query-client.ts +0 -25
  181. package/lib/polpo-client.tsx +0 -49
  182. package/lib/tool-catalog.ts +0 -234
  183. package/lib/use-event-catalog.ts +0 -28
  184. package/lib/utils.ts +0 -6
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useRef, useState } from "react";
4
+ import { ArrowUp, ChatCircleText, Plus, Stop } from "@phosphor-icons/react";
5
+ import ReactMarkdown from "react-markdown";
6
+ import { useAgents, useChat } from "@polpo-ai/react";
7
+ import { Button, IconButton, PageHeader } from "../components.js";
8
+ function messageText(content) {
9
+ if (typeof content === "string")
10
+ return content;
11
+ return content.map((part) => part.type === "text" ? part.text : `[${part.type}]`).join("\n");
12
+ }
13
+ export function PlaygroundView({ initialAgent }) {
14
+ const { agents, isLoading } = useAgents();
15
+ const [agent, setAgent] = useState(initialAgent ?? "");
16
+ useEffect(() => {
17
+ if (!agent && agents[0])
18
+ setAgent(agents[0].name);
19
+ }, [agent, agents]);
20
+ const chat = useChat({ agent: agent || undefined });
21
+ const bottomRef = useRef(null);
22
+ useEffect(() => bottomRef.current?.scrollIntoView({ behavior: "smooth" }), [chat.messages]);
23
+ const selected = useMemo(() => agents.find((item) => item.name === agent), [agents, agent]);
24
+ async function submit(event) {
25
+ event.preventDefault();
26
+ const form = event.currentTarget;
27
+ const input = form.elements.namedItem("message");
28
+ const value = input.value.trim();
29
+ if (!value || chat.isStreaming || !agent)
30
+ return;
31
+ input.value = "";
32
+ await chat.sendMessage(value);
33
+ }
34
+ return (_jsxs("div", { className: "pd-playground", children: [_jsx(PageHeader, { title: "Playground", description: "Call an agent through the same API your application uses.", actions: _jsxs(Button, { variant: "secondary", onClick: chat.newSession, children: [_jsx(Plus, { size: 15 }), "New chat"] }) }), _jsxs("div", { className: "pd-playground-toolbar", children: [_jsxs("label", { children: [_jsx("span", { children: "Agent" }), _jsx("select", { value: agent, disabled: isLoading, onChange: (event) => { setAgent(event.target.value); chat.newSession(); }, children: agents.map((item) => _jsx("option", { value: item.name, children: item.name }, item.name)) })] }), selected?.model ? _jsx("code", { children: selected.model }) : null] }), _jsxs("div", { className: "pd-chat-frame", children: [_jsxs("div", { className: "pd-messages", children: [chat.messages.length === 0 ? _jsxs("div", { className: "pd-chat-empty", children: [_jsx(ChatCircleText, { size: 30, weight: "duotone" }), _jsx("strong", { children: agent ? `Talk to ${agent}` : "Create an agent first" }), _jsx("span", { children: "Messages stream from your local Polpo runtime." })] }) : null, chat.messages.map((message) => _jsx(MessageBubble, { message: message }, message.id)), chat.error ? _jsx("div", { className: "pd-error", children: chat.error.message }) : null, _jsx("div", { ref: bottomRef })] }), _jsxs("form", { className: "pd-composer", onSubmit: (event) => void submit(event), children: [_jsx("textarea", { name: "message", rows: 2, placeholder: agent ? `Message ${agent}...` : "Create an agent first", disabled: !agent, onKeyDown: (event) => { if (event.key === "Enter" && !event.shiftKey) {
35
+ event.preventDefault();
36
+ event.currentTarget.form?.requestSubmit();
37
+ } } }), chat.isStreaming ? _jsx(IconButton, { label: "Stop response", type: "button", onClick: chat.abort, children: _jsx(Stop, { size: 15, weight: "fill" }) }) : _jsx(IconButton, { label: "Send message", type: "submit", disabled: !agent, children: _jsx(ArrowUp, { size: 16, weight: "bold" }) })] })] })] }));
38
+ }
39
+ function MessageBubble({ message }) {
40
+ const text = messageText(message.content);
41
+ return (_jsxs("article", { className: "pd-message", "data-role": message.role, children: [_jsx("div", { className: "pd-message-role", children: message.role === "assistant" ? "Agent" : "You" }), _jsx("div", { className: "pd-markdown", children: _jsx(ReactMarkdown, { children: text || (message.role === "assistant" ? "Thinking..." : "") }) }), message.segments?.filter((segment) => segment.type === "tool_call").map((segment) => segment.type === "tool_call" ? _jsxs("div", { className: "pd-tool-call", children: [_jsx("span", { children: segment.toolCall.name }), _jsx("code", { children: segment.toolCall.state })] }, segment.toolCall.id) : null)] }));
42
+ }
43
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","sourceRoot":"","sources":["../../src/views/playground.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function SessionDetailView({ sessionId }: {
2
+ sessionId: string;
3
+ }): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=session-detail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-detail.d.ts","sourceRoot":"","sources":["../../src/views/session-detail.tsx"],"names":[],"mappings":"AAYA,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,2CASrE"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import ReactMarkdown from "react-markdown";
5
+ import { ArrowLeft } from "@phosphor-icons/react";
6
+ import { useSessions } from "@polpo-ai/react";
7
+ import { Button, LoadingRows, PageHeader } from "../components.js";
8
+ import { useDashboardHost } from "../host.js";
9
+ function contentText(content) { return typeof content === "string" ? content : content.map((part) => part.type === "text" ? part.text : `[${part.type}]`).join("\n"); }
10
+ export function SessionDetailView({ sessionId }) {
11
+ const host = useDashboardHost();
12
+ const { sessions, getMessages } = useSessions();
13
+ const [messages, setMessages] = useState([]);
14
+ const [loading, setLoading] = useState(true);
15
+ const [error, setError] = useState(null);
16
+ const session = sessions.find((item) => item.id === sessionId);
17
+ useEffect(() => { let live = true; setLoading(true); getMessages(sessionId).then((data) => { if (live)
18
+ setMessages(data); }).catch((cause) => { if (live)
19
+ setError(cause instanceof Error ? cause.message : "Could not load session"); }).finally(() => { if (live)
20
+ setLoading(false); }); return () => { live = false; }; }, [getMessages, sessionId]);
21
+ return _jsxs("div", { className: "pd-view-stack", children: [_jsx(PageHeader, { title: session?.title || "Session", description: session?.agent || sessionId, actions: _jsxs(Button, { variant: "secondary", onClick: () => host.navigate("/sessions"), children: [_jsx(ArrowLeft, { size: 15 }), "Sessions"] }) }), error ? _jsx("div", { className: "pd-error", children: error }) : null, loading ? _jsx(LoadingRows, {}) : _jsx("div", { className: "pd-transcript", children: messages.map((message) => _jsxs("article", { "data-role": message.role, children: [_jsx("header", { children: message.role }), _jsx("div", { className: "pd-markdown", children: _jsx(ReactMarkdown, { children: contentText(message.content) }) })] }, message.id)) })] });
22
+ }
23
+ //# sourceMappingURL=session-detail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-detail.js","sourceRoot":"","sources":["../../src/views/session-detail.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function SessionsView(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/views/sessions.tsx"],"names":[],"mappings":"AASA,wBAAgB,YAAY,4CAS3B"}
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { ArrowClockwise, CaretRight, ChatCircleText } from "@phosphor-icons/react";
5
+ import { useSessions } from "@polpo-ai/react";
6
+ import { DataTable, IconButton, LoadingRows, PageHeader } from "../components.js";
7
+ export function SessionsView() {
8
+ const { sessions, isLoading, error, refetch } = useSessions();
9
+ const columns = useMemo(() => [
10
+ { id: "session", header: "Session", accessorFn: (item) => item.title || item.id, cell: ({ row }) => _jsxs("div", { className: "pd-primary-cell", children: [_jsx(ChatCircleText, { size: 17, weight: "duotone" }), _jsxs("div", { children: [_jsx("strong", { children: row.original.title || "Untitled session" }), _jsx("span", { children: row.original.agent || "Orchestrator" })] })] }), meta: { width: 380 } },
11
+ { id: "messages", header: "Messages", accessorFn: (item) => item.messageCount ?? 0, meta: { width: 110, align: "center", hideOnMobile: true } },
12
+ { id: "updated", header: "Updated", accessorFn: (item) => item.updatedAt, cell: ({ getValue }) => _jsx("span", { children: new Date(String(getValue())).toLocaleString() }), meta: { width: 210, hideOnMobile: true } },
13
+ { id: "open", header: "", enableSorting: false, cell: () => _jsx(CaretRight, { size: 14 }), meta: { width: 44, align: "right" } },
14
+ ], []);
15
+ return _jsxs("div", { className: "pd-view-stack", children: [_jsx(PageHeader, { title: "Sessions", description: `${sessions.length} recorded conversations` }), error ? _jsx("div", { className: "pd-error", children: error.message }) : null, isLoading && sessions.length === 0 ? _jsx(LoadingRows, {}) : _jsx(DataTable, { columns: columns, data: sessions, getRowId: (item) => item.id, rowHref: (item) => `/sessions/${encodeURIComponent(item.id)}`, searchPlaceholder: "Search sessions...", searchFn: (item, query) => [item.id, item.title, item.agent].some((value) => value?.toLowerCase().includes(query)), rightSlot: _jsx(IconButton, { label: "Refresh sessions", onClick: () => void refetch(), children: _jsx(ArrowClockwise, { size: 15 }) }) })] });
16
+ }
17
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/views/sessions.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function SkillsView(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/views/skills.tsx"],"names":[],"mappings":"AASA,wBAAgB,UAAU,4CAQzB"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { ArrowClockwise, GraduationCap } from "@phosphor-icons/react";
5
+ import { useSkills } from "@polpo-ai/react";
6
+ import { DataTable, IconButton, LoadingRows, PageHeader } from "../components.js";
7
+ export function SkillsView() {
8
+ const { skills, isLoading, error, refetch } = useSkills();
9
+ const columns = useMemo(() => [
10
+ { id: "skill", header: "Skill", accessorFn: (item) => item.name, cell: ({ row }) => _jsxs("div", { className: "pd-primary-cell", children: [_jsx(GraduationCap, { size: 17, weight: "duotone" }), _jsxs("div", { children: [_jsx("strong", { children: row.original.name }), _jsx("span", { children: row.original.description || "Reusable agent capability" })] })] }), meta: { width: 520 } },
11
+ { id: "source", header: "Source", accessorFn: (item) => item.source || "project", meta: { width: 160, hideOnMobile: true } },
12
+ { id: "agents", header: "Agents", accessorFn: (item) => item.assignedTo?.length ?? 0, meta: { width: 90, align: "center", hideOnMobile: true } },
13
+ ], []);
14
+ return _jsxs("div", { className: "pd-view-stack", children: [_jsx(PageHeader, { title: "Skills", description: `${skills.length} installed ${skills.length === 1 ? "skill" : "skills"}` }), error ? _jsx("div", { className: "pd-error", children: error.message }) : null, isLoading && skills.length === 0 ? _jsx(LoadingRows, {}) : _jsx(DataTable, { columns: columns, data: skills, getRowId: (item) => item.name, searchPlaceholder: "Search skills...", searchFn: (item, query) => [item.name, item.description, item.source].some((value) => value?.toLowerCase().includes(query)), rightSlot: _jsx(IconButton, { label: "Refresh skills", onClick: () => void refetch(), children: _jsx(ArrowClockwise, { size: 15 }) }) })] });
15
+ }
16
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/views/skills.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,96 +1,60 @@
1
1
  {
2
2
  "name": "@polpo-ai/dashboard",
3
- "version": "0.1.3",
4
- "publishConfig": {
5
- "access": "public"
3
+ "version": "0.15.8",
4
+ "description": "Polpo v2 runtime dashboard views for self-hosted and managed hosts",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./styles.css": "./src/styles.css"
6
14
  },
7
15
  "files": [
8
- "index.ts",
9
- "app",
10
- "components",
11
- "lib",
12
- "hooks",
13
- "README.md"
16
+ "dist",
17
+ "src/styles.css",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "sideEffects": [
22
+ "**/*.css"
14
23
  ],
15
- "exports": {
16
- ".": "./index.ts"
17
- },
18
24
  "dependencies": {
19
- "@base-ui/react": "^1.3.0",
20
- "@lobehub/icons": "^5.8.0",
21
- "@lumea-labs/canvas": "^0.1.2",
22
- "@lumea-labs/chat": "^0.1.5",
23
- "@lumea-labs/chat-canvas": "^0.1.1",
24
- "@lumea-labs/chat-polpo": "^0.1.2",
25
- "@lumea-labs/docs": "^0.1.3",
26
- "@lumea-labs/file-manager": "^0.1.1",
27
- "@lumea-labs/file-manager-polpo": "^0.1.3",
28
- "@lumea-labs/llm": "^0.1.3",
29
- "@lumea-labs/llm-polpo": "^0.1.1",
30
- "@lumea-labs/markdown": "^0.1.2",
31
- "@lumea-labs/orchestrator": "^0.1.1",
32
- "@lumea-labs/skills": "^0.1.1",
33
- "@lumea-labs/skills-polpo": "^0.1.1",
34
- "@lumea-labs/spreadsheet": "^0.1.3",
35
- "@lumea-labs/tool-calls": "^0.1.2",
36
- "@polpo-ai/chat": "^0.11.1",
37
- "@streamdown/code": "^1.1.1",
38
- "@tailwindcss/typography": "^0.5.19",
39
- "@tanstack/react-query": "^5.90.21",
40
- "@tiptap/extension-image": "^3.23.6",
41
- "@tiptap/extension-placeholder": "^3.23.6",
42
- "@tiptap/extension-table": "^3.23.6",
43
- "@tiptap/extension-table-cell": "^3.23.6",
44
- "@tiptap/extension-table-header": "^3.23.6",
45
- "@tiptap/extension-table-row": "^3.23.6",
46
- "@tiptap/markdown": "^3.23.6",
47
- "@tiptap/react": "^3.23.6",
48
- "@tiptap/starter-kit": "^3.23.6",
49
- "@xyflow/react": "^12.10.1",
50
- "@zwight/luckyexcel": "^1.1.6",
51
- "class-variance-authority": "^0.7.1",
52
- "clsx": "^2.1.1",
53
- "cmdk": "^1.1.1",
54
- "lucide-react": "^0.577.0",
55
- "motion": "^12.36.0",
56
- "next": "16.2.6",
57
- "next-intl": "^4.12.0",
58
- "next-themes": "^0.4.6",
59
- "node-html-markdown": "^2.0.0",
60
- "react": "19.2.6",
61
- "react-dom": "19.2.6",
25
+ "@phosphor-icons/react": "^2.1.10",
26
+ "@tanstack/react-table": "^8.21.3",
62
27
  "react-markdown": "^10.1.0",
63
- "react-virtuoso": "^4.12.0",
64
- "recharts": "^2.15.4",
65
- "shadcn": "^4.0.8",
66
- "shiki": "^4.0.2",
67
- "sonner": "^2.0.7",
68
- "streamdown": "^2.5.0",
69
- "sugar-high": "^1.1.0",
70
- "tailwind-merge": "^3.5.0",
71
- "tw-animate-css": "^1.4.0",
72
- "@polpo-ai/core": "0.7.18",
73
- "@polpo-ai/react": "0.7.18",
74
- "@polpo-ai/sdk": "0.7.18"
28
+ "@polpo-ai/react": "0.15.8",
29
+ "@polpo-ai/sdk": "0.15.8"
30
+ },
31
+ "peerDependencies": {
32
+ "react": "^18.0.0 || ^19.0.0",
33
+ "react-dom": "^18.0.0 || ^19.0.0"
75
34
  },
76
35
  "devDependencies": {
77
- "@playwright/test": "^1.58.2",
78
- "@tailwindcss/postcss": "^4",
79
- "@types/node": "^20",
80
- "@types/react": "^19",
81
- "@types/react-dom": "^19",
82
- "eslint": "^9",
83
- "eslint-config-next": "16.2.6",
84
- "tailwindcss": "^4",
85
- "typescript": "^5"
36
+ "@testing-library/jest-dom": "^6.9.1",
37
+ "@testing-library/react": "^16.3.2",
38
+ "@types/react": "^19.0.0",
39
+ "@types/react-dom": "^19.2.3",
40
+ "jsdom": "^29.0.1",
41
+ "react": "^19.0.0",
42
+ "react-dom": "^19.2.4",
43
+ "typescript": "^5.7.0",
44
+ "vitest": "^3.2.4"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "license": "Apache-2.0",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/lumea-labs/polpo.git",
53
+ "directory": "packages/dashboard"
86
54
  },
87
55
  "scripts": {
88
- "dev": "next dev --turbopack",
89
- "build": "next build",
90
- "start": "next start",
91
- "lint": "eslint",
92
- "test:e2e": "playwright test",
93
- "test:e2e:ui": "playwright test --ui",
94
- "test:e2e:headed": "playwright test --headed"
56
+ "build": "tsc",
57
+ "dev": "tsc --watch",
58
+ "test": "vitest run"
95
59
  }
96
60
  }
package/src/styles.css ADDED
@@ -0,0 +1,169 @@
1
+ :root {
2
+ --pd-bg: #f5f3ee;
3
+ --pd-surface: #fbfaf7;
4
+ --pd-panel: #efede7;
5
+ --pd-ink: #262520;
6
+ --pd-muted: #77736a;
7
+ --pd-border: #d9d5cc;
8
+ --pd-border-strong: #c7c1b5;
9
+ --pd-accent: #176b43;
10
+ --pd-accent-hover: #125737;
11
+ --pd-danger: #a33d35;
12
+ --pd-shadow: 0 12px 36px rgba(42, 38, 29, .1);
13
+ color-scheme: light;
14
+ }
15
+
16
+ * { box-sizing: border-box; }
17
+ body { margin: 0; background: var(--pd-bg); color: var(--pd-ink); font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; letter-spacing: 0; }
18
+ button, input, textarea, select { font: inherit; letter-spacing: 0; }
19
+ button { color: inherit; }
20
+ a { color: inherit; }
21
+ code, pre { font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; }
22
+
23
+ .pd-min-w-0 { min-width: 0; }
24
+ .pd-page-body { width: min(100%, 1240px); margin: 0 auto; padding: 34px 40px 64px; }
25
+ .pd-view-stack { display: flex; flex-direction: column; gap: 24px; min-width: 0; }
26
+ .pd-page-header { display: flex; min-height: 64px; align-items: flex-start; justify-content: space-between; gap: 24px; }
27
+ .pd-page-header h1 { margin: 0; font-size: 24px; line-height: 1.25; font-weight: 650; }
28
+ .pd-page-header p { margin: 7px 0 0; max-width: 720px; color: var(--pd-muted); font-size: 14px; line-height: 1.5; }
29
+ .pd-actions, .pd-form-actions, .pd-editor-footer > div { display: flex; align-items: center; gap: 8px; }
30
+ .pd-actions { flex: none; }
31
+
32
+ .pd-button, .pd-icon-button { display: inline-flex; align-items: center; justify-content: center; border: 1px solid transparent; border-radius: 6px; cursor: pointer; transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease; }
33
+ .pd-button { min-height: 36px; gap: 7px; padding: 0 13px; font-size: 13px; font-weight: 560; white-space: nowrap; }
34
+ .pd-button-primary { background: var(--pd-ink); color: #fff; }
35
+ .pd-button-primary:hover { background: #3b3932; }
36
+ .pd-button-secondary { border-color: var(--pd-border); background: var(--pd-surface); }
37
+ .pd-button-secondary:hover, .pd-button-ghost:hover { background: var(--pd-panel); }
38
+ .pd-button-ghost { background: transparent; }
39
+ .pd-button-danger { border-color: rgba(163, 61, 53, .25); background: #fff7f5; color: var(--pd-danger); }
40
+ .pd-button:disabled, .pd-icon-button:disabled { cursor: not-allowed; opacity: .48; }
41
+ .pd-icon-button { width: 34px; height: 34px; padding: 0; border-color: var(--pd-border); background: var(--pd-surface); }
42
+ .pd-icon-button:hover { background: var(--pd-panel); border-color: var(--pd-border-strong); }
43
+
44
+ .pd-table-stack { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
45
+ .pd-table-toolbar { display: flex; align-items: center; gap: 10px; min-height: 36px; }
46
+ .pd-table-toolbar-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
47
+ .pd-search { display: flex; width: min(320px, 100%); height: 34px; align-items: center; gap: 8px; padding: 0 10px; border: 1px solid var(--pd-border); border-radius: 6px; background: var(--pd-surface); color: var(--pd-muted); }
48
+ .pd-search:focus-within { border-color: var(--pd-border-strong); box-shadow: 0 0 0 3px rgba(38, 37, 32, .05); }
49
+ .pd-search input { min-width: 0; flex: 1; border: 0; outline: 0; background: transparent; color: var(--pd-ink); font-size: 13px; }
50
+ .pd-table-frame { overflow: hidden; border: 1px solid var(--pd-border); border-radius: 7px; background: var(--pd-surface); }
51
+ .pd-table-scroll { overflow-x: auto; }
52
+ .pd-table-frame table { width: 100%; min-width: 680px; border-collapse: collapse; table-layout: auto; }
53
+ .pd-table-frame th { height: 39px; padding: 0 14px; border-bottom: 1px solid var(--pd-border); background: var(--pd-panel); color: var(--pd-muted); font-size: 11px; font-weight: 620; text-align: left; text-transform: uppercase; }
54
+ .pd-table-frame th button { display: inline-flex; align-items: center; gap: 5px; width: 100%; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; text-transform: inherit; }
55
+ .pd-table-frame td { height: 58px; padding: 9px 14px; border-bottom: 1px solid var(--pd-border); font-size: 13px; vertical-align: middle; }
56
+ .pd-table-frame tbody tr:last-child td { border-bottom: 0; }
57
+ .pd-table-frame tbody tr[data-clickable="true"] { cursor: pointer; outline: none; }
58
+ .pd-table-frame tbody tr[data-clickable="true"]:hover td, .pd-table-frame tbody tr[data-clickable="true"]:focus td { background: #f3f1eb; }
59
+ .pd-table-frame [data-align="right"] { text-align: right; }
60
+ .pd-table-frame [data-align="center"] { text-align: center; }
61
+ .pd-table-frame th[data-align="right"] button { justify-content: flex-end; }
62
+ .pd-table-frame th[data-align="center"] button { justify-content: center; }
63
+ .pd-table-frame td code { display: inline-block; max-width: 280px; overflow: hidden; color: #5f5a50; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
64
+ .pd-primary-cell { display: flex; min-width: 0; align-items: center; gap: 10px; }
65
+ .pd-primary-cell > svg { flex: none; color: #686258; }
66
+ .pd-primary-cell > div { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 3px; }
67
+ .pd-primary-cell strong, .pd-primary-cell span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
68
+ .pd-primary-cell strong { font-size: 13px; font-weight: 610; }
69
+ .pd-primary-cell span { color: var(--pd-muted); font-size: 12px; }
70
+ .pd-file-name { display: flex; min-width: 0; align-items: center; gap: 9px; }
71
+ .pd-file-name svg { flex: none; color: #686258; }
72
+ .pd-file-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
73
+ .pd-empty-cell { height: 220px !important; text-align: center; }
74
+ .pd-pagination { display: flex; min-height: 46px; align-items: center; justify-content: space-between; padding: 6px 10px 6px 14px; border-top: 1px solid var(--pd-border); color: var(--pd-muted); font-size: 12px; }
75
+ .pd-pagination > div { display: flex; gap: 6px; }
76
+
77
+ .pd-empty { display: flex; min-height: 190px; align-items: center; justify-content: center; flex-direction: column; gap: 8px; color: var(--pd-muted); }
78
+ .pd-empty strong { color: var(--pd-ink); font-size: 14px; }
79
+ .pd-empty span { margin-bottom: 6px; font-size: 13px; }
80
+ .pd-error { padding: 11px 13px; border: 1px solid rgba(163, 61, 53, .22); border-radius: 6px; background: #fff6f4; color: var(--pd-danger); font-size: 13px; }
81
+ .pd-saved { color: var(--pd-accent); font-size: 12px; font-weight: 600; }
82
+ .pd-spin { animation: pd-spin 800ms linear infinite; }
83
+ @keyframes pd-spin { to { transform: rotate(360deg); } }
84
+
85
+ .pd-loading-rows { overflow: hidden; border: 1px solid var(--pd-border); border-radius: 7px; background: var(--pd-surface); }
86
+ .pd-loading-rows div { height: 58px; border-bottom: 1px solid var(--pd-border); background: linear-gradient(90deg, transparent, rgba(255,255,255,.82), transparent), var(--pd-panel); background-size: 240px 100%; animation: pd-shimmer 1.2s infinite linear; }
87
+ .pd-loading-rows div:last-child { border-bottom: 0; }
88
+ @keyframes pd-shimmer { from { background-position: -240px 0; } to { background-position: calc(100% + 240px) 0; } }
89
+
90
+ .pd-modal-backdrop { position: fixed; z-index: 100; inset: 0; display: grid; place-items: center; padding: 20px; background: rgba(35, 33, 28, .42); backdrop-filter: blur(3px); }
91
+ .pd-modal { width: min(640px, 100%); max-height: min(760px, calc(100vh - 40px)); overflow: auto; border: 1px solid var(--pd-border-strong); border-radius: 8px; background: var(--pd-surface); box-shadow: var(--pd-shadow); }
92
+ .pd-modal > header { position: sticky; z-index: 1; top: 0; display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; padding: 20px; border-bottom: 1px solid var(--pd-border); background: var(--pd-surface); }
93
+ .pd-modal h2 { margin: 0; font-size: 18px; line-height: 1.3; }
94
+ .pd-modal header p { margin: 6px 0 0; color: var(--pd-muted); font-size: 13px; line-height: 1.5; }
95
+ .pd-form { display: flex; flex-direction: column; gap: 18px; padding: 20px; }
96
+ .pd-field { display: flex; flex-direction: column; gap: 7px; }
97
+ .pd-field > span { font-size: 12px; font-weight: 620; }
98
+ .pd-field small { color: var(--pd-muted); font-size: 11px; line-height: 1.45; }
99
+ .pd-field input, .pd-field textarea, .pd-field select, .pd-memory-editor textarea, .pd-editor input, .pd-editor textarea, .pd-composer textarea, .pd-playground-toolbar select { width: 100%; border: 1px solid var(--pd-border); border-radius: 6px; outline: 0; background: #fff; color: var(--pd-ink); }
100
+ .pd-field input, .pd-editor input, .pd-playground-toolbar select { height: 38px; padding: 0 11px; }
101
+ .pd-field textarea, .pd-editor textarea { resize: vertical; padding: 10px 11px; line-height: 1.55; }
102
+ .pd-field input:focus, .pd-field textarea:focus, .pd-editor input:focus, .pd-editor textarea:focus, .pd-memory-editor textarea:focus, .pd-composer textarea:focus, .pd-playground-toolbar select:focus { border-color: var(--pd-border-strong); box-shadow: 0 0 0 3px rgba(38, 37, 32, .05); }
103
+ .pd-form-actions { justify-content: flex-end; padding-top: 2px; }
104
+
105
+ .pd-editor, .pd-memory-editor { overflow: hidden; border: 1px solid var(--pd-border); border-radius: 7px; background: var(--pd-surface); }
106
+ .pd-editor-section { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 22px; }
107
+ .pd-editor-section h2 { grid-column: 1 / -1; margin: 0 0 2px; font-size: 15px; }
108
+ .pd-editor-section .pd-field:last-child { grid-column: 1 / -1; }
109
+ .pd-editor-footer { display: flex; min-height: 58px; align-items: center; justify-content: space-between; gap: 16px; padding: 10px 14px; border-top: 1px solid var(--pd-border); background: var(--pd-panel); }
110
+ .pd-memory-editor textarea { display: block; min-height: min(62vh, 650px); resize: vertical; padding: 18px; border: 0; border-radius: 0; background: transparent; font-family: "SFMono-Regular", Consolas, monospace; font-size: 13px; line-height: 1.65; }
111
+ .pd-memory-editor footer { display: flex; min-height: 56px; align-items: center; justify-content: space-between; padding: 9px 12px 9px 16px; border-top: 1px solid var(--pd-border); background: var(--pd-panel); color: var(--pd-muted); font-size: 12px; }
112
+
113
+ .pd-breadcrumb { display: flex; min-height: 34px; align-items: center; gap: 6px; color: var(--pd-muted); font-size: 12px; }
114
+ .pd-breadcrumb span { display: inline-flex; align-items: center; gap: 6px; }
115
+ .pd-breadcrumb button { max-width: 220px; overflow: hidden; padding: 4px 6px; border: 0; border-radius: 4px; background: transparent; color: inherit; cursor: pointer; text-overflow: ellipsis; white-space: nowrap; }
116
+ .pd-breadcrumb button:hover { background: var(--pd-panel); color: var(--pd-ink); }
117
+
118
+ .pd-playground { display: flex; min-height: calc(100vh - 64px); flex-direction: column; gap: 18px; }
119
+ .pd-playground-toolbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
120
+ .pd-playground-toolbar label { display: flex; width: min(320px, 100%); flex-direction: column; gap: 6px; }
121
+ .pd-playground-toolbar label span { color: var(--pd-muted); font-size: 11px; font-weight: 620; text-transform: uppercase; }
122
+ .pd-playground-toolbar code { padding: 6px 8px; border: 1px solid var(--pd-border); border-radius: 5px; background: var(--pd-panel); color: var(--pd-muted); font-size: 11px; }
123
+ .pd-chat-frame { display: flex; min-height: 520px; flex: 1; flex-direction: column; overflow: hidden; border: 1px solid var(--pd-border); border-radius: 7px; background: var(--pd-surface); }
124
+ .pd-messages { display: flex; min-height: 0; flex: 1; flex-direction: column; gap: 26px; overflow-y: auto; padding: 28px max(24px, calc((100% - 760px) / 2)); }
125
+ .pd-chat-empty { display: flex; min-height: 360px; align-items: center; justify-content: center; flex-direction: column; gap: 8px; color: var(--pd-muted); text-align: center; }
126
+ .pd-chat-empty strong { color: var(--pd-ink); }
127
+ .pd-chat-empty span { font-size: 13px; }
128
+ .pd-message { max-width: 720px; }
129
+ .pd-message[data-role="user"] { align-self: flex-end; max-width: min(620px, 86%); padding: 11px 14px; border-radius: 7px 7px 2px 7px; background: var(--pd-panel); }
130
+ .pd-message-role { margin-bottom: 7px; color: var(--pd-muted); font-size: 10px; font-weight: 650; text-transform: uppercase; }
131
+ .pd-markdown { overflow-wrap: anywhere; font-size: 14px; line-height: 1.65; }
132
+ .pd-markdown > :first-child { margin-top: 0; }
133
+ .pd-markdown > :last-child { margin-bottom: 0; }
134
+ .pd-markdown pre { overflow-x: auto; padding: 13px; border: 1px solid var(--pd-border); border-radius: 6px; background: #292823; color: #f4f2eb; font-size: 12px; }
135
+ .pd-markdown code:not(pre code) { padding: 2px 4px; border-radius: 3px; background: var(--pd-panel); font-size: .9em; }
136
+ .pd-tool-call { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-top: 9px; padding: 8px 10px; border: 1px solid var(--pd-border); border-radius: 5px; color: var(--pd-muted); font-size: 11px; }
137
+ .pd-tool-call code { font-size: 10px; }
138
+ .pd-composer { display: flex; align-items: flex-end; gap: 8px; padding: 12px; border-top: 1px solid var(--pd-border); background: var(--pd-panel); }
139
+ .pd-composer textarea { min-height: 42px; max-height: 160px; resize: none; padding: 10px 11px; line-height: 1.45; }
140
+
141
+ .pd-transcript { display: flex; flex-direction: column; gap: 14px; }
142
+ .pd-transcript article { padding: 18px; border: 1px solid var(--pd-border); border-radius: 7px; background: var(--pd-surface); }
143
+ .pd-transcript article[data-role="user"] { margin-left: min(10%, 80px); background: var(--pd-panel); }
144
+ .pd-transcript article header { margin-bottom: 9px; color: var(--pd-muted); font-size: 10px; font-weight: 650; text-transform: uppercase; }
145
+
146
+ @media (max-width: 760px) {
147
+ .pd-page-body { padding: 24px 16px 48px; }
148
+ .pd-page-header { min-height: auto; flex-direction: column; gap: 14px; }
149
+ .pd-actions { width: 100%; flex-wrap: wrap; }
150
+ .pd-table-toolbar { align-items: stretch; flex-wrap: wrap; }
151
+ .pd-search { width: 100%; }
152
+ .pd-table-toolbar-right { margin-left: auto; }
153
+ .pd-table-frame table { min-width: 0; table-layout: fixed; }
154
+ .pd-table-frame [data-mobile-hidden="true"] { display: none; }
155
+ .pd-table-frame th, .pd-table-frame td { padding-right: 12px; padding-left: 12px; }
156
+ .pd-editor-section { grid-template-columns: 1fr; padding: 16px; }
157
+ .pd-editor-section .pd-field:last-child { grid-column: auto; }
158
+ .pd-editor-footer { align-items: stretch; flex-direction: column-reverse; }
159
+ .pd-editor-footer > div { justify-content: flex-end; }
160
+ .pd-playground { min-height: calc(100vh - 56px); }
161
+ .pd-playground-toolbar { align-items: stretch; flex-direction: column; }
162
+ .pd-playground-toolbar label { width: 100%; }
163
+ .pd-messages { padding: 20px 14px; }
164
+ .pd-message[data-role="user"] { max-width: 92%; }
165
+ }
166
+
167
+ @media (prefers-reduced-motion: reduce) {
168
+ *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
169
+ }
@@ -1,47 +0,0 @@
1
- "use client";
2
-
3
- /**
4
- * Error boundary for the dashboard group. A transient backend failure
5
- * (control-plane 5xx / network / DB unreachable) now surfaces here instead
6
- * of being swallowed into "no orgs → /onboarding". Auth failures (401) are
7
- * handled upstream by `getOrgs` (redirect to /login).
8
- */
9
- export default function DashboardError({
10
- error,
11
- reset,
12
- }: {
13
- error: Error & { digest?: string };
14
- reset: () => void;
15
- }) {
16
- return (
17
- <div className="flex min-h-[60vh] items-center justify-center p-6">
18
- <div className="w-full max-w-md border border-border bg-card p-8 text-center">
19
- <h2 className="text-base font-semibold text-foreground">Something went wrong</h2>
20
- <p className="mt-2 text-sm text-muted-foreground">
21
- We couldn&apos;t reach the control plane. This is usually temporary —
22
- give it a moment and retry.
23
- </p>
24
- {error?.digest ? (
25
- <p className="mt-3 font-mono text-[11px] text-muted-foreground/50">
26
- ref: {error.digest}
27
- </p>
28
- ) : null}
29
- <div className="mt-6 flex items-center justify-center gap-3">
30
- <button
31
- type="button"
32
- onClick={() => reset()}
33
- className="border border-foreground bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90"
34
- >
35
- Try again
36
- </button>
37
- <a
38
- href="/login"
39
- className="border border-border px-4 py-2 text-sm font-medium text-foreground transition-colors hover:border-foreground/40"
40
- >
41
- Sign in
42
- </a>
43
- </div>
44
- </div>
45
- </div>
46
- );
47
- }
@@ -1,41 +0,0 @@
1
- import { Sidebar, MobileSidebar, MobileHeader } from "../../components/dashboard/sidebar";
2
- import { TopHeader } from "../../components/dashboard/top-header";
3
- import { Providers } from "../../components/providers";
4
- import { MobileSidebarProvider } from "../../hooks/use-mobile-sidebar";
5
- import { DesktopSidebarProvider } from "../../hooks/use-desktop-sidebar";
6
- import { CopilotLayout } from "../../components/dashboard/project-copilot";
7
-
8
- /**
9
- * Single-tenant self-host shell. No Better Auth session, no org list, no
10
- * onboarding gate — those live only in the cloud build. One local instance,
11
- * straight into the dashboard chrome.
12
- */
13
- export default function DashboardLayout({
14
- children,
15
- }: {
16
- children: React.ReactNode;
17
- }) {
18
- return (
19
- <Providers>
20
- <MobileSidebarProvider>
21
- <DesktopSidebarProvider>
22
- <div className="flex h-screen flex-col overflow-hidden">
23
- <div className="hidden md:block">
24
- <TopHeader />
25
- </div>
26
-
27
- <div className="flex flex-1 overflow-hidden">
28
- <Sidebar />
29
- <MobileSidebar />
30
-
31
- <div className="flex flex-1 flex-col overflow-hidden">
32
- <MobileHeader />
33
- <CopilotLayout>{children}</CopilotLayout>
34
- </div>
35
- </div>
36
- </div>
37
- </DesktopSidebarProvider>
38
- </MobileSidebarProvider>
39
- </Providers>
40
- );
41
- }
@@ -1,30 +0,0 @@
1
- export default function DashboardLoading() {
2
- return (
3
- <div className="px-4 py-6 md:px-8 md:py-8">
4
- <div className="space-y-4">
5
- {/* Header skeleton */}
6
- <div className="h-8 w-48 animate-pulse rounded bg-muted" />
7
- <div className="h-4 w-80 animate-pulse rounded bg-muted/60" />
8
-
9
- {/* Content skeleton */}
10
- <div className="mt-8 grid gap-4 md:grid-cols-2 lg:grid-cols-4">
11
- {Array.from({ length: 4 }).map((_, i) => (
12
- <div
13
- key={i}
14
- className="h-24 animate-pulse rounded-lg border border-border bg-card"
15
- />
16
- ))}
17
- </div>
18
-
19
- <div className="mt-8 space-y-3">
20
- {Array.from({ length: 5 }).map((_, i) => (
21
- <div
22
- key={i}
23
- className="h-12 animate-pulse rounded border border-border bg-card"
24
- />
25
- ))}
26
- </div>
27
- </div>
28
- </div>
29
- );
30
- }