nitrostack 1.0.65 → 1.0.66

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 (55) hide show
  1. package/package.json +2 -1
  2. package/src/studio/README.md +140 -0
  3. package/src/studio/app/api/auth/fetch-metadata/route.ts +71 -0
  4. package/src/studio/app/api/auth/register-client/route.ts +67 -0
  5. package/src/studio/app/api/chat/route.ts +250 -0
  6. package/src/studio/app/api/health/checks/route.ts +42 -0
  7. package/src/studio/app/api/health/route.ts +13 -0
  8. package/src/studio/app/api/init/route.ts +109 -0
  9. package/src/studio/app/api/ping/route.ts +13 -0
  10. package/src/studio/app/api/prompts/[name]/route.ts +21 -0
  11. package/src/studio/app/api/prompts/route.ts +13 -0
  12. package/src/studio/app/api/resources/[...uri]/route.ts +18 -0
  13. package/src/studio/app/api/resources/route.ts +13 -0
  14. package/src/studio/app/api/roots/route.ts +13 -0
  15. package/src/studio/app/api/sampling/route.ts +14 -0
  16. package/src/studio/app/api/tools/[name]/call/route.ts +41 -0
  17. package/src/studio/app/api/tools/route.ts +23 -0
  18. package/src/studio/app/api/widget-examples/route.ts +44 -0
  19. package/src/studio/app/auth/callback/page.tsx +175 -0
  20. package/src/studio/app/auth/page.tsx +560 -0
  21. package/src/studio/app/chat/page.tsx +1133 -0
  22. package/src/studio/app/chat/page.tsx.backup +390 -0
  23. package/src/studio/app/globals.css +486 -0
  24. package/src/studio/app/health/page.tsx +179 -0
  25. package/src/studio/app/layout.tsx +68 -0
  26. package/src/studio/app/logs/page.tsx +279 -0
  27. package/src/studio/app/page.tsx +351 -0
  28. package/src/studio/app/page.tsx.backup +346 -0
  29. package/src/studio/app/ping/page.tsx +209 -0
  30. package/src/studio/app/prompts/page.tsx +230 -0
  31. package/src/studio/app/resources/page.tsx +315 -0
  32. package/src/studio/app/settings/page.tsx +199 -0
  33. package/src/studio/branding.md +807 -0
  34. package/src/studio/components/EnlargeModal.tsx +138 -0
  35. package/src/studio/components/LogMessage.tsx +153 -0
  36. package/src/studio/components/MarkdownRenderer.tsx +410 -0
  37. package/src/studio/components/Sidebar.tsx +295 -0
  38. package/src/studio/components/ToolCard.tsx +139 -0
  39. package/src/studio/components/WidgetRenderer.tsx +346 -0
  40. package/src/studio/lib/api.ts +207 -0
  41. package/src/studio/lib/http-client-transport.ts +222 -0
  42. package/src/studio/lib/llm-service.ts +480 -0
  43. package/src/studio/lib/log-manager.ts +76 -0
  44. package/src/studio/lib/mcp-client.ts +258 -0
  45. package/src/studio/lib/store.ts +192 -0
  46. package/src/studio/lib/theme-provider.tsx +50 -0
  47. package/src/studio/lib/types.ts +107 -0
  48. package/src/studio/lib/widget-loader.ts +90 -0
  49. package/src/studio/middleware.ts +27 -0
  50. package/src/studio/next.config.js +38 -0
  51. package/src/studio/package.json +35 -0
  52. package/src/studio/postcss.config.mjs +10 -0
  53. package/src/studio/public/nitrocloud.png +0 -0
  54. package/src/studio/tailwind.config.ts +67 -0
  55. package/src/studio/tsconfig.json +42 -0
@@ -0,0 +1,199 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect } from 'react';
4
+ import { Settings as SettingsIcon, Wifi, CheckCircle, AlertCircle } from 'lucide-react';
5
+
6
+ export default function SettingsPage() {
7
+ const [transport, setTransport] = useState<'stdio' | 'http'>('stdio');
8
+ const [connecting, setConnecting] = useState(false);
9
+ const [connectionStatus, setConnectionStatus] = useState<'idle' | 'success' | 'error'>('idle');
10
+ const [errorMessage, setErrorMessage] = useState('');
11
+
12
+ useEffect(() => {
13
+ // Load saved settings from localStorage
14
+ const savedTransport = localStorage.getItem('mcp_transport');
15
+
16
+ if (savedTransport) setTransport(savedTransport as 'stdio' | 'http');
17
+ }, []);
18
+
19
+ const handleSaveSettings = async () => {
20
+ setConnecting(true);
21
+ setConnectionStatus('idle');
22
+ setErrorMessage('');
23
+
24
+ try {
25
+ // Save settings to localStorage
26
+ localStorage.setItem('mcp_transport', transport);
27
+
28
+ // Try to reconnect with new settings
29
+ const response = await fetch('/api/init', {
30
+ method: 'POST',
31
+ headers: { 'Content-Type': 'application/json' },
32
+ body: JSON.stringify({
33
+ transport,
34
+ }),
35
+ });
36
+
37
+ if (!response.ok) {
38
+ const error = await response.json();
39
+ throw new Error(error.error || 'Failed to connect');
40
+ }
41
+
42
+ const data = await response.json();
43
+ setConnectionStatus('success');
44
+ console.log('✅ Settings saved and connection established:', data);
45
+ } catch (error: any) {
46
+ console.error('❌ Failed to save settings:', error);
47
+ setConnectionStatus('error');
48
+ setErrorMessage(error.message || 'Failed to connect');
49
+ } finally {
50
+ setConnecting(false);
51
+ }
52
+ };
53
+
54
+ return (
55
+ <div className="fixed inset-0 flex flex-col bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
56
+ {/* Sticky Header */}
57
+ <div className="sticky top-0 z-10 border-b border-border/50 px-6 py-3 flex items-center justify-between bg-card/80 backdrop-blur-md shadow-sm">
58
+ <div className="flex items-center gap-3">
59
+ <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-primary to-amber-500 flex items-center justify-center shadow-md">
60
+ <SettingsIcon className="w-5 h-5 text-white" strokeWidth={2.5} />
61
+ </div>
62
+ <div>
63
+ <h1 className="text-lg font-bold text-foreground">Settings</h1>
64
+ </div>
65
+ </div>
66
+ </div>
67
+
68
+ {/* Content - ONLY this scrolls */}
69
+ <div className="flex-1 overflow-y-auto overflow-x-hidden">
70
+ <div className="max-w-4xl mx-auto px-6 py-6">
71
+
72
+ {/* Settings Card */}
73
+ <div className="max-w-2xl">
74
+ <div className="card p-6">
75
+ <h2 className="text-xl font-semibold text-foreground mb-6">Transport Configuration</h2>
76
+
77
+ {/* Transport Type Selection */}
78
+ <div className="mb-6">
79
+ <label className="block text-sm font-medium text-foreground mb-3">
80
+ Transport Type
81
+ </label>
82
+ <div className="grid grid-cols-2 gap-4">
83
+ <button
84
+ disabled
85
+ className={`p-4 rounded-lg border-2 transition-all text-left border-primary bg-primary/10`}
86
+ >
87
+ <div className="flex items-center gap-3 mb-2">
88
+ <div className={`w-3 h-3 rounded-full bg-primary`} />
89
+ <h3 className="font-semibold text-foreground">STDIO</h3>
90
+ </div>
91
+ <p className="text-sm text-muted-foreground">
92
+ Direct process communication (default)
93
+ </p>
94
+ </button>
95
+
96
+ <button
97
+ disabled
98
+ className={`p-4 rounded-lg border-2 transition-all text-left border-border hover:border-primary/50`}
99
+ >
100
+ <div className="flex items-center gap-3 mb-2">
101
+ <div className={`w-3 h-3 rounded-full bg-muted`} />
102
+ <h3 className="font-semibold text-foreground">HTTP</h3>
103
+ </div>
104
+ <p className="text-sm text-muted-foreground">
105
+ HTTP/SSE transport for remote servers
106
+ </p>
107
+ </button>
108
+ </div>
109
+ </div>
110
+
111
+ {/* Port Allocation Info */}
112
+ <div className="mb-6 p-4 bg-blue-500/10 rounded-lg border border-blue-500/20">
113
+ <h4 className="font-semibold text-foreground mb-2">Port Allocation</h4>
114
+ <div className="space-y-1 text-sm">
115
+ <div className="flex items-center gap-2">
116
+ <span className="text-muted-foreground">Studio UI:</span>
117
+ <code className="px-2 py-0.5 bg-muted rounded text-foreground">Port 3000</code>
118
+ </div>
119
+ <div className="flex items-center gap-2">
120
+ <span className="text-muted-foreground">Widget Server:</span>
121
+ <code className="px-2 py-0.5 bg-muted rounded text-foreground">Port 3001</code>
122
+ </div>
123
+ <div className="flex items-center gap-2">
124
+ <span className="text-muted-foreground">MCP HTTP Server:</span>
125
+ <code className="px-2 py-0.5 bg-primary/20 rounded text-primary font-semibold">Port 3002</code>
126
+ </div>
127
+ </div>
128
+ </div>
129
+
130
+ {/* Info Box */}
131
+ <div className="mb-6 p-4 bg-primary/5 rounded-lg border border-primary/20">
132
+ <div className="flex gap-3">
133
+ <Wifi className="w-5 h-5 text-primary flex-shrink-0 mt-0.5" />
134
+ <div>
135
+ <h4 className="font-semibold text-foreground mb-1">Transport Information</h4>
136
+ <p className="text-sm text-muted-foreground mb-2">
137
+ <strong>STDIO</strong> (Default): Studio spawns the MCP server as a child process and communicates
138
+ via standard input/output. The MCP server still runs dual transport (STDIO + HTTP on port 3002).
139
+ </p>
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ {/* Connection Status */}
145
+ {connectionStatus !== 'idle' && (
146
+ <div className={`mb-6 p-4 rounded-lg border ${
147
+ connectionStatus === 'success'
148
+ ? 'bg-emerald-500/10 border-emerald-500/20'
149
+ : 'bg-rose-500/10 border-rose-500/20'
150
+ }`}>
151
+ <div className="flex gap-3">
152
+ {connectionStatus === 'success' ? (
153
+ <>
154
+ <CheckCircle className="w-5 h-5 text-emerald-500 flex-shrink-0 mt-0.5" />
155
+ <div>
156
+ <h4 className="font-semibold text-emerald-500 mb-1">Connected</h4>
157
+ <p className="text-sm text-emerald-600">
158
+ Settings saved and connection established successfully.
159
+ </p>
160
+ </div>
161
+ </>
162
+ ) : (
163
+ <>
164
+ <AlertCircle className="w-5 h-5 text-rose-500 flex-shrink-0 mt-0.5" />
165
+ <div>
166
+ <h4 className="font-semibold text-rose-500 mb-1">Connection Failed</h4>
167
+ <p className="text-sm text-rose-600">
168
+ {errorMessage || 'Failed to establish connection with the selected transport.'}
169
+ </p>
170
+ </div>
171
+ </>
172
+ )}
173
+ </div>
174
+ </div>
175
+ )}
176
+
177
+ {/* Save Button */}
178
+ <button
179
+ onClick={handleSaveSettings}
180
+ disabled={connecting}
181
+ className="btn btn-primary w-full"
182
+ >
183
+ {connecting ? (
184
+ <>
185
+ <div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
186
+ Connecting...
187
+ </>
188
+ ) : (
189
+ 'Save & Connect'
190
+ )}
191
+ </button>
192
+ </div>
193
+ </div>
194
+ </div>
195
+ </div>
196
+ </div>
197
+ );
198
+ }
199
+