+
+
+ {series.length > 1 ? (
+
+ {series.map((s) => (
+
+
+ {s.label}
+
+ ))}
+
+ ) : null}
+
+
+
+
+ {weeks.map((week, i) => (
+
+ {series.map((s) => {
+ const value = s.values[i] ?? 0;
+ const height = value > 0 ? Math.max(4, (value / max) * 100) : 2;
+ return (
+
0 ? s.color : "#EBEEF4",
+ }}
+ />
+ );
+ })}
+
+ ))}
+
+ {!hasData ? (
+
+ No usage events yet
+
+ ) : null}
+
+
+
+ {weeks.length > 0 ? formatWeekLabel(weeks[0].weekStart) : ""}
+ {weeks.length > 0 ? formatWeekLabel(weeks[weeks.length - 1].weekStart) : ""}
+
+
+ );
+}
+
+/* ── Main screen ── */
+
+export function AnalyticsScreen() {
+ const { activeOrg, orgContext } = useOrgDashboard();
+
+ const { data, isLoading } = useQuery({
+ queryKey: ["telemetry", "analytics"],
+ queryFn: fetchAnalytics,
+ });
+
+ const weekly = data?.weekly ?? [];
+ const tasks7d = (data?.tasksCompleted7d ?? 0) + (data?.tasksFailed7d ?? 0);
+ const seats = orgContext?.members.length ?? data?.members ?? 0;
+ const locked = Boolean(orgContext) && seats < ANALYTICS_MIN_SEATS;
+
+ return (
+
+
+ {/* Breadcrumb */}
+
+ {activeOrg?.name ?? "OpenWork Cloud"}
+
+ Analytics
+
+
+ {/* Header */}
+
+
Usage & adoption
+
+ Included with {ANALYTICS_MIN_SEATS}+ seats
+
+
+
+ See how your team is adopting OpenWork — active members, sessions, and task activity over time.
+ Only event metadata is collected — never prompts, code, or file contents.
+
+
+ {locked ? (
+
+
+
+
+
+
+ Analytics is available for workspaces with {ANALYTICS_MIN_SEATS} or more seats
+
+
+
+ Your workspace currently has {seats} {seats === 1 ? "seat" : "seats"}. Add seats to unlock
+ adoption and usage insights — active members, session frequency, and task activity across your whole team.
+
+
+
+ Invite members
+
+
+ Manage seats & billing
+
+
+
+ ) : (
+ <>
+ {/* Summary cards */}
+
+ }
+ title="OpenWork users"
+ value={isLoading ? "…" : `${data?.members ?? 0}`}
+ sub={`${data?.pendingInvites ?? 0} pending invites`}
+ tone="violet"
+ />
+ }
+ title="Active this week"
+ value={isLoading ? "…" : `${data?.activeMembers7d ?? 0}`}
+ sub={`${data?.activeMembers30d ?? 0} active in last 30 days`}
+ tone="blue"
+ />
+ }
+ title="Sessions this week"
+ value={isLoading ? "…" : `${data?.sessions7d ?? 0}`}
+ sub={`${data?.sessions30d ?? 0} in last 30 days`}
+ tone="amber"
+ />
+ }
+ title="Tasks this week"
+ value={isLoading ? "…" : `${tasks7d}`}
+ sub={`${successRate(data?.tasksCompleted7d ?? 0, data?.tasksFailed7d ?? 0)} success rate`}
+ tone="green"
+ />
+
+
+ {/* Trend charts */}
+
+ w.activeMembers) }]}
+ />
+ w.sessions) }]}
+ />
+
+
+
+ w.tasksCompleted) },
+ { label: "Failed", color: "#E5484D", values: weekly.map((w) => w.tasksFailed) },
+ ]}
+ />
+
+
+ {/* 30-day detail */}
+
+ }
+ title="Avg task duration"
+ value={isLoading ? "…" : formatDuration(data?.avgTaskDurationMs30d ?? null)}
+ sub="Completed tasks, last 30 days"
+ tone="blue"
+ />
+ }
+ title="Tasks completed"
+ value={isLoading ? "…" : `${data?.tasksCompleted30d ?? 0}`}
+ sub="Last 30 days"
+ tone="green"
+ />
+ }
+ title="Tasks failed"
+ value={isLoading ? "…" : `${data?.tasksFailed30d ?? 0}`}
+ sub={`${successRate(data?.tasksCompleted30d ?? 0, data?.tasksFailed30d ?? 0)} success rate over 30 days`}
+ tone="amber"
+ />
+
+
+ {/* Privacy note */}
+
+ Telemetry never includes prompt contents, code, file contents, diffs, secrets, or terminal output.
+ Usage data appears here once members sign in to the OpenWork app and start running tasks.
+
+ >
+ )}
+
+ );
+}
diff --git a/ee/apps/den-web/app/(den)/dashboard/_components/org-dashboard-shell.tsx b/ee/apps/den-web/app/(den)/dashboard/_components/org-dashboard-shell.tsx
index 24eb8d8f5..2c9b12f14 100644
--- a/ee/apps/den-web/app/(den)/dashboard/_components/org-dashboard-shell.tsx
+++ b/ee/apps/den-web/app/(den)/dashboard/_components/org-dashboard-shell.tsx
@@ -4,6 +4,7 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { useMemo, useState } from "react";
import {
+ BarChart3,
BookOpen,
Bot,
Cable,
@@ -27,6 +28,7 @@ import {
import { useDenFlow } from "../../_providers/den-flow-provider";
import {
formatRoleLabel,
+ getAnalyticsRoute,
getBackgroundAgentsRoute,
getApiKeysRoute,
getBillingRoute,
@@ -109,6 +111,9 @@ function getDashboardPageTitle(pathname: string, orgSlug: string | null) {
if (pathname === dashboardRoot) {
return "Home";
}
+ if (pathname.startsWith(getAnalyticsRoute(orgSlug))) {
+ return "Analytics";
+ }
if (pathname.startsWith(getMembersRoute(orgSlug))) {
return "Members";
}
@@ -187,6 +192,12 @@ export function OrgDashboardShell({ children }: { children: React.ReactNode }) {
},
...(access.isAdmin
? [
+ {
+ href: activeOrg ? getAnalyticsRoute(activeOrg.slug) : "#",
+ label: "Analytics",
+ icon: BarChart3,
+ badge: "New",
+ },
// NOTE: Shared Workspace soft-disabled — uncomment to re-enable
// {
// href: activeOrg ? getBackgroundAgentsRoute(activeOrg.slug) : "#",