nitrostack 1.0.70 → 1.0.72

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 (35) hide show
  1. package/package.json +1 -1
  2. package/src/studio/app/api/chat/route.ts +33 -15
  3. package/src/studio/app/auth/callback/page.tsx +6 -6
  4. package/src/studio/app/chat/page.tsx +1124 -415
  5. package/src/studio/app/chat/page.tsx.backup +1046 -187
  6. package/src/studio/app/globals.css +361 -191
  7. package/src/studio/app/health/page.tsx +72 -76
  8. package/src/studio/app/layout.tsx +9 -11
  9. package/src/studio/app/logs/page.tsx +29 -30
  10. package/src/studio/app/page.tsx +134 -230
  11. package/src/studio/app/prompts/page.tsx +115 -97
  12. package/src/studio/app/resources/page.tsx +115 -124
  13. package/src/studio/app/settings/page.tsx +1080 -125
  14. package/src/studio/app/tools/page.tsx +343 -0
  15. package/src/studio/components/EnlargeModal.tsx +76 -65
  16. package/src/studio/components/LogMessage.tsx +5 -5
  17. package/src/studio/components/MarkdownRenderer.tsx +4 -4
  18. package/src/studio/components/Sidebar.tsx +150 -210
  19. package/src/studio/components/SplashScreen.tsx +109 -0
  20. package/src/studio/components/ToolCard.tsx +50 -41
  21. package/src/studio/components/VoiceOrbOverlay.tsx +469 -0
  22. package/src/studio/components/WidgetRenderer.tsx +8 -3
  23. package/src/studio/components/tools/ToolsCanvas.tsx +327 -0
  24. package/src/studio/lib/llm-service.ts +104 -1
  25. package/src/studio/lib/store.ts +36 -21
  26. package/src/studio/lib/types.ts +1 -1
  27. package/src/studio/package-lock.json +3303 -0
  28. package/src/studio/package.json +3 -1
  29. package/src/studio/public/NitroStudio Isotype Color.png +0 -0
  30. package/src/studio/tailwind.config.ts +63 -17
  31. package/templates/typescript-starter/package-lock.json +4112 -0
  32. package/templates/typescript-starter/package.json +2 -3
  33. package/templates/typescript-starter/src/modules/calculator/calculator.tools.ts +100 -5
  34. package/src/studio/app/auth/page.tsx +0 -560
  35. package/src/studio/app/ping/page.tsx +0 -209
@@ -1,209 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { useStudioStore } from '@/lib/store';
5
- import { api } from '@/lib/api';
6
- import { Wifi, Activity, Clock, TrendingUp, Radio } from 'lucide-react';
7
-
8
- export default function PingPage() {
9
- const { pingHistory, addPingResult } = useStudioStore();
10
- const [pinging, setPinging] = useState(false);
11
- const [lastLatency, setLastLatency] = useState<number | null>(null);
12
-
13
- const handlePing = async () => {
14
- setPinging(true);
15
- const startTime = Date.now();
16
-
17
- try {
18
- await api.ping();
19
- const latency = Date.now() - startTime;
20
- setLastLatency(latency);
21
- addPingResult({ time: new Date(), latency });
22
- } catch (error) {
23
- console.error('Ping failed:', error);
24
- } finally {
25
- setPinging(false);
26
- }
27
- };
28
-
29
- const averageLatency =
30
- pingHistory.length > 0
31
- ? Math.round(pingHistory.reduce((sum, p) => sum + p.latency, 0) / pingHistory.length)
32
- : null;
33
-
34
- const minLatency =
35
- pingHistory.length > 0
36
- ? Math.min(...pingHistory.map((p) => p.latency))
37
- : null;
38
-
39
- const maxLatency =
40
- pingHistory.length > 0
41
- ? Math.max(...pingHistory.map((p) => p.latency))
42
- : null;
43
-
44
- const getLatencyColor = (latency: number) => {
45
- if (latency < 100) return 'text-emerald-500';
46
- if (latency < 500) return 'text-amber-500';
47
- return 'text-rose-500';
48
- };
49
-
50
- const getLatencyBg = (latency: number) => {
51
- if (latency < 100) return 'bg-emerald-500/10 border-emerald-500/20';
52
- if (latency < 500) return 'bg-amber-500/10 border-amber-500/20';
53
- return 'bg-rose-500/10 border-rose-500/20';
54
- };
55
-
56
- const getLatencyDotColor = (latency: number) => {
57
- if (latency < 100) return 'bg-emerald-500';
58
- if (latency < 500) return 'bg-amber-500';
59
- return 'bg-rose-500';
60
- };
61
-
62
- return (
63
- <div className="fixed inset-0 flex flex-col bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
64
- {/* Sticky Header */}
65
- <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">
66
- <div className="flex items-center gap-3">
67
- <div className="w-8 h-8 rounded-lg bg-gradient-to-br from-cyan-500 to-blue-500 flex items-center justify-center shadow-md">
68
- <Wifi className="w-5 h-5 text-white" strokeWidth={2.5} />
69
- </div>
70
- <div>
71
- <h1 className="text-lg font-bold text-foreground">Ping</h1>
72
- </div>
73
- </div>
74
- </div>
75
-
76
- {/* Content - ONLY this scrolls */}
77
- <div className="flex-1 overflow-y-auto overflow-x-hidden">
78
- <div className="max-w-4xl mx-auto px-6 py-6">
79
-
80
- {/* Main Ping Card */}
81
- <div className="card card-hover p-8 mb-8 text-center bg-gradient-to-br from-card via-card to-muted/20">
82
- <button
83
- onClick={handlePing}
84
- disabled={pinging}
85
- className="btn btn-primary btn-lg mx-auto px-12 py-4 text-lg gap-3 shadow-lg hover:shadow-xl transition-all"
86
- >
87
- {pinging ? (
88
- <>
89
- <Radio className="w-6 h-6 animate-pulse" />
90
- Pinging...
91
- </>
92
- ) : (
93
- <>
94
- <Wifi className="w-6 h-6" />
95
- Send Ping
96
- </>
97
- )}
98
- </button>
99
-
100
- {lastLatency !== null && (
101
- <div className="mt-8 animate-fade-in">
102
- <div className={`inline-block px-8 py-4 rounded-2xl border ${getLatencyBg(lastLatency)}`}>
103
- <div className={`text-6xl font-bold ${getLatencyColor(lastLatency)}`}>
104
- {lastLatency}ms
105
- </div>
106
- <div className="text-muted-foreground mt-2 flex items-center justify-center gap-2">
107
- <Clock className="w-4 h-4" />
108
- Last ping latency
109
- </div>
110
- </div>
111
- </div>
112
- )}
113
- </div>
114
-
115
- {/* Statistics Grid */}
116
- {pingHistory.length > 0 && (
117
- <div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
118
- {/* Average */}
119
- <div className="card card-hover p-6">
120
- <div className="flex items-center gap-3 mb-3">
121
- <div className="w-10 h-10 rounded-lg bg-blue-500/10 flex items-center justify-center">
122
- <TrendingUp className="w-5 h-5 text-blue-500" />
123
- </div>
124
- <h3 className="font-semibold text-foreground">Average</h3>
125
- </div>
126
- <div className="text-3xl font-bold text-foreground">{averageLatency}ms</div>
127
- <p className="text-sm text-muted-foreground mt-1">{pingHistory.length} total pings</p>
128
- </div>
129
-
130
- {/* Min */}
131
- <div className="card card-hover p-6">
132
- <div className="flex items-center gap-3 mb-3">
133
- <div className="w-10 h-10 rounded-lg bg-emerald-500/10 flex items-center justify-center">
134
- <Activity className="w-5 h-5 text-emerald-500" />
135
- </div>
136
- <h3 className="font-semibold text-foreground">Fastest</h3>
137
- </div>
138
- <div className="text-3xl font-bold text-emerald-500">{minLatency}ms</div>
139
- <p className="text-sm text-muted-foreground mt-1">Best response time</p>
140
- </div>
141
-
142
- {/* Max */}
143
- <div className="card card-hover p-6">
144
- <div className="flex items-center gap-3 mb-3">
145
- <div className="w-10 h-10 rounded-lg bg-amber-500/10 flex items-center justify-center">
146
- <Clock className="w-5 h-5 text-amber-500" />
147
- </div>
148
- <h3 className="font-semibold text-foreground">Slowest</h3>
149
- </div>
150
- <div className="text-3xl font-bold text-amber-500">{maxLatency}ms</div>
151
- <p className="text-sm text-muted-foreground mt-1">Worst response time</p>
152
- </div>
153
- </div>
154
- )}
155
-
156
- {/* Ping History */}
157
- {pingHistory.length > 0 && (
158
- <div>
159
- <h2 className="text-2xl font-semibold text-foreground mb-6 flex items-center gap-2">
160
- <Activity className="w-6 h-6 text-primary" />
161
- Recent Pings
162
- </h2>
163
- <div className="space-y-3">
164
- {pingHistory.slice().reverse().map((ping, idx) => (
165
- <div
166
- key={idx}
167
- className="card card-hover p-5 flex items-center justify-between animate-fade-in"
168
- >
169
- <div className="flex items-center gap-3">
170
- <div className={`w-3 h-3 rounded-full ${getLatencyDotColor(ping.latency)} shadow-lg`} />
171
- <span className="text-sm text-muted-foreground font-mono">
172
- {ping.time.toLocaleTimeString()}
173
- </span>
174
- </div>
175
- <div className="flex items-center gap-3">
176
- <span className={`text-lg font-bold ${getLatencyColor(ping.latency)}`}>
177
- {ping.latency}ms
178
- </span>
179
- <span className={`badge ${
180
- ping.latency < 100
181
- ? 'badge-success'
182
- : ping.latency < 500
183
- ? 'badge-warning'
184
- : 'badge-error'
185
- }`}>
186
- {ping.latency < 100 ? 'Excellent' : ping.latency < 500 ? 'Good' : 'Slow'}
187
- </span>
188
- </div>
189
- </div>
190
- ))}
191
- </div>
192
- </div>
193
- )}
194
-
195
- {/* Empty State */}
196
- {pingHistory.length === 0 && !pinging && (
197
- <div className="empty-state">
198
- <Wifi className="empty-state-icon" />
199
- <p className="empty-state-title">No ping history yet</p>
200
- <p className="empty-state-description">
201
- Click the "Send Ping" button above to test your connection
202
- </p>
203
- </div>
204
- )}
205
- </div>
206
- </div>
207
- </div>
208
- );
209
- }