veryfront 0.0.51 → 0.0.52

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.
@@ -0,0 +1,128 @@
1
+ 'use client'
2
+
3
+ import { Chat } from 'veryfront/ai/components'
4
+ import { useChat } from 'veryfront/ai/react'
5
+ import { ServiceConnections } from './components/ServiceConnections'
6
+
7
+ // Define services for this project - automatically populated by scaffolding
8
+ // Each integration adds its service here when installed
9
+ const SERVICES = [
10
+ // Services will be dynamically populated based on installed integrations
11
+ // For now, we fetch from the status API instead
12
+ ]
13
+
14
+ export default function ChatPage() {
15
+ const chat = useChat({ api: '/api/chat' })
16
+
17
+ return (
18
+ <div className="flex flex-col h-screen bg-white dark:bg-neutral-900">
19
+ {/* Header - sticky at top, full width */}
20
+ <header className="sticky top-0 z-10 flex-shrink-0 border-b border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900">
21
+ <div className="px-4 py-3 flex items-center justify-between">
22
+ <h1 className="font-medium text-neutral-900 dark:text-white">AI Assistant</h1>
23
+ <div className="flex items-center gap-4">
24
+ <IntegrationStatus />
25
+ <a
26
+ href="/setup"
27
+ className="text-sm text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"
28
+ >
29
+ Setup
30
+ </a>
31
+ </div>
32
+ </div>
33
+ </header>
34
+
35
+ {/* Chat - fills remaining space with scrollable content */}
36
+ <Chat {...chat} className="flex-1 min-h-0" placeholder="Message" />
37
+ </div>
38
+ )
39
+ }
40
+
41
+ // Component to show integration status from the API
42
+ function IntegrationStatus() {
43
+ // Note: ServiceConnections fetches from /api/auth/status
44
+ // We'll use the integrations/status API which has the full list
45
+ return <ServiceStatusFromAPI />
46
+ }
47
+
48
+ import { useEffect, useState } from 'react'
49
+
50
+ interface Integration {
51
+ id: string
52
+ name: string
53
+ connected: boolean
54
+ connectUrl: string
55
+ }
56
+
57
+ function ServiceStatusFromAPI() {
58
+ const [integrations, setIntegrations] = useState<Integration[]>([])
59
+ const [loading, setLoading] = useState(true)
60
+
61
+ useEffect(() => {
62
+ async function fetchStatus() {
63
+ try {
64
+ const res = await fetch('/api/integrations/status')
65
+ if (res.ok) {
66
+ const data = await res.json()
67
+ setIntegrations(data.integrations || [])
68
+ }
69
+ } catch (error) {
70
+ console.error('Failed to fetch integration status:', error)
71
+ } finally {
72
+ setLoading(false)
73
+ }
74
+ }
75
+ fetchStatus()
76
+ }, [])
77
+
78
+ if (loading) {
79
+ return (
80
+ <div className="flex items-center gap-2">
81
+ <div className="animate-pulse h-6 w-24 bg-neutral-200 dark:bg-neutral-700 rounded-full" />
82
+ </div>
83
+ )
84
+ }
85
+
86
+ if (integrations.length === 0) {
87
+ return null
88
+ }
89
+
90
+ const connected = integrations.filter(i => i.connected)
91
+ const disconnected = integrations.filter(i => !i.connected)
92
+
93
+ return (
94
+ <div className="flex items-center gap-2">
95
+ {/* Show connected services as green badges */}
96
+ {connected.map(service => (
97
+ <span
98
+ key={service.id}
99
+ className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400"
100
+ title={`${service.name} connected`}
101
+ >
102
+ <span className="w-1.5 h-1.5 rounded-full bg-green-500" />
103
+ {service.name}
104
+ </span>
105
+ ))}
106
+
107
+ {/* Show disconnected services as clickable grey badges */}
108
+ {disconnected.map(service => (
109
+ <a
110
+ key={service.id}
111
+ href={service.connectUrl}
112
+ className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-xs font-medium bg-neutral-100 text-neutral-600 hover:bg-neutral-200 dark:bg-neutral-800 dark:text-neutral-400 dark:hover:bg-neutral-700 transition-colors"
113
+ title={`Connect ${service.name}`}
114
+ >
115
+ <span className="w-1.5 h-1.5 rounded-full bg-neutral-400" />
116
+ {service.name}
117
+ </a>
118
+ ))}
119
+
120
+ {/* Show count if not all connected */}
121
+ {disconnected.length > 0 && (
122
+ <span className="text-xs text-neutral-500 dark:text-neutral-400">
123
+ {connected.length}/{integrations.length}
124
+ </span>
125
+ )}
126
+ </div>
127
+ )
128
+ }
@@ -46,18 +46,12 @@ const gmailService = new OAuthService(gmailConfig, memoryTokenStore);
46
46
  * Create a Gmail client for API operations
47
47
  */
48
48
  export function createGmailClient() {
49
+ // OAuthService.fetch() already handles auth, error checking, and JSON parsing
49
50
  async function apiRequest<T>(
50
51
  endpoint: string,
51
52
  options: RequestInit = {},
52
53
  ): Promise<T> {
53
- const response = await gmailService.fetch(endpoint, options);
54
-
55
- if (!response.ok) {
56
- const error = await response.text();
57
- throw new Error(`Gmail API error: ${response.status} - ${error}`);
58
- }
59
-
60
- return response.json();
54
+ return gmailService.fetch<T>(endpoint, options);
61
55
  }
62
56
 
63
57
  return {
@@ -12,7 +12,12 @@ export default function ChatPage() {
12
12
  <header className="sticky top-0 z-10 flex-shrink-0 border-b border-neutral-200 dark:border-neutral-800 bg-white dark:bg-neutral-900">
13
13
  <div className="px-4 py-3 flex items-center justify-between">
14
14
  <h1 className="font-medium text-neutral-900 dark:text-white">AI Assistant</h1>
15
- {/* Add ServiceConnections here when integrations are added */}
15
+ <a
16
+ href="/setup"
17
+ className="text-sm text-neutral-500 hover:text-neutral-700 dark:text-neutral-400 dark:hover:text-neutral-200"
18
+ >
19
+ Setup
20
+ </a>
16
21
  </div>
17
22
  </header>
18
23
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "Zero-config React meta-framework for building agentic AI applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",