context-mode 1.0.80 → 1.0.82

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 (43) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.openclaw-plugin/openclaw.plugin.json +1 -1
  4. package/.openclaw-plugin/package.json +1 -1
  5. package/build/cli.js +57 -0
  6. package/build/server.js +94 -1
  7. package/cli.bundle.mjs +106 -99
  8. package/insight/components.json +25 -0
  9. package/insight/index.html +13 -0
  10. package/insight/package.json +54 -0
  11. package/insight/server.mjs +624 -0
  12. package/insight/src/components/analytics.tsx +112 -0
  13. package/insight/src/components/ui/badge.tsx +52 -0
  14. package/insight/src/components/ui/button.tsx +58 -0
  15. package/insight/src/components/ui/card.tsx +103 -0
  16. package/insight/src/components/ui/chart.tsx +371 -0
  17. package/insight/src/components/ui/collapsible.tsx +19 -0
  18. package/insight/src/components/ui/input.tsx +20 -0
  19. package/insight/src/components/ui/progress.tsx +83 -0
  20. package/insight/src/components/ui/scroll-area.tsx +55 -0
  21. package/insight/src/components/ui/separator.tsx +23 -0
  22. package/insight/src/components/ui/table.tsx +114 -0
  23. package/insight/src/components/ui/tabs.tsx +82 -0
  24. package/insight/src/components/ui/tooltip.tsx +64 -0
  25. package/insight/src/lib/api.ts +71 -0
  26. package/insight/src/lib/utils.ts +6 -0
  27. package/insight/src/main.tsx +22 -0
  28. package/insight/src/routeTree.gen.ts +189 -0
  29. package/insight/src/router.tsx +19 -0
  30. package/insight/src/routes/__root.tsx +55 -0
  31. package/insight/src/routes/enterprise.tsx +316 -0
  32. package/insight/src/routes/index.tsx +914 -0
  33. package/insight/src/routes/knowledge.tsx +221 -0
  34. package/insight/src/routes/knowledge_.$dbHash.$sourceId.tsx +137 -0
  35. package/insight/src/routes/search.tsx +97 -0
  36. package/insight/src/routes/sessions.tsx +179 -0
  37. package/insight/src/routes/sessions_.$dbHash.$sessionId.tsx +181 -0
  38. package/insight/src/styles.css +104 -0
  39. package/insight/tsconfig.json +29 -0
  40. package/insight/vite.config.ts +19 -0
  41. package/openclaw.plugin.json +1 -1
  42. package/package.json +2 -1
  43. package/server.bundle.mjs +76 -72
@@ -0,0 +1,189 @@
1
+ /* eslint-disable */
2
+
3
+ // @ts-nocheck
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+
7
+ // This file was automatically generated by TanStack Router.
8
+ // You should NOT make any changes in this file as it will be overwritten.
9
+ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
10
+
11
+ import { Route as rootRouteImport } from './routes/__root'
12
+ import { Route as SessionsRouteImport } from './routes/sessions'
13
+ import { Route as SearchRouteImport } from './routes/search'
14
+ import { Route as KnowledgeRouteImport } from './routes/knowledge'
15
+ import { Route as EnterpriseRouteImport } from './routes/enterprise'
16
+ import { Route as IndexRouteImport } from './routes/index'
17
+ import { Route as SessionsDbHashSessionIdRouteImport } from './routes/sessions_.$dbHash.$sessionId'
18
+ import { Route as KnowledgeDbHashSourceIdRouteImport } from './routes/knowledge_.$dbHash.$sourceId'
19
+
20
+ const SessionsRoute = SessionsRouteImport.update({
21
+ id: '/sessions',
22
+ path: '/sessions',
23
+ getParentRoute: () => rootRouteImport,
24
+ } as any)
25
+ const SearchRoute = SearchRouteImport.update({
26
+ id: '/search',
27
+ path: '/search',
28
+ getParentRoute: () => rootRouteImport,
29
+ } as any)
30
+ const KnowledgeRoute = KnowledgeRouteImport.update({
31
+ id: '/knowledge',
32
+ path: '/knowledge',
33
+ getParentRoute: () => rootRouteImport,
34
+ } as any)
35
+ const EnterpriseRoute = EnterpriseRouteImport.update({
36
+ id: '/enterprise',
37
+ path: '/enterprise',
38
+ getParentRoute: () => rootRouteImport,
39
+ } as any)
40
+ const IndexRoute = IndexRouteImport.update({
41
+ id: '/',
42
+ path: '/',
43
+ getParentRoute: () => rootRouteImport,
44
+ } as any)
45
+ const SessionsDbHashSessionIdRoute = SessionsDbHashSessionIdRouteImport.update({
46
+ id: '/sessions_/$dbHash/$sessionId',
47
+ path: '/sessions/$dbHash/$sessionId',
48
+ getParentRoute: () => rootRouteImport,
49
+ } as any)
50
+ const KnowledgeDbHashSourceIdRoute = KnowledgeDbHashSourceIdRouteImport.update({
51
+ id: '/knowledge_/$dbHash/$sourceId',
52
+ path: '/knowledge/$dbHash/$sourceId',
53
+ getParentRoute: () => rootRouteImport,
54
+ } as any)
55
+
56
+ export interface FileRoutesByFullPath {
57
+ '/': typeof IndexRoute
58
+ '/enterprise': typeof EnterpriseRoute
59
+ '/knowledge': typeof KnowledgeRoute
60
+ '/search': typeof SearchRoute
61
+ '/sessions': typeof SessionsRoute
62
+ '/knowledge/$dbHash/$sourceId': typeof KnowledgeDbHashSourceIdRoute
63
+ '/sessions/$dbHash/$sessionId': typeof SessionsDbHashSessionIdRoute
64
+ }
65
+ export interface FileRoutesByTo {
66
+ '/': typeof IndexRoute
67
+ '/enterprise': typeof EnterpriseRoute
68
+ '/knowledge': typeof KnowledgeRoute
69
+ '/search': typeof SearchRoute
70
+ '/sessions': typeof SessionsRoute
71
+ '/knowledge/$dbHash/$sourceId': typeof KnowledgeDbHashSourceIdRoute
72
+ '/sessions/$dbHash/$sessionId': typeof SessionsDbHashSessionIdRoute
73
+ }
74
+ export interface FileRoutesById {
75
+ __root__: typeof rootRouteImport
76
+ '/': typeof IndexRoute
77
+ '/enterprise': typeof EnterpriseRoute
78
+ '/knowledge': typeof KnowledgeRoute
79
+ '/search': typeof SearchRoute
80
+ '/sessions': typeof SessionsRoute
81
+ '/knowledge_/$dbHash/$sourceId': typeof KnowledgeDbHashSourceIdRoute
82
+ '/sessions_/$dbHash/$sessionId': typeof SessionsDbHashSessionIdRoute
83
+ }
84
+ export interface FileRouteTypes {
85
+ fileRoutesByFullPath: FileRoutesByFullPath
86
+ fullPaths:
87
+ | '/'
88
+ | '/enterprise'
89
+ | '/knowledge'
90
+ | '/search'
91
+ | '/sessions'
92
+ | '/knowledge/$dbHash/$sourceId'
93
+ | '/sessions/$dbHash/$sessionId'
94
+ fileRoutesByTo: FileRoutesByTo
95
+ to:
96
+ | '/'
97
+ | '/enterprise'
98
+ | '/knowledge'
99
+ | '/search'
100
+ | '/sessions'
101
+ | '/knowledge/$dbHash/$sourceId'
102
+ | '/sessions/$dbHash/$sessionId'
103
+ id:
104
+ | '__root__'
105
+ | '/'
106
+ | '/enterprise'
107
+ | '/knowledge'
108
+ | '/search'
109
+ | '/sessions'
110
+ | '/knowledge_/$dbHash/$sourceId'
111
+ | '/sessions_/$dbHash/$sessionId'
112
+ fileRoutesById: FileRoutesById
113
+ }
114
+ export interface RootRouteChildren {
115
+ IndexRoute: typeof IndexRoute
116
+ EnterpriseRoute: typeof EnterpriseRoute
117
+ KnowledgeRoute: typeof KnowledgeRoute
118
+ SearchRoute: typeof SearchRoute
119
+ SessionsRoute: typeof SessionsRoute
120
+ KnowledgeDbHashSourceIdRoute: typeof KnowledgeDbHashSourceIdRoute
121
+ SessionsDbHashSessionIdRoute: typeof SessionsDbHashSessionIdRoute
122
+ }
123
+
124
+ declare module '@tanstack/react-router' {
125
+ interface FileRoutesByPath {
126
+ '/sessions': {
127
+ id: '/sessions'
128
+ path: '/sessions'
129
+ fullPath: '/sessions'
130
+ preLoaderRoute: typeof SessionsRouteImport
131
+ parentRoute: typeof rootRouteImport
132
+ }
133
+ '/search': {
134
+ id: '/search'
135
+ path: '/search'
136
+ fullPath: '/search'
137
+ preLoaderRoute: typeof SearchRouteImport
138
+ parentRoute: typeof rootRouteImport
139
+ }
140
+ '/knowledge': {
141
+ id: '/knowledge'
142
+ path: '/knowledge'
143
+ fullPath: '/knowledge'
144
+ preLoaderRoute: typeof KnowledgeRouteImport
145
+ parentRoute: typeof rootRouteImport
146
+ }
147
+ '/enterprise': {
148
+ id: '/enterprise'
149
+ path: '/enterprise'
150
+ fullPath: '/enterprise'
151
+ preLoaderRoute: typeof EnterpriseRouteImport
152
+ parentRoute: typeof rootRouteImport
153
+ }
154
+ '/': {
155
+ id: '/'
156
+ path: '/'
157
+ fullPath: '/'
158
+ preLoaderRoute: typeof IndexRouteImport
159
+ parentRoute: typeof rootRouteImport
160
+ }
161
+ '/sessions_/$dbHash/$sessionId': {
162
+ id: '/sessions_/$dbHash/$sessionId'
163
+ path: '/sessions/$dbHash/$sessionId'
164
+ fullPath: '/sessions/$dbHash/$sessionId'
165
+ preLoaderRoute: typeof SessionsDbHashSessionIdRouteImport
166
+ parentRoute: typeof rootRouteImport
167
+ }
168
+ '/knowledge_/$dbHash/$sourceId': {
169
+ id: '/knowledge_/$dbHash/$sourceId'
170
+ path: '/knowledge/$dbHash/$sourceId'
171
+ fullPath: '/knowledge/$dbHash/$sourceId'
172
+ preLoaderRoute: typeof KnowledgeDbHashSourceIdRouteImport
173
+ parentRoute: typeof rootRouteImport
174
+ }
175
+ }
176
+ }
177
+
178
+ const rootRouteChildren: RootRouteChildren = {
179
+ IndexRoute: IndexRoute,
180
+ EnterpriseRoute: EnterpriseRoute,
181
+ KnowledgeRoute: KnowledgeRoute,
182
+ SearchRoute: SearchRoute,
183
+ SessionsRoute: SessionsRoute,
184
+ KnowledgeDbHashSourceIdRoute: KnowledgeDbHashSourceIdRoute,
185
+ SessionsDbHashSessionIdRoute: SessionsDbHashSessionIdRoute,
186
+ }
187
+ export const routeTree = rootRouteImport
188
+ ._addFileChildren(rootRouteChildren)
189
+ ._addFileTypes<FileRouteTypes>()
@@ -0,0 +1,19 @@
1
+ import { createRouter as createTanStackRouter } from '@tanstack/react-router'
2
+ import { routeTree } from './routeTree.gen'
3
+
4
+ export function getRouter() {
5
+ const router = createTanStackRouter({
6
+ routeTree,
7
+ scrollRestoration: true,
8
+ defaultPreload: 'intent',
9
+ defaultPreloadStaleTime: 0,
10
+ })
11
+
12
+ return router
13
+ }
14
+
15
+ declare module '@tanstack/react-router' {
16
+ interface Register {
17
+ router: ReturnType<typeof getRouter>
18
+ }
19
+ }
@@ -0,0 +1,55 @@
1
+ import { Link, Outlet, createRootRoute } from "@tanstack/react-router";
2
+ import { Database, Brain, History, Search, Building2 } from "lucide-react";
3
+
4
+ import "../styles.css";
5
+
6
+ const NAV = [
7
+ { to: "/", label: "Dashboard", icon: Database },
8
+ { to: "/knowledge", label: "Knowledge Base", icon: Brain },
9
+ { to: "/sessions", label: "Sessions", icon: History },
10
+ { to: "/search", label: "Search", icon: Search },
11
+ { to: "/enterprise", label: "Enterprise", icon: Building2 },
12
+ ] as const;
13
+
14
+ export const Route = createRootRoute({
15
+ component: RootLayout,
16
+ });
17
+
18
+ function RootLayout() {
19
+ return (
20
+ <div className="dark flex min-h-screen bg-background text-foreground">
21
+ <aside className="w-56 border-r border-border bg-card fixed h-screen flex flex-col">
22
+ <div className="p-4 border-b border-border">
23
+ <h1 className="text-sm font-semibold text-foreground tracking-wider uppercase">
24
+ Context Mode
25
+ </h1>
26
+ <p className="text-xs text-muted-foreground/60 mt-0.5">
27
+ Insight
28
+ </p>
29
+ </div>
30
+ <nav className="flex-1 py-2">
31
+ {NAV.map(({ to, label, icon: Icon }) => (
32
+ <Link
33
+ key={to}
34
+ to={to}
35
+ activeOptions={{ exact: to === "/" }}
36
+ className="flex items-center gap-3 px-4 py-2.5 text-sm transition-colors border-l-2 border-transparent text-muted-foreground hover:text-foreground hover:bg-accent/50 [&.active]:border-primary [&.active]:text-primary [&.active]:bg-accent [&.active]:font-medium"
37
+ >
38
+ <Icon className="h-4 w-4" />
39
+ {label}
40
+ </Link>
41
+ ))}
42
+ </nav>
43
+ <div className="p-4 border-t border-border">
44
+ <p className="text-[10px] text-muted-foreground/50">
45
+ Local · Read-only
46
+ </p>
47
+ </div>
48
+ </aside>
49
+
50
+ <main className="ml-56 flex-1 p-8 max-w-6xl">
51
+ <Outlet />
52
+ </main>
53
+ </div>
54
+ );
55
+ }
@@ -0,0 +1,316 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
3
+ import { Badge } from "@/components/ui/badge";
4
+ import { Separator } from "@/components/ui/separator";
5
+ import {
6
+ Building2, Sparkles, DollarSign, TestTube2, GraduationCap, ArrowRight,
7
+ Mail, Cloud, ShieldCheck, GitPullRequest, Monitor, Users, Shield, Code,
8
+ } from "lucide-react";
9
+
10
+ export const Route = createFileRoute("/enterprise")({ component: EnterprisePage });
11
+
12
+ // ── Enterprise Persona Data ──
13
+ const PERSONAS = [
14
+ {
15
+ name: "CTO / VP Engineering",
16
+ icon: Building2,
17
+ metrics: 6,
18
+ blocked: 2,
19
+ color: "border-blue-500/30",
20
+ bg: "bg-blue-500/5",
21
+ badge: "bg-blue-500/15 text-blue-400",
22
+ insights: [
23
+ "57 idle licenses = $27K/yr waste",
24
+ "AI adoption at 68% — 32% of seats unused",
25
+ ],
26
+ roi: "$27K/yr license savings",
27
+ },
28
+ {
29
+ name: "Engineering Manager",
30
+ icon: Users,
31
+ metrics: 7,
32
+ color: "border-purple-500/30",
33
+ bg: "bg-purple-500/5",
34
+ badge: "bg-purple-500/15 text-purple-400",
35
+ insights: [
36
+ "Dev A takes 3.2hr to first commit vs team avg 1.8hr",
37
+ "Team rework rate 47 edits/file — specs unclear",
38
+ ],
39
+ roi: "2.6x sprint velocity improvement",
40
+ },
41
+ {
42
+ name: "DevEx Lead",
43
+ icon: Sparkles,
44
+ metrics: 7,
45
+ color: "border-cyan-500/30",
46
+ bg: "bg-cyan-500/5",
47
+ badge: "bg-cyan-500/15 text-cyan-400",
48
+ insights: [
49
+ "42% of devs quit the tool after 3 days",
50
+ "New hire ramp: 6 weeks to 2 weeks with context-mode",
51
+ ],
52
+ roi: "6wk to 2wk onboarding",
53
+ },
54
+ {
55
+ name: "Security / CISO",
56
+ icon: Shield,
57
+ metrics: 5,
58
+ color: "border-red-500/30",
59
+ bg: "bg-red-500/5",
60
+ badge: "bg-red-500/15 text-red-400",
61
+ insights: [
62
+ "AWS key appeared in tool output for 7 minutes",
63
+ "12 dangerous command attempts blocked this week",
64
+ ],
65
+ roi: "Full SOC2 AI audit trail",
66
+ },
67
+ {
68
+ name: "FinOps",
69
+ icon: DollarSign,
70
+ metrics: 1,
71
+ blocked: 4,
72
+ muted: true,
73
+ color: "border-zinc-500/20",
74
+ bg: "bg-zinc-500/5",
75
+ badge: "bg-zinc-500/15 text-zinc-500",
76
+ insights: [
77
+ "Cost data requires platform changes — 4 metrics blocked",
78
+ ],
79
+ roi: "15-30% cost optimization (when unblocked)",
80
+ comingSoon: true,
81
+ },
82
+ {
83
+ name: "QA Lead",
84
+ icon: TestTube2,
85
+ metrics: 5,
86
+ color: "border-amber-500/30",
87
+ bg: "bg-amber-500/5",
88
+ badge: "bg-amber-500/15 text-amber-400",
89
+ insights: [
90
+ "Only 28% of sessions run tests",
91
+ "35% first-pass test rate — quality crisis signal",
92
+ ],
93
+ roi: "Targeted tech debt sprints",
94
+ },
95
+ {
96
+ name: "Developer",
97
+ icon: Code,
98
+ metrics: 5,
99
+ color: "border-emerald-500/30",
100
+ bg: "bg-emerald-500/5",
101
+ badge: "bg-emerald-500/15 text-emerald-400",
102
+ insights: [
103
+ "Error rate dropped 60% after updating CLAUDE.md",
104
+ "Tool mastery curve: 34% to 11% errors in 8 weeks",
105
+ ],
106
+ roi: "Personal mastery curve",
107
+ note: "Already in Personal tab",
108
+ },
109
+ {
110
+ name: "Onboarding",
111
+ icon: GraduationCap,
112
+ metrics: 5,
113
+ color: "border-orange-500/30",
114
+ bg: "bg-orange-500/5",
115
+ badge: "bg-orange-500/15 text-orange-400",
116
+ insights: [
117
+ "New hire first commit: 4.2hr vs team avg 1.8hr",
118
+ "Tool discovery: 3 tools week 1 to 8 tools week 6",
119
+ ],
120
+ roi: "4x faster ramp time",
121
+ },
122
+ ] as const;
123
+
124
+ // ── Enterprise Persona Card ──
125
+ function PersonaCard({ persona }: { persona: typeof PERSONAS[number] }) {
126
+ const Icon = persona.icon;
127
+ const isMuted = "muted" in persona && persona.muted;
128
+ return (
129
+ <Card className={`${persona.color} ${persona.bg} ${isMuted ? "opacity-50" : ""}`}>
130
+ <CardContent className="p-5">
131
+ <div className="flex items-center gap-3 mb-3">
132
+ <div className={`rounded-lg p-2 ${persona.bg}`}>
133
+ <Icon className="h-5 w-5" />
134
+ </div>
135
+ <div className="flex-1 min-w-0">
136
+ <div className="flex items-center gap-2">
137
+ <h4 className="text-sm font-bold truncate">{persona.name}</h4>
138
+ {"comingSoon" in persona && persona.comingSoon && (
139
+ <Badge variant="outline" className="text-[9px] text-zinc-500 border-zinc-500/30">Coming Soon</Badge>
140
+ )}
141
+ </div>
142
+ <div className="flex items-center gap-2 mt-0.5">
143
+ <span className={`text-[10px] font-bold uppercase tracking-wider px-2 py-0.5 rounded-full ${persona.badge}`}>
144
+ {persona.metrics} metrics
145
+ </span>
146
+ {"blocked" in persona && persona.blocked && (
147
+ <span className="text-[10px] text-muted-foreground">{persona.blocked} blocked</span>
148
+ )}
149
+ </div>
150
+ </div>
151
+ </div>
152
+
153
+ <div className="space-y-1.5 mb-3">
154
+ {persona.insights.map((insight, i) => (
155
+ <div key={i} className="flex items-start gap-2">
156
+ <ArrowRight className="h-3 w-3 mt-0.5 shrink-0 text-muted-foreground" />
157
+ <p className="text-xs text-muted-foreground leading-relaxed">{insight}</p>
158
+ </div>
159
+ ))}
160
+ </div>
161
+
162
+ <div className="rounded-lg bg-background/40 px-3 py-2">
163
+ <p className="text-[10px] font-bold uppercase tracking-wider text-muted-foreground mb-0.5">ROI</p>
164
+ <p className="text-xs font-semibold">{persona.roi}</p>
165
+ </div>
166
+
167
+ {"note" in persona && persona.note && (
168
+ <p className="text-[10px] text-muted-foreground mt-2 italic">{persona.note}</p>
169
+ )}
170
+ </CardContent>
171
+ </Card>
172
+ );
173
+ }
174
+
175
+ // ── Enterprise Page ──
176
+ function EnterprisePage() {
177
+ return (
178
+ <div className="space-y-6">
179
+ <div>
180
+ <h2 className="text-2xl font-semibold">Enterprise</h2>
181
+ <p className="text-sm text-muted-foreground mt-1">Team analytics, compliance, and cloud sessions</p>
182
+ </div>
183
+
184
+ {/* Header */}
185
+ <Card>
186
+ <CardContent className="pt-6">
187
+ <div className="flex items-center gap-3 mb-3">
188
+ <div className="rounded-lg bg-blue-500/10 p-2.5">
189
+ <Building2 className="h-6 w-6 text-blue-500" />
190
+ </div>
191
+ <div>
192
+ <h2 className="text-xl font-bold">context-mode for Enterprise</h2>
193
+ <p className="text-sm text-muted-foreground">56 metrics · 8 personas · 143 actionable insights</p>
194
+ </div>
195
+ </div>
196
+ <p className="text-sm text-muted-foreground leading-relaxed">
197
+ The open source plugin handles individual developers.
198
+ For teams, we're building a managed analytics layer.
199
+ </p>
200
+ </CardContent>
201
+ </Card>
202
+
203
+ {/* Enterprise Value Props — 2x2 Grid */}
204
+ <div className="grid gap-4 md:grid-cols-2">
205
+ <Card>
206
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
207
+ <CardTitle className="text-sm">Context as a Service — API</CardTitle>
208
+ <Cloud className="h-4 w-4 text-cyan-500" />
209
+ </CardHeader>
210
+ <CardContent>
211
+ <CardDescription className="mb-4">
212
+ Your AI tools produce session data that no other tool can see. We expose it as an API.
213
+ </CardDescription>
214
+ <div className="flex flex-wrap gap-2 mb-4">
215
+ <Badge variant="secondary" className="text-[10px]">CI/CD Pipelines</Badge>
216
+ <Badge variant="secondary" className="text-[10px]">Code Review</Badge>
217
+ <Badge variant="secondary" className="text-[10px]">Compliance</Badge>
218
+ </div>
219
+ <p className="text-[11px] text-muted-foreground">
220
+ Twilio model: plugin free, API paid.
221
+ </p>
222
+ </CardContent>
223
+ </Card>
224
+
225
+ <Card>
226
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
227
+ <CardTitle className="text-sm">For your CISO</CardTitle>
228
+ <ShieldCheck className="h-4 w-4 text-red-500" />
229
+ </CardHeader>
230
+ <CardContent>
231
+ <CardDescription className="mb-4 italic">
232
+ "What did the AI do? Which files did it access? Did it run anything dangerous? Can we prove it for SOC2?"
233
+ </CardDescription>
234
+ <div className="space-y-2">
235
+ <div className="flex items-center gap-2">
236
+ <Badge variant="outline" className="text-[10px] shrink-0">Audit</Badge>
237
+ <span className="text-xs text-muted-foreground">Every tool call, every file access, timestamped</span>
238
+ </div>
239
+ <div className="flex items-center gap-2">
240
+ <Badge variant="outline" className="text-[10px] shrink-0">SOC2</Badge>
241
+ <span className="text-xs text-muted-foreground">Automated compliance reports</span>
242
+ </div>
243
+ </div>
244
+ </CardContent>
245
+ </Card>
246
+
247
+ <Card>
248
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
249
+ <CardTitle className="text-sm">For your DevOps</CardTitle>
250
+ <GitPullRequest className="h-4 w-4 text-purple-500" />
251
+ </CardHeader>
252
+ <CardContent>
253
+ <CardDescription className="mb-4 italic">
254
+ "AI edited 47 files in this PR, 3 have no tests, 4 edit-run-fix cycles on auth.ts. Should we merge?"
255
+ </CardDescription>
256
+ <div className="flex flex-wrap gap-2">
257
+ <Badge variant="secondary" className="text-[10px]">GitHub Actions</Badge>
258
+ <Badge variant="secondary" className="text-[10px]">AI risk scoring</Badge>
259
+ <Badge variant="secondary" className="text-[10px]">Deploy gates</Badge>
260
+ </div>
261
+ </CardContent>
262
+ </Card>
263
+
264
+ <Card>
265
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
266
+ <CardTitle className="text-sm">For your developers</CardTitle>
267
+ <Monitor className="h-4 w-4 text-emerald-500" />
268
+ </CardHeader>
269
+ <CardContent>
270
+ <CardDescription className="mb-4 italic">
271
+ "I was debugging auth.ts yesterday on my laptop. Now I'm on my desktop. Where was I?"
272
+ </CardDescription>
273
+ <p className="text-xs font-semibold">Cloud sessions. Any device, any time. Full history.</p>
274
+ </CardContent>
275
+ </Card>
276
+ </div>
277
+
278
+ {/* Persona Grid */}
279
+ <div>
280
+ <div className="flex items-center gap-2 mb-3">
281
+ <Users className="h-4 w-4 text-purple-500" />
282
+ <h3 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">Who Gets What</h3>
283
+ <Badge variant="secondary" className="text-[10px]">8 personas</Badge>
284
+ </div>
285
+ <div className="grid gap-3 md:grid-cols-2">
286
+ {PERSONAS.map((persona, i) => (
287
+ <PersonaCard key={i} persona={persona} />
288
+ ))}
289
+ </div>
290
+ </div>
291
+
292
+ <Separator />
293
+
294
+ {/* CTA */}
295
+ <Card className="border-blue-500/30 bg-blue-500/5">
296
+ <CardContent className="pt-6">
297
+ <div className="flex flex-col sm:flex-row items-start sm:items-center gap-4">
298
+ <div className="flex-1">
299
+ <h3 className="text-base font-bold mb-1">We're onboarding design partners</h3>
300
+ <p className="text-sm text-muted-foreground">
301
+ 5 spots for teams that want to shape the product. Free access during the design phase.
302
+ </p>
303
+ </div>
304
+ <a
305
+ href="mailto:bm.ksglu@gmail.com?subject=context-mode%20Enterprise%20—%20Design%20Partner"
306
+ className="inline-flex items-center gap-2 rounded-lg bg-blue-500 px-4 py-2 text-sm font-medium text-white hover:bg-blue-600 transition-colors shrink-0"
307
+ >
308
+ <Mail className="h-4 w-4" />
309
+ Contact Us
310
+ </a>
311
+ </div>
312
+ </CardContent>
313
+ </Card>
314
+ </div>
315
+ );
316
+ }