nitrostack 1.0.65 → 1.0.67

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 (61) hide show
  1. package/package.json +3 -2
  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
  56. package/templates/typescript-oauth/AI_AGENT_CLI_REFERENCE.md +0 -701
  57. package/templates/typescript-oauth/AI_AGENT_SDK_REFERENCE.md +0 -1260
  58. package/templates/typescript-oauth/package-lock.json +0 -4253
  59. package/templates/typescript-pizzaz/IMPLEMENTATION.md +0 -98
  60. package/templates/typescript-starter/AI_AGENT_CLI_REFERENCE.md +0 -701
  61. package/templates/typescript-starter/AI_AGENT_SDK_REFERENCE.md +0 -1260
@@ -0,0 +1,90 @@
1
+ // Widget Loader - Handles dev/prod widget loading
2
+
3
+ export function getWidgetUrl(uri: string): string {
4
+ // Check if we're in dev mode (widget dev server on 3001)
5
+ const isDevMode =
6
+ typeof window !== 'undefined' &&
7
+ (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');
8
+
9
+ if (isDevMode && uri.startsWith('/widgets/')) {
10
+ // Dev mode: load from Next.js dev server
11
+ const widgetPath = uri.replace('/widgets/', '');
12
+ return `http://localhost:3001/${widgetPath}`;
13
+ }
14
+
15
+ // Production mode: load from same origin
16
+ return uri;
17
+ }
18
+
19
+ export function isDevWidget(uri: string): boolean {
20
+ return uri.startsWith('/widgets/') || uri.includes('component://');
21
+ }
22
+
23
+ export async function loadWidget(uri: string): Promise<{ html: string; isDevMode: boolean }> {
24
+ const isDevMode =
25
+ typeof window !== 'undefined' &&
26
+ (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');
27
+
28
+ if (isDevMode && uri.startsWith('/widgets/')) {
29
+ // Dev mode: return URL for iframe
30
+ return { html: getWidgetUrl(uri), isDevMode: true };
31
+ }
32
+
33
+ // Production mode: fetch widget HTML
34
+ try {
35
+ const response = await fetch(`/api/resources/${encodeURIComponent(uri)}`);
36
+ const data = await response.json();
37
+
38
+ if (data.contents && data.contents.length > 0) {
39
+ return { html: data.contents[0].text || '', isDevMode: false };
40
+ }
41
+
42
+ return { html: '', isDevMode: false };
43
+ } catch (error) {
44
+ console.error('Failed to load widget:', error);
45
+ return { html: '', isDevMode: false };
46
+ }
47
+ }
48
+
49
+ export function createWidgetHTML(html: string, data: any): string {
50
+ const htmlParts = [
51
+ '<!DOCTYPE html>',
52
+ '<html>',
53
+ '<head>',
54
+ '<meta charset="UTF-8">',
55
+ '<meta name="viewport" content="width=device-width, initial-scale=1.0">',
56
+ '<style>',
57
+ 'html, body { margin: 0; padding: 0; background: transparent; }',
58
+ 'body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }',
59
+ '</style>',
60
+ '</head>',
61
+ '<body>',
62
+ '<script>',
63
+ 'window.openai = ' + JSON.stringify({ toolOutput: data }) + ';',
64
+ '</script>',
65
+ html,
66
+ '</body>',
67
+ '</html>',
68
+ ];
69
+
70
+ return htmlParts.join('\n');
71
+ }
72
+
73
+ export function postMessageToWidget(iframe: HTMLIFrameElement, data: any, delay: number = 500) {
74
+ iframe.onload = () => {
75
+ setTimeout(() => {
76
+ try {
77
+ iframe.contentWindow?.postMessage(
78
+ {
79
+ type: 'toolOutput',
80
+ data,
81
+ },
82
+ '*'
83
+ );
84
+ } catch (e) {
85
+ console.error('Failed to post message to widget:', e);
86
+ }
87
+ }, delay);
88
+ };
89
+ }
90
+
@@ -0,0 +1,27 @@
1
+ // Studio Middleware - Widget Proxying
2
+ import { NextResponse } from 'next/server';
3
+ import type { NextRequest } from 'next/server';
4
+
5
+ export function middleware(request: NextRequest) {
6
+ const { pathname } = request.nextUrl;
7
+
8
+ // In development, proxy widget requests to the widget dev server
9
+ if (process.env.NODE_ENV === 'development' && process.env.WIDGETS_DEV_MODE === 'true') {
10
+ const widgetsDevPort = process.env.WIDGETS_DEV_PORT || '3001';
11
+
12
+ // Proxy /widgets/* to widget dev server
13
+ if (pathname.startsWith('/widgets/')) {
14
+ const widgetPath = pathname.replace('/widgets/', '');
15
+ const targetUrl = `http://localhost:${widgetsDevPort}/${widgetPath}`;
16
+
17
+ return NextResponse.rewrite(new URL(targetUrl));
18
+ }
19
+ }
20
+
21
+ return NextResponse.next();
22
+ }
23
+
24
+ export const config = {
25
+ matcher: ['/widgets/:path*'],
26
+ };
27
+
@@ -0,0 +1,38 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+ import { createRequire } from 'module';
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const require = createRequire(import.meta.url);
8
+
9
+ /** @type {import('next').NextConfig} */
10
+ const nextConfig = {
11
+ images: {
12
+ unoptimized: true,
13
+ },
14
+ typescript: {
15
+ ignoreBuildErrors: true,
16
+ },
17
+ eslint: {
18
+ ignoreDuringBuilds: true,
19
+ },
20
+ // Ensure Next transpiles our package when it's nested under node_modules
21
+ transpilePackages: ['nitrostack'],
22
+ webpack: (config) => {
23
+ // Provide @ alias so imports like '@/lib/store' work reliably
24
+ config.resolve.alias = {
25
+ ...config.resolve.alias,
26
+ '@': __dirname,
27
+ };
28
+ // Do NOT inject custom TS rules; rely on Next's defaults + transpilePackages
29
+ return config;
30
+ },
31
+ env: {
32
+ MCP_SERVER_PORT: process.env.MCP_SERVER_PORT,
33
+ MCP_TRANSPORT_TYPE: process.env.MCP_TRANSPORT_TYPE,
34
+ },
35
+ };
36
+
37
+ export default nextConfig;
38
+
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@nitrostack/studio",
3
+ "version": "3.1.0",
4
+ "description": "NitroStack Studio - Visual MCP Server Inspector",
5
+ "private": true,
6
+ "type": "module",
7
+ "scripts": {
8
+ "dev": "next dev -p 3000",
9
+ "build": "next build",
10
+ "start": "next start",
11
+ "lint": "next lint",
12
+ "export": "next build && next export"
13
+ },
14
+ "dependencies": {
15
+ "@fontsource/inter": "^5.2.8",
16
+ "@fontsource/jetbrains-mono": "^5.2.8",
17
+ "@modelcontextprotocol/sdk": "^1.0.4",
18
+ "clsx": "^2.1.0",
19
+ "eventsource": "^2.0.2",
20
+ "lucide-react": "^0.546.0",
21
+ "next": "^14.2.5",
22
+ "react": "^18.3.1",
23
+ "react-dom": "^18.3.1",
24
+ "zustand": "^4.5.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^22.10.5",
28
+ "@types/react": "^18.3.3",
29
+ "@types/react-dom": "^18.3.0",
30
+ "autoprefixer": "^10.4.19",
31
+ "postcss": "^8.4.38",
32
+ "tailwindcss": "^3.4.4",
33
+ "typescript": "^5.3.3"
34
+ }
35
+ }
@@ -0,0 +1,10 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ tailwindcss: {},
5
+ autoprefixer: {},
6
+ },
7
+ };
8
+
9
+ export default config;
10
+
Binary file
@@ -0,0 +1,67 @@
1
+ import type { Config } from 'tailwindcss';
2
+
3
+ const config: Config = {
4
+ darkMode: 'class',
5
+ content: [
6
+ './pages/**/*.{js,ts,jsx,tsx,mdx}',
7
+ './components/**/*.{js,ts,jsx,tsx,mdx}',
8
+ './app/**/*.{js,ts,jsx,tsx,mdx}',
9
+ ],
10
+ theme: {
11
+ extend: {
12
+ colors: {
13
+ // Brand colors - Gold & Black
14
+ primary: {
15
+ DEFAULT: '#d4af37', // Gold
16
+ 50: '#fdfcf8',
17
+ 100: '#f9f7ed',
18
+ 200: '#f2ecd3',
19
+ 300: '#ead9a1',
20
+ 400: '#e2c870',
21
+ 500: '#d4af37', // Main gold
22
+ 600: '#b8962b',
23
+ 700: '#967824',
24
+ 800: '#7a6020',
25
+ 900: '#654f1d',
26
+ },
27
+ background: 'hsl(var(--background))',
28
+ foreground: 'hsl(var(--foreground))',
29
+ card: {
30
+ DEFAULT: 'hsl(var(--card))',
31
+ foreground: 'hsl(var(--card-foreground))',
32
+ },
33
+ popover: {
34
+ DEFAULT: 'hsl(var(--popover))',
35
+ foreground: 'hsl(var(--popover-foreground))',
36
+ },
37
+ secondary: {
38
+ DEFAULT: 'hsl(var(--secondary))',
39
+ foreground: 'hsl(var(--secondary-foreground))',
40
+ },
41
+ muted: {
42
+ DEFAULT: 'hsl(var(--muted))',
43
+ foreground: 'hsl(var(--muted-foreground))',
44
+ },
45
+ accent: {
46
+ DEFAULT: 'hsl(var(--accent))',
47
+ foreground: 'hsl(var(--accent-foreground))',
48
+ },
49
+ destructive: {
50
+ DEFAULT: 'hsl(var(--destructive))',
51
+ foreground: 'hsl(var(--destructive-foreground))',
52
+ },
53
+ border: 'hsl(var(--border))',
54
+ input: 'hsl(var(--input))',
55
+ ring: 'hsl(var(--ring))',
56
+ },
57
+ borderRadius: {
58
+ lg: 'var(--radius)',
59
+ md: 'calc(var(--radius) - 2px)',
60
+ sm: 'calc(var(--radius) - 4px)',
61
+ },
62
+ },
63
+ },
64
+ plugins: [],
65
+ };
66
+
67
+ export default config;
@@ -0,0 +1,42 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "strict": true,
12
+ "noEmit": true,
13
+ "esModuleInterop": true,
14
+ "module": "esnext",
15
+ "moduleResolution": "node",
16
+ "resolveJsonModule": true,
17
+ "isolatedModules": true,
18
+ "jsx": "preserve",
19
+ "incremental": true,
20
+ "plugins": [
21
+ {
22
+ "name": "next"
23
+ }
24
+ ],
25
+ "paths": {
26
+ "@/*": [
27
+ "./*"
28
+ ]
29
+ },
30
+ "baseUrl": "."
31
+ },
32
+ "include": [
33
+ "next-env.d.ts",
34
+ "**/*.ts",
35
+ "**/*.tsx",
36
+ ".next/types/**/*.ts",
37
+ "../../dist/studio/types/**/*.ts"
38
+ ],
39
+ "exclude": [
40
+ "node_modules"
41
+ ]
42
+ }