nitrostack 1.0.75 → 1.0.77

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nitrostack",
3
- "version": "1.0.75",
3
+ "version": "1.0.77",
4
4
  "description": "NitroStack - Build powerful MCP servers with TypeScript",
5
5
  "type": "module",
6
6
  "main": "dist/core/index.js",
@@ -103,9 +103,9 @@ function OAuthCallback() {
103
103
  setStatus('success');
104
104
  setMessage('Authorization successful! Redirecting...');
105
105
 
106
- // Redirect back to auth page after 2 seconds
106
+ // Redirect back to settings auth tab after 2 seconds
107
107
  setTimeout(() => {
108
- router.push('/auth');
108
+ router.push('/settings?tab=auth');
109
109
  }, 2000);
110
110
  } else {
111
111
  setStatus('error');
@@ -147,10 +147,10 @@ function OAuthCallback() {
147
147
  <h1 className="text-2xl font-bold text-foreground mb-2">Authorization Failed</h1>
148
148
  <p className="text-muted-foreground mb-4">{message}</p>
149
149
  <button
150
- onClick={() => router.push('/auth')}
150
+ onClick={() => router.push('/settings?tab=auth')}
151
151
  className="btn btn-primary"
152
152
  >
153
- Back to Auth Page
153
+ Back to Settings
154
154
  </button>
155
155
  </>
156
156
  )}
@@ -0,0 +1,51 @@
1
+ 'use client';
2
+
3
+ import { useEffect } from 'react';
4
+ import { useRouter, useSearchParams } from 'next/navigation';
5
+ import { Suspense } from 'react';
6
+ import { ArrowPathIcon } from '@heroicons/react/24/outline';
7
+
8
+ function AuthRedirect() {
9
+ const router = useRouter();
10
+ const searchParams = useSearchParams();
11
+
12
+ useEffect(() => {
13
+ // Preserve any query parameters that might be relevant
14
+ const params = new URLSearchParams();
15
+ params.set('tab', 'auth');
16
+
17
+ // Forward any existing params (like success messages)
18
+ searchParams.forEach((value, key) => {
19
+ if (key !== 'tab') {
20
+ params.set(key, value);
21
+ }
22
+ });
23
+
24
+ router.replace(`/settings?${params.toString()}`);
25
+ }, [router, searchParams]);
26
+
27
+ return (
28
+ <div className="fixed inset-0 flex items-center justify-center bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
29
+ <div className="text-center">
30
+ <ArrowPathIcon className="w-8 h-8 text-primary animate-spin mx-auto mb-4" />
31
+ <p className="text-muted-foreground">Redirecting to authentication settings...</p>
32
+ </div>
33
+ </div>
34
+ );
35
+ }
36
+
37
+ export default function AuthPage() {
38
+ return (
39
+ <Suspense fallback={
40
+ <div className="fixed inset-0 flex items-center justify-center bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
41
+ <div className="text-center">
42
+ <ArrowPathIcon className="w-8 h-8 text-primary animate-spin mx-auto mb-4" />
43
+ <p className="text-muted-foreground">Loading...</p>
44
+ </div>
45
+ </div>
46
+ }>
47
+ <AuthRedirect />
48
+ </Suspense>
49
+ );
50
+ }
51
+
@@ -1,6 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { useState, useEffect } from 'react';
3
+ import { useState, useEffect, Suspense } from 'react';
4
+ import { useSearchParams } from 'next/navigation';
4
5
  import { api } from '@/lib/api';
5
6
  import { useStudioStore } from '@/lib/store';
6
7
  import {
@@ -23,7 +24,9 @@ import {
23
24
  ChatBubbleLeftIcon,
24
25
  } from '@heroicons/react/24/outline';
25
26
 
26
- export default function SettingsPage() {
27
+ function SettingsContent() {
28
+ const searchParams = useSearchParams();
29
+
27
30
  // Auth State
28
31
  const { oauthState, setOAuthState } = useStudioStore();
29
32
  const initialServerUrl =
@@ -236,7 +239,11 @@ export default function SettingsPage() {
236
239
  }
237
240
  };
238
241
 
239
- const [activeTab, setActiveTab] = useState<'general' | 'chat' | 'auth' | 'ping'>('general');
242
+ // Get initial tab from URL query param
243
+ const initialTab = searchParams.get('tab') as 'general' | 'chat' | 'auth' | 'ping' | null;
244
+ const [activeTab, setActiveTab] = useState<'general' | 'chat' | 'auth' | 'ping'>(
245
+ initialTab && ['general', 'chat', 'auth', 'ping'].includes(initialTab) ? initialTab : 'general'
246
+ );
240
247
  const [transport, setTransport] = useState<'stdio' | 'http'>('stdio');
241
248
  const {
242
249
  connection,
@@ -1153,3 +1160,18 @@ export default function SettingsPage() {
1153
1160
  </div>
1154
1161
  );
1155
1162
  }
1163
+
1164
+ export default function SettingsPage() {
1165
+ return (
1166
+ <Suspense fallback={
1167
+ <div className="fixed inset-0 flex items-center justify-center bg-background" style={{ left: 'var(--sidebar-width, 15rem)' }}>
1168
+ <div className="text-center">
1169
+ <SettingsIcon className="w-8 h-8 text-muted-foreground animate-pulse mx-auto mb-4" />
1170
+ <p className="text-muted-foreground">Loading settings...</p>
1171
+ </div>
1172
+ </div>
1173
+ }>
1174
+ <SettingsContent />
1175
+ </Suspense>
1176
+ );
1177
+ }
@@ -24,13 +24,15 @@ export function WidgetRenderer({ uri, data, className = '' }: WidgetRendererProp
24
24
 
25
25
  // Minimum height to prevent collapse
26
26
  const MIN_HEIGHT = 50;
27
+ // Maximum height to prevent infinite growth (widgets using 100vh can cause feedback loops)
28
+ const MAX_HEIGHT = 2000;
27
29
 
28
- // Stable handler for resize messages - no max height limit
30
+ // Stable handler for resize messages
29
31
  const handleResize = useCallback((height: number) => {
30
32
  if (!mountedRef.current) return;
31
33
  if (height && typeof height === 'number' && height > 0) {
32
- // Allow widget to be any height it needs
33
- const newHeight = Math.max(MIN_HEIGHT, height);
34
+ // Clamp height between min and max to prevent infinite growth
35
+ const newHeight = Math.min(MAX_HEIGHT, Math.max(MIN_HEIGHT, height));
34
36
  setContentHeight(newHeight);
35
37
  }
36
38
  }, []);
@@ -46,8 +46,6 @@ nitrostack init my-flight-app --template typescript-oauth
46
46
  cd my-flight-app
47
47
 
48
48
  # Install all dependencies (root + widgets)
49
- npm install
50
- # or
51
49
  nitrostack install
52
50
  ```
53
51
 
@@ -5,7 +5,6 @@
5
5
  "type": "module",
6
6
  "description": "NitroStack Flight Booking - Real-time flight search and booking with Duffel API integration",
7
7
  "scripts": {
8
- "postinstall": "nitrostack install --skip-widgets || true",
9
8
  "dev": "nitrostack dev",
10
9
  "build": "nitrostack build",
11
10
  "start": "npm run build && nitrostack start",
@@ -42,8 +42,6 @@ nitrostack init my-pizza-app --template typescript-pizzaz
42
42
  cd my-pizza-app
43
43
 
44
44
  # Install all dependencies (root + widgets)
45
- npm install
46
- # or
47
45
  nitrostack install
48
46
  ```
49
47
 
@@ -5,7 +5,6 @@
5
5
  "type": "module",
6
6
  "description": "NitroStack Pizza Shop Finder - Interactive map widgets with Mapbox integration",
7
7
  "scripts": {
8
- "postinstall": "nitrostack install --skip-widgets || true",
9
8
  "dev": "nitrostack dev",
10
9
  "build": "nitrostack build",
11
10
  "start": "npm run build && nitrostack start",
@@ -117,8 +117,8 @@ export default function PizzaListWidget() {
117
117
  return (
118
118
  <div style={{
119
119
  background: isDark ? '#0a0a0a' : '#f9fafb',
120
- minHeight: '100vh',
121
- maxHeight: maxHeight || '100vh',
120
+ minHeight: '400px',
121
+ maxHeight: maxHeight || '600px',
122
122
  overflow: 'auto',
123
123
  }}>
124
124
  {/* Header */}
@@ -71,8 +71,8 @@ export default function PizzaShopWidget() {
71
71
  return (
72
72
  <div style={{
73
73
  background: isDark ? '#0a0a0a' : '#f9fafb',
74
- minHeight: '100vh',
75
- maxHeight: maxHeight || '100vh',
74
+ minHeight: '500px',
75
+ maxHeight: maxHeight || '800px',
76
76
  overflow: 'auto',
77
77
  }}>
78
78
  {/* Hero Image */}
@@ -34,8 +34,6 @@ nitrostack init my-calculator --template typescript-starter
34
34
  cd my-calculator
35
35
 
36
36
  # Install all dependencies (root + widgets)
37
- npm install
38
- # or
39
37
  nitrostack install
40
38
  ```
41
39
 
@@ -5,7 +5,6 @@
5
5
  "type": "module",
6
6
  "description": "NitroStack starter template - Learn MCP server basics with a simple calculator example",
7
7
  "scripts": {
8
- "postinstall": "nitrostack install --skip-widgets || true",
9
8
  "dev": "nitrostack dev",
10
9
  "build": "nitrostack build",
11
10
  "start": "npm run build && nitrostack start",
@@ -114,7 +114,7 @@ export class CalculatorTools {
114
114
  fs.writeFileSync(filePath, buffer);
115
115
  ctx.logger.info(`Saved file to ${filePath}`);
116
116
  } catch (e) {
117
- ctx.logger.error('Failed to save file', e);
117
+ ctx.logger.error('Failed to save file', { error: e instanceof Error ? e.message : String(e) });
118
118
  }
119
119
  }
120
120