nitrostack 1.0.71 → 1.0.73
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.
- package/dist/auth/api-key.js.map +1 -1
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +3 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/middleware.d.ts +1 -1
- package/dist/auth/middleware.d.ts.map +1 -1
- package/dist/auth/middleware.js.map +1 -1
- package/dist/auth/secure-secret.d.ts +136 -0
- package/dist/auth/secure-secret.d.ts.map +1 -0
- package/dist/auth/secure-secret.js +182 -0
- package/dist/auth/secure-secret.js.map +1 -0
- package/dist/auth/server-metadata.d.ts.map +1 -1
- package/dist/auth/server-metadata.js.map +1 -1
- package/dist/auth/simple-jwt.d.ts +100 -14
- package/dist/auth/simple-jwt.d.ts.map +1 -1
- package/dist/auth/simple-jwt.js +19 -9
- package/dist/auth/simple-jwt.js.map +1 -1
- package/dist/auth/token-store.js +1 -1
- package/dist/auth/token-store.js.map +1 -1
- package/dist/auth/token-validation.js +1 -1
- package/dist/auth/token-validation.js.map +1 -1
- package/dist/cli/commands/build.js +1 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/generate-types.js +12 -12
- package/dist/cli/commands/generate-types.js.map +1 -1
- package/dist/cli/commands/generate.d.ts +8 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +13 -12
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.js +1 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/upgrade.d.ts +10 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +221 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/app-decorator.d.ts +4 -3
- package/dist/core/app-decorator.d.ts.map +1 -1
- package/dist/core/app-decorator.js +67 -28
- package/dist/core/app-decorator.js.map +1 -1
- package/dist/core/builders.d.ts +19 -7
- package/dist/core/builders.d.ts.map +1 -1
- package/dist/core/builders.js +15 -8
- package/dist/core/builders.js.map +1 -1
- package/dist/core/component.d.ts +8 -8
- package/dist/core/component.d.ts.map +1 -1
- package/dist/core/component.js +3 -2
- package/dist/core/component.js.map +1 -1
- package/dist/core/config-module.d.ts +11 -4
- package/dist/core/config-module.d.ts.map +1 -1
- package/dist/core/config-module.js +1 -1
- package/dist/core/config-module.js.map +1 -1
- package/dist/core/decorators/cache.decorator.d.ts +9 -9
- package/dist/core/decorators/cache.decorator.d.ts.map +1 -1
- package/dist/core/decorators/cache.decorator.js +3 -3
- package/dist/core/decorators/cache.decorator.js.map +1 -1
- package/dist/core/decorators/health-check.decorator.d.ts +3 -3
- package/dist/core/decorators/health-check.decorator.d.ts.map +1 -1
- package/dist/core/decorators/health-check.decorator.js +2 -2
- package/dist/core/decorators/health-check.decorator.js.map +1 -1
- package/dist/core/decorators/rate-limit.decorator.d.ts +5 -4
- package/dist/core/decorators/rate-limit.decorator.d.ts.map +1 -1
- package/dist/core/decorators/rate-limit.decorator.js +3 -3
- package/dist/core/decorators/rate-limit.decorator.js.map +1 -1
- package/dist/core/decorators.d.ts +47 -29
- package/dist/core/decorators.d.ts.map +1 -1
- package/dist/core/decorators.js +9 -9
- package/dist/core/decorators.js.map +1 -1
- package/dist/core/di/container.d.ts +21 -4
- package/dist/core/di/container.d.ts.map +1 -1
- package/dist/core/di/container.js +11 -7
- package/dist/core/di/container.js.map +1 -1
- package/dist/core/di/injectable.decorator.d.ts +5 -3
- package/dist/core/di/injectable.decorator.d.ts.map +1 -1
- package/dist/core/di/injectable.decorator.js.map +1 -1
- package/dist/core/errors.d.ts +4 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/events/event-emitter.d.ts +3 -3
- package/dist/core/events/event-emitter.d.ts.map +1 -1
- package/dist/core/events/event-emitter.js.map +1 -1
- package/dist/core/events/event.decorator.d.ts +5 -5
- package/dist/core/events/event.decorator.d.ts.map +1 -1
- package/dist/core/events/event.decorator.js +10 -6
- package/dist/core/events/event.decorator.js.map +1 -1
- package/dist/core/events/log-emitter.d.ts +7 -1
- package/dist/core/events/log-emitter.d.ts.map +1 -1
- package/dist/core/events/log-emitter.js.map +1 -1
- package/dist/core/filters/exception-filter.decorator.d.ts +5 -5
- package/dist/core/filters/exception-filter.decorator.d.ts.map +1 -1
- package/dist/core/filters/exception-filter.decorator.js +3 -3
- package/dist/core/filters/exception-filter.decorator.js.map +1 -1
- package/dist/core/filters/exception-filter.interface.d.ts +14 -5
- package/dist/core/filters/exception-filter.interface.d.ts.map +1 -1
- package/dist/core/guards/apikey.guard.d.ts +1 -1
- package/dist/core/guards/apikey.guard.d.ts.map +1 -1
- package/dist/core/guards/guard.interface.d.ts +1 -1
- package/dist/core/guards/guard.interface.d.ts.map +1 -1
- package/dist/core/guards/jwt.guard.d.ts +1 -1
- package/dist/core/guards/jwt.guard.d.ts.map +1 -1
- package/dist/core/guards/oauth.guard.d.ts +1 -1
- package/dist/core/guards/oauth.guard.d.ts.map +1 -1
- package/dist/core/guards/use-guards.decorator.d.ts +3 -3
- package/dist/core/guards/use-guards.decorator.d.ts.map +1 -1
- package/dist/core/guards/use-guards.decorator.js +1 -1
- package/dist/core/guards/use-guards.decorator.js.map +1 -1
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/interceptors/interceptor.decorator.d.ts +4 -4
- package/dist/core/interceptors/interceptor.decorator.d.ts.map +1 -1
- package/dist/core/interceptors/interceptor.decorator.js +2 -2
- package/dist/core/interceptors/interceptor.decorator.js.map +1 -1
- package/dist/core/interceptors/interceptor.interface.d.ts +3 -3
- package/dist/core/interceptors/interceptor.interface.d.ts.map +1 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js.map +1 -1
- package/dist/core/middleware/middleware.decorator.d.ts +4 -4
- package/dist/core/middleware/middleware.decorator.d.ts.map +1 -1
- package/dist/core/middleware/middleware.decorator.js +2 -2
- package/dist/core/middleware/middleware.decorator.js.map +1 -1
- package/dist/core/middleware/middleware.interface.d.ts +3 -3
- package/dist/core/middleware/middleware.interface.d.ts.map +1 -1
- package/dist/core/module.d.ts +33 -14
- package/dist/core/module.d.ts.map +1 -1
- package/dist/core/module.js +11 -6
- package/dist/core/module.js.map +1 -1
- package/dist/core/oauth-module.d.ts +9 -3
- package/dist/core/oauth-module.d.ts.map +1 -1
- package/dist/core/oauth-module.js +4 -3
- package/dist/core/oauth-module.js.map +1 -1
- package/dist/core/pipes/pipe.decorator.d.ts +14 -5
- package/dist/core/pipes/pipe.decorator.d.ts.map +1 -1
- package/dist/core/pipes/pipe.decorator.js +2 -2
- package/dist/core/pipes/pipe.decorator.js.map +1 -1
- package/dist/core/pipes/pipe.interface.d.ts +9 -4
- package/dist/core/pipes/pipe.interface.d.ts.map +1 -1
- package/dist/core/prompt.d.ts +13 -4
- package/dist/core/prompt.d.ts.map +1 -1
- package/dist/core/prompt.js +2 -2
- package/dist/core/prompt.js.map +1 -1
- package/dist/core/resource.d.ts +7 -2
- package/dist/core/resource.d.ts.map +1 -1
- package/dist/core/resource.js +2 -2
- package/dist/core/resource.js.map +1 -1
- package/dist/core/server.d.ts +49 -3
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +61 -34
- package/dist/core/server.js.map +1 -1
- package/dist/core/tool.d.ts +44 -16
- package/dist/core/tool.d.ts.map +1 -1
- package/dist/core/tool.js +19 -6
- package/dist/core/tool.js.map +1 -1
- package/dist/core/transports/discovery-http-server.d.ts +7 -1
- package/dist/core/transports/discovery-http-server.d.ts.map +1 -1
- package/dist/core/transports/discovery-http-server.js.map +1 -1
- package/dist/core/transports/http-server.d.ts +2 -2
- package/dist/core/transports/http-server.d.ts.map +1 -1
- package/dist/core/transports/http-server.js +1 -1
- package/dist/core/transports/http-server.js.map +1 -1
- package/dist/core/transports/streamable-http.d.ts +4 -4
- package/dist/core/transports/streamable-http.d.ts.map +1 -1
- package/dist/core/transports/streamable-http.js +1 -1
- package/dist/core/transports/streamable-http.js.map +1 -1
- package/dist/core/types.d.ts +87 -15
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/widgets/widget-registry.d.ts +2 -2
- package/dist/core/widgets/widget-registry.d.ts.map +1 -1
- package/dist/core/widgets/widget-registry.js +1 -1
- package/dist/core/widgets/widget-registry.js.map +1 -1
- package/dist/testing/index.d.ts +44 -17
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -8
- package/dist/testing/index.js.map +1 -1
- package/dist/ui-next/index.d.ts +1 -1
- package/dist/ui-next/index.d.ts.map +1 -1
- package/dist/ui-next/index.js.map +1 -1
- package/dist/widgets/hooks/useWidgetSDK.d.ts +5 -5
- package/dist/widgets/runtime/WidgetLayout.js.map +1 -1
- package/dist/widgets/sdk.d.ts +5 -5
- package/dist/widgets/sdk.d.ts.map +1 -1
- package/dist/widgets/sdk.js.map +1 -1
- package/package.json +1 -1
- package/src/studio/app/api/auth/fetch-metadata/route.ts +3 -2
- package/src/studio/app/api/auth/register-client/route.ts +3 -2
- package/src/studio/app/api/chat/route.ts +33 -17
- package/src/studio/app/api/health/checks/route.ts +5 -4
- package/src/studio/app/api/init/route.ts +3 -2
- package/src/studio/app/api/ping/route.ts +3 -2
- package/src/studio/app/api/prompts/[name]/route.ts +4 -3
- package/src/studio/app/api/prompts/route.ts +3 -2
- package/src/studio/app/api/resources/[...uri]/route.ts +3 -2
- package/src/studio/app/api/resources/route.ts +3 -2
- package/src/studio/app/api/roots/route.ts +3 -2
- package/src/studio/app/api/sampling/route.ts +3 -2
- package/src/studio/app/api/tools/[name]/call/route.ts +3 -2
- package/src/studio/app/api/tools/route.ts +4 -3
- package/src/studio/app/api/widget-examples/route.ts +5 -4
- package/src/studio/app/auth/callback/page.tsx +9 -8
- package/src/studio/app/chat/page.tsx +1535 -468
- package/src/studio/app/chat/page.tsx.backup +1046 -187
- package/src/studio/app/globals.css +361 -191
- package/src/studio/app/health/page.tsx +73 -77
- package/src/studio/app/layout.tsx +9 -11
- package/src/studio/app/logs/page.tsx +31 -32
- package/src/studio/app/page.tsx +136 -232
- package/src/studio/app/prompts/page.tsx +115 -97
- package/src/studio/app/resources/page.tsx +115 -124
- package/src/studio/app/settings/page.tsx +1083 -127
- package/src/studio/app/tools/page.tsx +343 -0
- package/src/studio/components/EnlargeModal.tsx +76 -65
- package/src/studio/components/LogMessage.tsx +6 -6
- package/src/studio/components/MarkdownRenderer.tsx +246 -349
- package/src/studio/components/Sidebar.tsx +165 -210
- package/src/studio/components/SplashScreen.tsx +109 -0
- package/src/studio/components/ToolCard.tsx +50 -41
- package/src/studio/components/VoiceOrbOverlay.tsx +475 -0
- package/src/studio/components/WidgetErrorBoundary.tsx +48 -0
- package/src/studio/components/WidgetRenderer.tsx +169 -211
- package/src/studio/components/ops/OpsCanvas.tsx +748 -0
- package/src/studio/components/ops/OpsNodeDetailPanel.tsx +150 -0
- package/src/studio/components/ops/OpsSummaryBar.tsx +90 -0
- package/src/studio/components/ops/index.ts +5 -0
- package/src/studio/components/ops/nodes/BaseNode.tsx +65 -0
- package/src/studio/components/ops/nodes/LLMCallNode.tsx +34 -0
- package/src/studio/components/ops/nodes/LLMResponseNode.tsx +33 -0
- package/src/studio/components/ops/nodes/ToolCallNode.tsx +30 -0
- package/src/studio/components/ops/nodes/ToolResultNode.tsx +43 -0
- package/src/studio/components/ops/nodes/UserPromptNode.tsx +34 -0
- package/src/studio/components/ops/nodes/WidgetRenderNode.tsx +23 -0
- package/src/studio/components/ops/nodes/index.ts +8 -0
- package/src/studio/components/tools/ToolsCanvas.tsx +327 -0
- package/src/studio/lib/api.ts +61 -42
- package/src/studio/lib/http-client-transport.ts +2 -2
- package/src/studio/lib/llm-service.ts +126 -47
- package/src/studio/lib/mcp-client.ts +9 -6
- package/src/studio/lib/ops-store.ts +427 -0
- package/src/studio/lib/ops-tracker.ts +416 -0
- package/src/studio/lib/ops-types.ts +164 -0
- package/src/studio/lib/store.ts +23 -11
- package/src/studio/lib/types.ts +228 -38
- package/src/studio/lib/widget-loader.ts +2 -2
- package/src/studio/package-lock.json +3303 -0
- package/src/studio/package.json +3 -1
- package/src/studio/public/NitroStudio Isotype Color.png +0 -0
- package/src/studio/tailwind.config.ts +63 -17
- package/templates/typescript-oauth/src/modules/flights/flights.prompts.ts +19 -22
- package/dist/cli/build-widgets.mjs +0 -165
- package/src/studio/app/auth/page.tsx +0 -560
- package/src/studio/app/ping/page.tsx +0 -209
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
4
|
import { api } from '@/lib/api';
|
|
5
|
-
import {
|
|
5
|
+
import { HeartIcon, ArrowPathIcon, CheckCircleIcon, ExclamationTriangleIcon, XCircleIcon, QuestionMarkCircleIcon } from '@heroicons/react/24/outline';
|
|
6
6
|
|
|
7
7
|
interface HealthCheck {
|
|
8
8
|
name: string;
|
|
9
9
|
status: 'up' | 'down' | 'degraded';
|
|
10
10
|
message?: string;
|
|
11
|
-
details?:
|
|
11
|
+
details?: Record<string, unknown>;
|
|
12
12
|
timestamp?: number;
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -38,47 +38,40 @@ export default function HealthPage() {
|
|
|
38
38
|
healthChecks.length === 0
|
|
39
39
|
? 'unknown'
|
|
40
40
|
: healthChecks.every((c) => c.status === 'up')
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
? 'healthy'
|
|
42
|
+
: healthChecks.some((c) => c.status === 'down')
|
|
43
|
+
? 'unhealthy'
|
|
44
|
+
: 'degraded';
|
|
45
45
|
|
|
46
46
|
const getStatusIcon = (status: string) => {
|
|
47
47
|
switch (status) {
|
|
48
48
|
case 'up':
|
|
49
49
|
case 'healthy':
|
|
50
|
-
return <
|
|
50
|
+
return <CheckCircleIcon className="w-12 h-12 text-emerald-500" />;
|
|
51
51
|
case 'degraded':
|
|
52
|
-
return <
|
|
52
|
+
return <ExclamationTriangleIcon className="w-12 h-12 text-status-warning" />;
|
|
53
53
|
case 'down':
|
|
54
54
|
case 'unhealthy':
|
|
55
|
-
return <
|
|
55
|
+
return <XCircleIcon className="w-12 h-12 text-rose-500" />;
|
|
56
56
|
default:
|
|
57
|
-
return <
|
|
57
|
+
return <QuestionMarkCircleIcon className="w-12 h-12 text-muted-foreground" />;
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
return (
|
|
62
62
|
<div className="fixed inset-0 flex flex-col bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
|
|
63
|
-
{/*
|
|
64
|
-
<div className="sticky top-0 z-10 border-b border-border/50 px-6 py-
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<div>
|
|
70
|
-
<h1 className="text-lg font-bold text-foreground">Health</h1>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
<button onClick={loadHealth} className="btn btn-primary text-sm px-4 py-2 gap-2" disabled={loading}>
|
|
74
|
-
<RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
|
|
75
|
-
{loading ? 'Checking...' : 'Refresh'}
|
|
63
|
+
{/* Minimal Professional Header */}
|
|
64
|
+
<div className="sticky top-0 z-10 border-b border-border/50 px-6 py-4 flex items-center justify-between bg-card/50 backdrop-blur-sm">
|
|
65
|
+
<h1 className="text-lg font-semibold text-foreground">Health</h1>
|
|
66
|
+
<button onClick={loadHealth} className="btn btn-primary text-sm px-4 py-2 gap-2">
|
|
67
|
+
<ArrowPathIcon className="h-4 w-4" />
|
|
68
|
+
Refresh
|
|
76
69
|
</button>
|
|
77
70
|
</div>
|
|
78
71
|
|
|
79
|
-
{/* Content
|
|
72
|
+
{/* Content */}
|
|
80
73
|
<div className="flex-1 overflow-y-auto overflow-x-hidden">
|
|
81
|
-
<div className="max-w-
|
|
74
|
+
<div className="max-w-5xl mx-auto px-6 py-6">
|
|
82
75
|
{/* Overall Status */}
|
|
83
76
|
<div className="card p-8 bg-gradient-to-br from-card to-muted/20 mb-6">
|
|
84
77
|
<div className="flex items-center gap-6">
|
|
@@ -101,79 +94,82 @@ export default function HealthPage() {
|
|
|
101
94
|
</div>
|
|
102
95
|
) : healthChecks.length === 0 ? (
|
|
103
96
|
<div className="empty-state">
|
|
104
|
-
<
|
|
97
|
+
<HeartIcon className="empty-state-icon" />
|
|
105
98
|
<p className="empty-state-title">No health checks configured</p>
|
|
106
99
|
<p className="empty-state-description">
|
|
107
100
|
Add health checks using the @HealthCheck decorator
|
|
108
101
|
</p>
|
|
109
102
|
</div>
|
|
110
103
|
) : (
|
|
111
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-
|
|
104
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
112
105
|
{healthChecks.map((check) => (
|
|
113
|
-
<div key={check.name} className="card
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
<div key={check.name} className="group relative bg-card/50 border border-border/50 rounded-xl p-5 transition-all duration-200 hover:bg-card hover:border-border hover:shadow-lg animate-fade-in">
|
|
107
|
+
{/* Gradient hover effect */}
|
|
108
|
+
<div className="absolute inset-0 rounded-xl bg-gradient-to-br from-primary/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
|
|
109
|
+
|
|
110
|
+
<div className="relative">
|
|
111
|
+
<div className="flex items-start justify-between mb-3">
|
|
112
|
+
<div className="flex items-center gap-3">
|
|
113
|
+
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${check.status === 'up'
|
|
118
114
|
? 'bg-emerald-500/10'
|
|
119
115
|
: check.status === 'degraded'
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
? 'badge-success'
|
|
116
|
+
? 'bg-yellow-500/10'
|
|
117
|
+
: 'bg-rose-500/10'
|
|
118
|
+
}`}>
|
|
119
|
+
{check.status === 'up' ? (
|
|
120
|
+
<CheckCircleIcon className="w-4 h-4 text-emerald-500" />
|
|
121
|
+
) : check.status === 'degraded' ? (
|
|
122
|
+
<ExclamationTriangleIcon className="w-4 h-4 text-yellow-500" />
|
|
123
|
+
) : (
|
|
124
|
+
<XCircleIcon className="w-4 h-4 text-rose-500" />
|
|
125
|
+
)}
|
|
126
|
+
</div>
|
|
127
|
+
<div>
|
|
128
|
+
<h3 className="text-sm font-medium capitalize text-foreground">{check.name}</h3>
|
|
129
|
+
<span
|
|
130
|
+
className={`text-[10px] font-medium px-2 py-0.5 rounded-full ${check.status === 'up'
|
|
131
|
+
? 'bg-emerald-500/10 text-emerald-500'
|
|
137
132
|
: check.status === 'degraded'
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
? 'bg-yellow-500/10 text-yellow-500'
|
|
134
|
+
: 'bg-rose-500/10 text-rose-500'
|
|
135
|
+
}`}
|
|
136
|
+
>
|
|
137
|
+
{check.status}
|
|
138
|
+
</span>
|
|
139
|
+
</div>
|
|
144
140
|
</div>
|
|
145
141
|
</div>
|
|
146
|
-
</div>
|
|
147
142
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
143
|
+
{check.message && (
|
|
144
|
+
<p className="text-xs text-muted-foreground/80 mb-3 leading-relaxed">{check.message}</p>
|
|
145
|
+
)}
|
|
151
146
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
147
|
+
{check.details && (
|
|
148
|
+
<div className="mt-3 p-3 bg-muted/20 rounded-lg border border-border/50">
|
|
149
|
+
<p className="text-[10px] font-medium text-muted-foreground mb-2 uppercase tracking-wider">Details</p>
|
|
150
|
+
<div className="space-y-1.5">
|
|
151
|
+
{Object.entries(check.details).map(([key, value]) => (
|
|
152
|
+
<div key={key} className="flex justify-between text-xs">
|
|
153
|
+
<span className="text-muted-foreground/70 capitalize">{key}:</span>
|
|
154
|
+
<span className="text-foreground font-mono">{String(value)}</span>
|
|
155
|
+
</div>
|
|
156
|
+
))}
|
|
157
|
+
</div>
|
|
162
158
|
</div>
|
|
163
|
-
|
|
164
|
-
)}
|
|
159
|
+
)}
|
|
165
160
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
161
|
+
{check.timestamp && (
|
|
162
|
+
<p className="text-[10px] text-muted-foreground/60 mt-3">
|
|
163
|
+
Last check: {new Date(check.timestamp).toLocaleString()}
|
|
164
|
+
</p>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
171
167
|
</div>
|
|
172
168
|
))}
|
|
173
169
|
</div>
|
|
174
170
|
)}
|
|
175
171
|
</div>
|
|
176
172
|
</div>
|
|
177
|
-
|
|
173
|
+
</div>
|
|
178
174
|
);
|
|
179
175
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import type { Metadata } from 'next';
|
|
2
2
|
import './globals.css';
|
|
3
|
-
import '@fontsource/inter/400.css';
|
|
4
|
-
import '@fontsource/inter/500.css';
|
|
5
|
-
import '@fontsource/inter/600.css';
|
|
6
|
-
import '@fontsource/inter/700.css';
|
|
7
3
|
import '@fontsource/jetbrains-mono/400.css';
|
|
8
4
|
import '@fontsource/jetbrains-mono/500.css';
|
|
9
5
|
import { Sidebar } from '@/components/Sidebar';
|
|
10
6
|
import { EnlargeModal } from '@/components/EnlargeModal';
|
|
7
|
+
import { SplashScreen } from '@/components/SplashScreen';
|
|
11
8
|
|
|
12
9
|
export const metadata: Metadata = {
|
|
13
10
|
title: 'NitroStudio - MCP Development Suite',
|
|
@@ -26,17 +23,18 @@ export default function RootLayout({
|
|
|
26
23
|
}) {
|
|
27
24
|
return (
|
|
28
25
|
<html lang="en" suppressHydrationWarning className="antialiased">
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
<head>
|
|
27
|
+
<script
|
|
28
|
+
dangerouslySetInnerHTML={{
|
|
29
|
+
__html: `
|
|
33
30
|
// Force dark mode
|
|
34
31
|
document.documentElement.className = 'dark antialiased';
|
|
35
32
|
`,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
</head>
|
|
39
36
|
<body className="min-h-screen font-sans">
|
|
37
|
+
<SplashScreen />
|
|
40
38
|
<div className="flex min-h-screen bg-gradient-to-br from-background via-background to-muted/20">
|
|
41
39
|
<Sidebar />
|
|
42
40
|
<main className="flex-1 transition-all duration-300 ease-in-out" style={{ marginLeft: 'var(--sidebar-width, 15rem)' }}>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState, useRef } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { CommandLineIcon, ArrowDownTrayIcon, ClipboardDocumentIcon, TrashIcon, PlayIcon, PauseIcon, FunnelIcon } from '@heroicons/react/24/outline';
|
|
5
5
|
|
|
6
6
|
interface LogEntry {
|
|
7
7
|
timestamp: string;
|
|
8
8
|
level: 'info' | 'error' | 'warn' | 'debug';
|
|
9
9
|
message: string;
|
|
10
|
-
data?:
|
|
10
|
+
data?: unknown;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export default function LogsPage() {
|
|
@@ -17,12 +17,13 @@ export default function LogsPage() {
|
|
|
17
17
|
const [filter, setFilter] = useState<string>('all');
|
|
18
18
|
const [error, setError] = useState<string | null>(null);
|
|
19
19
|
const logsEndRef = useRef<HTMLDivElement>(null);
|
|
20
|
+
const logsContainerRef = useRef<HTMLDivElement>(null);
|
|
20
21
|
const eventSourceRef = useRef<EventSource | null>(null);
|
|
21
22
|
|
|
22
|
-
// Auto-scroll to bottom
|
|
23
|
+
// Auto-scroll to bottom of logs container only
|
|
23
24
|
useEffect(() => {
|
|
24
|
-
if (autoScroll &&
|
|
25
|
-
|
|
25
|
+
if (autoScroll && logsContainerRef.current) {
|
|
26
|
+
logsContainerRef.current.scrollTop = logsContainerRef.current.scrollHeight;
|
|
26
27
|
}
|
|
27
28
|
}, [logs, autoScroll]);
|
|
28
29
|
|
|
@@ -63,10 +64,10 @@ export default function LogsPage() {
|
|
|
63
64
|
};
|
|
64
65
|
|
|
65
66
|
const downloadLogs = () => {
|
|
66
|
-
const logsText = logs.map(log =>
|
|
67
|
+
const logsText = logs.map(log =>
|
|
67
68
|
`[${log.timestamp}] [${log.level.toUpperCase()}] ${log.message}${log.data ? '\n' + JSON.stringify(log.data, null, 2) : ''}`
|
|
68
69
|
).join('\n\n');
|
|
69
|
-
|
|
70
|
+
|
|
70
71
|
const blob = new Blob([logsText], { type: 'text/plain' });
|
|
71
72
|
const url = URL.createObjectURL(blob);
|
|
72
73
|
const a = document.createElement('a');
|
|
@@ -77,10 +78,10 @@ export default function LogsPage() {
|
|
|
77
78
|
};
|
|
78
79
|
|
|
79
80
|
const copyLogs = async () => {
|
|
80
|
-
const logsText = logs.map(log =>
|
|
81
|
+
const logsText = logs.map(log =>
|
|
81
82
|
`[${log.timestamp}] [${log.level.toUpperCase()}] ${log.message}${log.data ? '\n' + JSON.stringify(log.data, null, 2) : ''}`
|
|
82
83
|
).join('\n\n');
|
|
83
|
-
|
|
84
|
+
|
|
84
85
|
await navigator.clipboard.writeText(logsText);
|
|
85
86
|
// Could add a toast notification here
|
|
86
87
|
};
|
|
@@ -89,8 +90,8 @@ export default function LogsPage() {
|
|
|
89
90
|
setIsStreaming(!isStreaming);
|
|
90
91
|
};
|
|
91
92
|
|
|
92
|
-
const filteredLogs = filter === 'all'
|
|
93
|
-
? logs
|
|
93
|
+
const filteredLogs = filter === 'all'
|
|
94
|
+
? logs
|
|
94
95
|
: logs.filter(log => log.level === filter);
|
|
95
96
|
|
|
96
97
|
const getLevelColor = (level: string) => {
|
|
@@ -111,7 +112,7 @@ export default function LogsPage() {
|
|
|
111
112
|
}
|
|
112
113
|
};
|
|
113
114
|
|
|
114
|
-
const formatData = (data:
|
|
115
|
+
const formatData = (data: unknown): string => {
|
|
115
116
|
try {
|
|
116
117
|
return JSON.stringify(data, null, 2);
|
|
117
118
|
} catch {
|
|
@@ -120,12 +121,12 @@ export default function LogsPage() {
|
|
|
120
121
|
};
|
|
121
122
|
|
|
122
123
|
return (
|
|
123
|
-
<div className="flex flex-col
|
|
124
|
+
<div className="fixed inset-0 flex flex-col bg-black" style={{ left: 'var(--sidebar-width, 15rem)' }}>
|
|
124
125
|
{/* Header */}
|
|
125
126
|
<div className="flex items-center justify-between px-6 py-4 bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900 border-b border-slate-700">
|
|
126
127
|
<div className="flex items-center gap-3">
|
|
127
128
|
<div className="p-2 rounded-lg bg-emerald-500/10 border border-emerald-500/20">
|
|
128
|
-
<
|
|
129
|
+
<CommandLineIcon className="w-5 h-5 text-emerald-400" />
|
|
129
130
|
</div>
|
|
130
131
|
<div>
|
|
131
132
|
<h1 className="text-xl font-bold text-white">Server Logs</h1>
|
|
@@ -150,11 +151,10 @@ export default function LogsPage() {
|
|
|
150
151
|
{/* Auto-scroll toggle */}
|
|
151
152
|
<button
|
|
152
153
|
onClick={() => setAutoScroll(!autoScroll)}
|
|
153
|
-
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}`}
|
|
154
|
+
className={`px-3 py-2 rounded-lg text-sm font-medium transition-colors ${autoScroll
|
|
155
|
+
? 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30'
|
|
156
|
+
: 'bg-slate-800 text-slate-400 border border-slate-700 hover:bg-slate-700'
|
|
157
|
+
}`}
|
|
158
158
|
>
|
|
159
159
|
Auto-scroll
|
|
160
160
|
</button>
|
|
@@ -162,14 +162,13 @@ export default function LogsPage() {
|
|
|
162
162
|
{/* Streaming toggle */}
|
|
163
163
|
<button
|
|
164
164
|
onClick={toggleStreaming}
|
|
165
|
-
className={`p-2 rounded-lg transition-colors ${
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}`}
|
|
165
|
+
className={`p-2 rounded-lg transition-colors ${isStreaming
|
|
166
|
+
? 'bg-emerald-500/20 text-emerald-400 border border-emerald-500/30'
|
|
167
|
+
: 'bg-slate-800 text-slate-400 border border-slate-700 hover:bg-slate-700'
|
|
168
|
+
}`}
|
|
170
169
|
title={isStreaming ? 'Pause streaming' : 'Resume streaming'}
|
|
171
170
|
>
|
|
172
|
-
{isStreaming ? <
|
|
171
|
+
{isStreaming ? <PauseIcon className="w-4 h-4" /> : <PlayIcon className="w-4 h-4" />}
|
|
173
172
|
</button>
|
|
174
173
|
|
|
175
174
|
{/* Copy */}
|
|
@@ -178,7 +177,7 @@ export default function LogsPage() {
|
|
|
178
177
|
className="p-2 bg-slate-800 border border-slate-700 rounded-lg text-slate-400 hover:bg-slate-700 hover:text-white transition-colors"
|
|
179
178
|
title="Copy logs"
|
|
180
179
|
>
|
|
181
|
-
<
|
|
180
|
+
<ClipboardDocumentIcon className="w-4 h-4" />
|
|
182
181
|
</button>
|
|
183
182
|
|
|
184
183
|
{/* Download */}
|
|
@@ -187,7 +186,7 @@ export default function LogsPage() {
|
|
|
187
186
|
className="p-2 bg-slate-800 border border-slate-700 rounded-lg text-slate-400 hover:bg-slate-700 hover:text-white transition-colors"
|
|
188
187
|
title="Download logs"
|
|
189
188
|
>
|
|
190
|
-
<
|
|
189
|
+
<ArrowDownTrayIcon className="w-4 h-4" />
|
|
191
190
|
</button>
|
|
192
191
|
|
|
193
192
|
{/* Clear */}
|
|
@@ -196,7 +195,7 @@ export default function LogsPage() {
|
|
|
196
195
|
className="p-2 bg-slate-800 border border-slate-700 rounded-lg text-slate-400 hover:bg-red-900/50 hover:text-red-400 hover:border-red-500/30 transition-colors"
|
|
197
196
|
title="Clear logs"
|
|
198
197
|
>
|
|
199
|
-
<
|
|
198
|
+
<TrashIcon className="w-4 h-4" />
|
|
200
199
|
</button>
|
|
201
200
|
</div>
|
|
202
201
|
</div>
|
|
@@ -226,11 +225,11 @@ export default function LogsPage() {
|
|
|
226
225
|
</div>
|
|
227
226
|
</div>
|
|
228
227
|
|
|
229
|
-
{/* Logs Container */}
|
|
230
|
-
<div className="flex-1 overflow-y-auto bg-black font-mono text-sm">
|
|
228
|
+
{/* Logs Container - Only this scrolls */}
|
|
229
|
+
<div ref={logsContainerRef} className="flex-1 overflow-y-auto bg-black font-mono text-sm">
|
|
231
230
|
{filteredLogs.length === 0 ? (
|
|
232
231
|
<div className="flex flex-col items-center justify-center h-full text-slate-600">
|
|
233
|
-
<
|
|
232
|
+
<CommandLineIcon className="w-16 h-16 mb-4 opacity-20" />
|
|
234
233
|
<p className="text-lg font-medium">No logs yet</p>
|
|
235
234
|
<p className="text-sm">Logs will appear here as they are generated</p>
|
|
236
235
|
</div>
|
|
@@ -257,7 +256,7 @@ export default function LogsPage() {
|
|
|
257
256
|
{/* Message */}
|
|
258
257
|
<div className="flex-1">
|
|
259
258
|
<p className="text-white break-words">{log.message}</p>
|
|
260
|
-
|
|
259
|
+
|
|
261
260
|
{/* Data (if present) */}
|
|
262
261
|
{log.data && (
|
|
263
262
|
<pre className="mt-2 p-3 bg-black/50 rounded border border-slate-800 overflow-x-auto">
|