@contractspec/example.integration-hub 3.5.5 → 3.7.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.
@@ -51,6 +51,38 @@ function useIntegrationData(projectId = "local-project") {
51
51
  };
52
52
  }
53
53
 
54
+ // src/ui/IntegrationHubChat.tsx
55
+ import { ChatWithSidebar } from "@contractspec/module.ai-chat";
56
+ import { jsxDEV } from "react/jsx-dev-runtime";
57
+ "use client";
58
+ var DEFAULT_SUGGESTIONS = [
59
+ "List my integrations",
60
+ "Show sync status",
61
+ "Add a connection"
62
+ ];
63
+ var DEFAULT_SYSTEM_PROMPT = `You are an Integration Hub assistant. Help users manage integrations, connections, and sync configurations. When asked about integrations, connections, or syncs, provide clear, actionable guidance.`;
64
+ function IntegrationHubChat({
65
+ proxyUrl = "/api/chat",
66
+ mcpServers,
67
+ thinkingLevel = "thinking",
68
+ suggestions = DEFAULT_SUGGESTIONS,
69
+ systemPrompt = DEFAULT_SYSTEM_PROMPT,
70
+ className
71
+ }) {
72
+ return /* @__PURE__ */ jsxDEV("div", {
73
+ className: className ?? "flex h-[500px] flex-col",
74
+ children: /* @__PURE__ */ jsxDEV(ChatWithSidebar, {
75
+ className: "flex-1",
76
+ systemPrompt,
77
+ proxyUrl,
78
+ mcpServers,
79
+ thinkingLevel,
80
+ suggestions,
81
+ showSuggestionsWhenEmpty: true
82
+ }, undefined, false, undefined, this)
83
+ }, undefined, false, undefined, this);
84
+ }
85
+
54
86
  // src/ui/IntegrationDashboard.tsx
55
87
  import { useState as useState2 } from "react";
56
88
  import {
@@ -60,7 +92,7 @@ import {
60
92
  StatCard,
61
93
  StatCardGroup
62
94
  } from "@contractspec/lib.design-system";
63
- import { jsxDEV } from "react/jsx-dev-runtime";
95
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
64
96
  "use client";
65
97
  var STATUS_COLORS = {
66
98
  ACTIVE: "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400",
@@ -93,35 +125,36 @@ function IntegrationDashboard() {
93
125
  const tabs = [
94
126
  { id: "integrations", label: "Integrations", icon: "\uD83D\uDD0C" },
95
127
  { id: "connections", label: "Connections", icon: "\uD83D\uDD17" },
96
- { id: "syncs", label: "Sync Configs", icon: "\uD83D\uDD04" }
128
+ { id: "syncs", label: "Sync Configs", icon: "\uD83D\uDD04" },
129
+ { id: "chat", label: "Chat", icon: "\uD83D\uDCAC" }
97
130
  ];
98
131
  if (loading) {
99
- return /* @__PURE__ */ jsxDEV(LoaderBlock, {
132
+ return /* @__PURE__ */ jsxDEV2(LoaderBlock, {
100
133
  label: "Loading Integrations..."
101
134
  }, undefined, false, undefined, this);
102
135
  }
103
136
  if (error) {
104
- return /* @__PURE__ */ jsxDEV(ErrorState, {
137
+ return /* @__PURE__ */ jsxDEV2(ErrorState, {
105
138
  title: "Failed to load Integrations",
106
139
  description: error.message,
107
140
  onRetry: refetch,
108
141
  retryLabel: "Retry"
109
142
  }, undefined, false, undefined, this);
110
143
  }
111
- return /* @__PURE__ */ jsxDEV("div", {
144
+ return /* @__PURE__ */ jsxDEV2("div", {
112
145
  className: "space-y-6",
113
146
  children: [
114
- /* @__PURE__ */ jsxDEV("div", {
147
+ /* @__PURE__ */ jsxDEV2("div", {
115
148
  className: "flex items-center justify-between",
116
149
  children: [
117
- /* @__PURE__ */ jsxDEV("h2", {
150
+ /* @__PURE__ */ jsxDEV2("h2", {
118
151
  className: "text-2xl font-bold",
119
152
  children: "Integration Hub"
120
153
  }, undefined, false, undefined, this),
121
- /* @__PURE__ */ jsxDEV(Button, {
154
+ /* @__PURE__ */ jsxDEV2(Button, {
122
155
  onClick: () => alert("Add integration modal"),
123
156
  children: [
124
- /* @__PURE__ */ jsxDEV("span", {
157
+ /* @__PURE__ */ jsxDEV2("span", {
125
158
  className: "mr-2",
126
159
  children: "+"
127
160
  }, undefined, false, undefined, this),
@@ -130,66 +163,66 @@ function IntegrationDashboard() {
130
163
  }, undefined, true, undefined, this)
131
164
  ]
132
165
  }, undefined, true, undefined, this),
133
- /* @__PURE__ */ jsxDEV(StatCardGroup, {
166
+ /* @__PURE__ */ jsxDEV2(StatCardGroup, {
134
167
  children: [
135
- /* @__PURE__ */ jsxDEV(StatCard, {
168
+ /* @__PURE__ */ jsxDEV2(StatCard, {
136
169
  label: "Integrations",
137
170
  value: stats.totalIntegrations,
138
171
  hint: `${stats.activeIntegrations} active`
139
172
  }, undefined, false, undefined, this),
140
- /* @__PURE__ */ jsxDEV(StatCard, {
173
+ /* @__PURE__ */ jsxDEV2(StatCard, {
141
174
  label: "Connections",
142
175
  value: stats.totalConnections,
143
176
  hint: `${stats.connectedCount} connected`
144
177
  }, undefined, false, undefined, this),
145
- /* @__PURE__ */ jsxDEV(StatCard, {
178
+ /* @__PURE__ */ jsxDEV2(StatCard, {
146
179
  label: "Syncs",
147
180
  value: stats.totalSyncs,
148
181
  hint: `${stats.activeSyncs} active`
149
182
  }, undefined, false, undefined, this)
150
183
  ]
151
184
  }, undefined, true, undefined, this),
152
- /* @__PURE__ */ jsxDEV("nav", {
185
+ /* @__PURE__ */ jsxDEV2("nav", {
153
186
  className: "bg-muted flex gap-1 rounded-lg p-1",
154
187
  role: "tablist",
155
- children: tabs.map((tab) => /* @__PURE__ */ jsxDEV(Button, {
188
+ children: tabs.map((tab) => /* @__PURE__ */ jsxDEV2(Button, {
156
189
  type: "button",
157
190
  role: "tab",
158
191
  "aria-selected": activeTab === tab.id,
159
192
  onClick: () => setActiveTab(tab.id),
160
193
  className: `flex flex-1 items-center justify-center gap-2 rounded-md px-4 py-2 text-sm font-medium transition-colors ${activeTab === tab.id ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
161
194
  children: [
162
- /* @__PURE__ */ jsxDEV("span", {
195
+ /* @__PURE__ */ jsxDEV2("span", {
163
196
  children: tab.icon
164
197
  }, undefined, false, undefined, this),
165
198
  tab.label
166
199
  ]
167
200
  }, tab.id, true, undefined, this))
168
201
  }, undefined, false, undefined, this),
169
- /* @__PURE__ */ jsxDEV("div", {
202
+ /* @__PURE__ */ jsxDEV2("div", {
170
203
  className: "min-h-[400px]",
171
204
  role: "tabpanel",
172
205
  children: [
173
- activeTab === "integrations" && /* @__PURE__ */ jsxDEV("div", {
206
+ activeTab === "integrations" && /* @__PURE__ */ jsxDEV2("div", {
174
207
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
175
208
  children: [
176
- integrations.map((integration) => /* @__PURE__ */ jsxDEV("div", {
209
+ integrations.map((integration) => /* @__PURE__ */ jsxDEV2("div", {
177
210
  className: "border-border bg-card hover:bg-muted/50 cursor-pointer rounded-lg border p-4 transition-colors",
178
211
  children: [
179
- /* @__PURE__ */ jsxDEV("div", {
212
+ /* @__PURE__ */ jsxDEV2("div", {
180
213
  className: "mb-3 flex items-center gap-3",
181
214
  children: [
182
- /* @__PURE__ */ jsxDEV("span", {
215
+ /* @__PURE__ */ jsxDEV2("span", {
183
216
  className: "text-2xl",
184
217
  children: TYPE_ICONS[integration.type] ?? "\u2699\uFE0F"
185
218
  }, undefined, false, undefined, this),
186
- /* @__PURE__ */ jsxDEV("div", {
219
+ /* @__PURE__ */ jsxDEV2("div", {
187
220
  children: [
188
- /* @__PURE__ */ jsxDEV("h3", {
221
+ /* @__PURE__ */ jsxDEV2("h3", {
189
222
  className: "font-medium",
190
223
  children: integration.name
191
224
  }, undefined, false, undefined, this),
192
- /* @__PURE__ */ jsxDEV("p", {
225
+ /* @__PURE__ */ jsxDEV2("p", {
193
226
  className: "text-muted-foreground text-sm",
194
227
  children: integration.type
195
228
  }, undefined, false, undefined, this)
@@ -197,14 +230,14 @@ function IntegrationDashboard() {
197
230
  }, undefined, true, undefined, this)
198
231
  ]
199
232
  }, undefined, true, undefined, this),
200
- /* @__PURE__ */ jsxDEV("div", {
233
+ /* @__PURE__ */ jsxDEV2("div", {
201
234
  className: "flex items-center justify-between",
202
235
  children: [
203
- /* @__PURE__ */ jsxDEV("span", {
236
+ /* @__PURE__ */ jsxDEV2("span", {
204
237
  className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[integration.status] ?? ""}`,
205
238
  children: integration.status
206
239
  }, undefined, false, undefined, this),
207
- /* @__PURE__ */ jsxDEV("span", {
240
+ /* @__PURE__ */ jsxDEV2("span", {
208
241
  className: "text-muted-foreground text-xs",
209
242
  children: integration.createdAt.toLocaleDateString()
210
243
  }, undefined, false, undefined, this)
@@ -212,64 +245,64 @@ function IntegrationDashboard() {
212
245
  }, undefined, true, undefined, this)
213
246
  ]
214
247
  }, integration.id, true, undefined, this)),
215
- integrations.length === 0 && /* @__PURE__ */ jsxDEV("div", {
248
+ integrations.length === 0 && /* @__PURE__ */ jsxDEV2("div", {
216
249
  className: "text-muted-foreground col-span-full flex h-64 items-center justify-center",
217
250
  children: "No integrations configured"
218
251
  }, undefined, false, undefined, this)
219
252
  ]
220
253
  }, undefined, true, undefined, this),
221
- activeTab === "connections" && /* @__PURE__ */ jsxDEV("div", {
254
+ activeTab === "connections" && /* @__PURE__ */ jsxDEV2("div", {
222
255
  className: "border-border rounded-lg border",
223
- children: /* @__PURE__ */ jsxDEV("table", {
256
+ children: /* @__PURE__ */ jsxDEV2("table", {
224
257
  className: "w-full",
225
258
  children: [
226
- /* @__PURE__ */ jsxDEV("thead", {
259
+ /* @__PURE__ */ jsxDEV2("thead", {
227
260
  className: "border-border bg-muted/30 border-b",
228
- children: /* @__PURE__ */ jsxDEV("tr", {
261
+ children: /* @__PURE__ */ jsxDEV2("tr", {
229
262
  children: [
230
- /* @__PURE__ */ jsxDEV("th", {
263
+ /* @__PURE__ */ jsxDEV2("th", {
231
264
  className: "px-4 py-3 text-left text-sm font-medium",
232
265
  children: "Connection"
233
266
  }, undefined, false, undefined, this),
234
- /* @__PURE__ */ jsxDEV("th", {
267
+ /* @__PURE__ */ jsxDEV2("th", {
235
268
  className: "px-4 py-3 text-left text-sm font-medium",
236
269
  children: "Status"
237
270
  }, undefined, false, undefined, this),
238
- /* @__PURE__ */ jsxDEV("th", {
271
+ /* @__PURE__ */ jsxDEV2("th", {
239
272
  className: "px-4 py-3 text-left text-sm font-medium",
240
273
  children: "Last Sync"
241
274
  }, undefined, false, undefined, this)
242
275
  ]
243
276
  }, undefined, true, undefined, this)
244
277
  }, undefined, false, undefined, this),
245
- /* @__PURE__ */ jsxDEV("tbody", {
278
+ /* @__PURE__ */ jsxDEV2("tbody", {
246
279
  className: "divide-border divide-y",
247
280
  children: [
248
- connections.map((conn) => /* @__PURE__ */ jsxDEV("tr", {
281
+ connections.map((conn) => /* @__PURE__ */ jsxDEV2("tr", {
249
282
  className: "hover:bg-muted/50",
250
283
  children: [
251
- /* @__PURE__ */ jsxDEV("td", {
284
+ /* @__PURE__ */ jsxDEV2("td", {
252
285
  className: "px-4 py-3",
253
- children: /* @__PURE__ */ jsxDEV("div", {
286
+ children: /* @__PURE__ */ jsxDEV2("div", {
254
287
  className: "font-medium",
255
288
  children: conn.name
256
289
  }, undefined, false, undefined, this)
257
290
  }, undefined, false, undefined, this),
258
- /* @__PURE__ */ jsxDEV("td", {
291
+ /* @__PURE__ */ jsxDEV2("td", {
259
292
  className: "px-4 py-3",
260
- children: /* @__PURE__ */ jsxDEV("span", {
293
+ children: /* @__PURE__ */ jsxDEV2("span", {
261
294
  className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[conn.status] ?? ""}`,
262
295
  children: conn.status
263
296
  }, undefined, false, undefined, this)
264
297
  }, undefined, false, undefined, this),
265
- /* @__PURE__ */ jsxDEV("td", {
298
+ /* @__PURE__ */ jsxDEV2("td", {
266
299
  className: "text-muted-foreground px-4 py-3 text-sm",
267
300
  children: conn.lastSyncAt?.toLocaleString() ?? "Never"
268
301
  }, undefined, false, undefined, this)
269
302
  ]
270
303
  }, conn.id, true, undefined, this)),
271
- connections.length === 0 && /* @__PURE__ */ jsxDEV("tr", {
272
- children: /* @__PURE__ */ jsxDEV("td", {
304
+ connections.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
305
+ children: /* @__PURE__ */ jsxDEV2("td", {
273
306
  colSpan: 3,
274
307
  className: "text-muted-foreground px-4 py-8 text-center",
275
308
  children: "No connections found"
@@ -280,48 +313,58 @@ function IntegrationDashboard() {
280
313
  ]
281
314
  }, undefined, true, undefined, this)
282
315
  }, undefined, false, undefined, this),
283
- activeTab === "syncs" && /* @__PURE__ */ jsxDEV("div", {
316
+ activeTab === "chat" && /* @__PURE__ */ jsxDEV2(IntegrationHubChat, {
317
+ proxyUrl: "/api/chat",
318
+ thinkingLevel: "thinking",
319
+ suggestions: [
320
+ "List my integrations",
321
+ "Show sync status",
322
+ "Add a connection"
323
+ ],
324
+ className: "min-h-[400px]"
325
+ }, undefined, false, undefined, this),
326
+ activeTab === "syncs" && /* @__PURE__ */ jsxDEV2("div", {
284
327
  className: "border-border rounded-lg border",
285
- children: /* @__PURE__ */ jsxDEV("table", {
328
+ children: /* @__PURE__ */ jsxDEV2("table", {
286
329
  className: "w-full",
287
330
  children: [
288
- /* @__PURE__ */ jsxDEV("thead", {
331
+ /* @__PURE__ */ jsxDEV2("thead", {
289
332
  className: "border-border bg-muted/30 border-b",
290
- children: /* @__PURE__ */ jsxDEV("tr", {
333
+ children: /* @__PURE__ */ jsxDEV2("tr", {
291
334
  children: [
292
- /* @__PURE__ */ jsxDEV("th", {
335
+ /* @__PURE__ */ jsxDEV2("th", {
293
336
  className: "px-4 py-3 text-left text-sm font-medium",
294
337
  children: "Sync Config"
295
338
  }, undefined, false, undefined, this),
296
- /* @__PURE__ */ jsxDEV("th", {
339
+ /* @__PURE__ */ jsxDEV2("th", {
297
340
  className: "px-4 py-3 text-left text-sm font-medium",
298
341
  children: "Frequency"
299
342
  }, undefined, false, undefined, this),
300
- /* @__PURE__ */ jsxDEV("th", {
343
+ /* @__PURE__ */ jsxDEV2("th", {
301
344
  className: "px-4 py-3 text-left text-sm font-medium",
302
345
  children: "Status"
303
346
  }, undefined, false, undefined, this),
304
- /* @__PURE__ */ jsxDEV("th", {
347
+ /* @__PURE__ */ jsxDEV2("th", {
305
348
  className: "px-4 py-3 text-left text-sm font-medium",
306
349
  children: "Records"
307
350
  }, undefined, false, undefined, this)
308
351
  ]
309
352
  }, undefined, true, undefined, this)
310
353
  }, undefined, false, undefined, this),
311
- /* @__PURE__ */ jsxDEV("tbody", {
354
+ /* @__PURE__ */ jsxDEV2("tbody", {
312
355
  className: "divide-border divide-y",
313
356
  children: [
314
- syncConfigs.map((sync) => /* @__PURE__ */ jsxDEV("tr", {
357
+ syncConfigs.map((sync) => /* @__PURE__ */ jsxDEV2("tr", {
315
358
  className: "hover:bg-muted/50",
316
359
  children: [
317
- /* @__PURE__ */ jsxDEV("td", {
360
+ /* @__PURE__ */ jsxDEV2("td", {
318
361
  className: "px-4 py-3",
319
362
  children: [
320
- /* @__PURE__ */ jsxDEV("div", {
363
+ /* @__PURE__ */ jsxDEV2("div", {
321
364
  className: "font-medium",
322
365
  children: sync.name
323
366
  }, undefined, false, undefined, this),
324
- /* @__PURE__ */ jsxDEV("div", {
367
+ /* @__PURE__ */ jsxDEV2("div", {
325
368
  className: "text-muted-foreground text-sm",
326
369
  children: [
327
370
  sync.sourceEntity,
@@ -331,25 +374,25 @@ function IntegrationDashboard() {
331
374
  }, undefined, true, undefined, this)
332
375
  ]
333
376
  }, undefined, true, undefined, this),
334
- /* @__PURE__ */ jsxDEV("td", {
377
+ /* @__PURE__ */ jsxDEV2("td", {
335
378
  className: "px-4 py-3 text-sm",
336
379
  children: sync.frequency
337
380
  }, undefined, false, undefined, this),
338
- /* @__PURE__ */ jsxDEV("td", {
381
+ /* @__PURE__ */ jsxDEV2("td", {
339
382
  className: "px-4 py-3",
340
- children: /* @__PURE__ */ jsxDEV("span", {
383
+ children: /* @__PURE__ */ jsxDEV2("span", {
341
384
  className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${STATUS_COLORS[sync.status] ?? ""}`,
342
385
  children: sync.status
343
386
  }, undefined, false, undefined, this)
344
387
  }, undefined, false, undefined, this),
345
- /* @__PURE__ */ jsxDEV("td", {
388
+ /* @__PURE__ */ jsxDEV2("td", {
346
389
  className: "text-muted-foreground px-4 py-3 text-sm",
347
390
  children: sync.recordsSynced.toLocaleString()
348
391
  }, undefined, false, undefined, this)
349
392
  ]
350
393
  }, sync.id, true, undefined, this)),
351
- syncConfigs.length === 0 && /* @__PURE__ */ jsxDEV("tr", {
352
- children: /* @__PURE__ */ jsxDEV("td", {
394
+ syncConfigs.length === 0 && /* @__PURE__ */ jsxDEV2("tr", {
395
+ children: /* @__PURE__ */ jsxDEV2("td", {
353
396
  colSpan: 4,
354
397
  className: "text-muted-foreground px-4 py-8 text-center",
355
398
  children: "No sync configurations found"
@@ -0,0 +1,15 @@
1
+ import type { McpClientConfig } from '@contractspec/lib.ai-agent/tools/mcp-client.browser';
2
+ export interface IntegrationHubChatProps {
3
+ /** Chat API URL (e.g. /api/chat). Required for streaming. */
4
+ proxyUrl?: string;
5
+ /** MCP server configs. Browser supports http/sse only; stdio returns empty tools. */
6
+ mcpServers?: McpClientConfig[];
7
+ /** Initial thinking level */
8
+ thinkingLevel?: 'instant' | 'thinking' | 'extra_thinking' | 'max';
9
+ /** Suggestion chips for empty state */
10
+ suggestions?: string[];
11
+ /** System prompt override */
12
+ systemPrompt?: string;
13
+ className?: string;
14
+ }
15
+ export declare function IntegrationHubChat({ proxyUrl, mcpServers, thinkingLevel, suggestions, systemPrompt, className, }: IntegrationHubChatProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,35 @@
1
+ // @bun
2
+ // src/ui/IntegrationHubChat.tsx
3
+ import { ChatWithSidebar } from "@contractspec/module.ai-chat";
4
+ import { jsxDEV } from "react/jsx-dev-runtime";
5
+ "use client";
6
+ var DEFAULT_SUGGESTIONS = [
7
+ "List my integrations",
8
+ "Show sync status",
9
+ "Add a connection"
10
+ ];
11
+ var DEFAULT_SYSTEM_PROMPT = `You are an Integration Hub assistant. Help users manage integrations, connections, and sync configurations. When asked about integrations, connections, or syncs, provide clear, actionable guidance.`;
12
+ function IntegrationHubChat({
13
+ proxyUrl = "/api/chat",
14
+ mcpServers,
15
+ thinkingLevel = "thinking",
16
+ suggestions = DEFAULT_SUGGESTIONS,
17
+ systemPrompt = DEFAULT_SYSTEM_PROMPT,
18
+ className
19
+ }) {
20
+ return /* @__PURE__ */ jsxDEV("div", {
21
+ className: className ?? "flex h-[500px] flex-col",
22
+ children: /* @__PURE__ */ jsxDEV(ChatWithSidebar, {
23
+ className: "flex-1",
24
+ systemPrompt,
25
+ proxyUrl,
26
+ mcpServers,
27
+ thinkingLevel,
28
+ suggestions,
29
+ showSuggestionsWhenEmpty: true
30
+ }, undefined, false, undefined, this)
31
+ }, undefined, false, undefined, this);
32
+ }
33
+ export {
34
+ IntegrationHubChat
35
+ };
@@ -3,4 +3,5 @@
3
3
  */
4
4
  export * from './renderers';
5
5
  export { IntegrationDashboard } from './IntegrationDashboard';
6
+ export { IntegrationHubChat } from './IntegrationHubChat';
6
7
  export * from './hooks';