dev3000 0.0.101 → 0.0.102
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/README.md +2 -0
- package/dist/dev-environment.d.ts +1 -0
- package/dist/dev-environment.d.ts.map +1 -1
- package/dist/dev-environment.js +52 -8
- package/dist/dev-environment.js.map +1 -1
- package/dist/screencast-manager.d.ts.map +1 -1
- package/dist/screencast-manager.js +3 -4
- package/dist/screencast-manager.js.map +1 -1
- package/dist/src/tui-interface-impl.tsx +7 -1
- package/dist/tui-interface-impl.d.ts.map +1 -1
- package/dist/tui-interface-impl.js +4 -1
- package/dist/tui-interface-impl.js.map +1 -1
- package/mcp-server/.next/BUILD_ID +1 -1
- package/mcp-server/.next/build-manifest.json +2 -2
- package/mcp-server/.next/fallback-build-manifest.json +2 -2
- package/mcp-server/.next/prerender-manifest.json +3 -3
- package/mcp-server/.next/server/app/_global-error.html +2 -2
- package/mcp-server/.next/server/app/_global-error.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.html +1 -1
- package/mcp-server/.next/server/app/_not-found.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/mcp-server/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.html +1 -1
- package/mcp-server/.next/server/app/index.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/mcp-server/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__0691849a._.js +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__0691849a._.js.map +1 -1
- package/mcp-server/.next/server/chunks/[root-of-the-server]__ae49815f._.js +35 -8
- package/mcp-server/.next/server/chunks/[root-of-the-server]__ae49815f._.js.map +1 -1
- package/mcp-server/.next/server/server-reference-manifest.js +1 -1
- package/mcp-server/.next/server/server-reference-manifest.json +1 -1
- package/mcp-server/app/mcp/route.ts +26 -1
- package/mcp-server/app/mcp/tools.ts +188 -1
- package/package.json +2 -1
- package/src/tui-interface-impl.tsx +7 -1
- /package/mcp-server/.next/static/{eVcHKbTsqk-_vUXyVOoaO → 4DzBVkDIn_yRVz53mYMf8}/_buildManifest.js +0 -0
- /package/mcp-server/.next/static/{eVcHKbTsqk-_vUXyVOoaO → 4DzBVkDIn_yRVz53mYMf8}/_clientMiddlewareManifest.json +0 -0
- /package/mcp-server/.next/static/{eVcHKbTsqk-_vUXyVOoaO → 4DzBVkDIn_yRVz53mYMf8}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"
|
|
1
|
+
self.__RSC_SERVER_MANIFEST="{\n \"node\": {},\n \"edge\": {},\n \"encryptionKey\": \"J2fGjU4v1SMY6g5pu3U2aY0GeU26Wipdet5Y3MnFxRU=\"\n}"
|
|
@@ -5,7 +5,14 @@ import type { Tool } from "@modelcontextprotocol/sdk/types.js"
|
|
|
5
5
|
import { createMcpHandler } from "mcp-handler"
|
|
6
6
|
import { z } from "zod"
|
|
7
7
|
import { getMCPClientManager } from "./client-manager"
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
crawlApp,
|
|
10
|
+
executeBrowserAction,
|
|
11
|
+
findComponentSource,
|
|
12
|
+
fixMyApp,
|
|
13
|
+
restartDevServer,
|
|
14
|
+
TOOL_DESCRIPTIONS
|
|
15
|
+
} from "./tools"
|
|
9
16
|
|
|
10
17
|
// Detect available package runner (bunx, npx, pnpm dlx, or fail)
|
|
11
18
|
const getPackageRunner = (): { command: string; args: string[] } | null => {
|
|
@@ -502,6 +509,24 @@ const handler = createMcpHandler(
|
|
|
502
509
|
}
|
|
503
510
|
)
|
|
504
511
|
|
|
512
|
+
// App crawler tool
|
|
513
|
+
server.tool(
|
|
514
|
+
"crawl_app",
|
|
515
|
+
TOOL_DESCRIPTIONS.crawl_app,
|
|
516
|
+
{
|
|
517
|
+
depth: z
|
|
518
|
+
.union([z.number().int().min(1), z.literal("all")])
|
|
519
|
+
.optional()
|
|
520
|
+
.describe(
|
|
521
|
+
"Crawl depth: number (1=homepage only, 2=homepage+next level, etc.) or 'all' for exhaustive (default: 1)"
|
|
522
|
+
),
|
|
523
|
+
projectName: z.string().optional().describe("Project name (if multiple dev3000 instances are running)")
|
|
524
|
+
},
|
|
525
|
+
async (params) => {
|
|
526
|
+
return crawlApp(params)
|
|
527
|
+
}
|
|
528
|
+
)
|
|
529
|
+
|
|
505
530
|
// Tool that returns monitoring code for Claude to execute
|
|
506
531
|
// TODO: Commenting out for now - need to figure out the right approach for proactive monitoring
|
|
507
532
|
/*
|
|
@@ -24,7 +24,10 @@ export const TOOL_DESCRIPTIONS = {
|
|
|
24
24
|
"🔍 **COMPONENT SOURCE FINDER** - Maps DOM elements to their source code by extracting the React component function and finding unique patterns to search for.\n\n🎯 **HOW IT WORKS:**\n• Inspects the element via Chrome DevTools Protocol\n• Extracts the React component function source using .toString()\n• Identifies unique code patterns (specific JSX, classNames, imports)\n• Returns targeted grep patterns to find the exact source file\n\n💡 **PERFECT FOR:** Finding which file contains the code for a specific element, especially useful for CLS debugging when you need to fix layout shifts in specific components.",
|
|
25
25
|
|
|
26
26
|
restart_dev_server:
|
|
27
|
-
"🔄 **DEV SERVER RESTART** - Safely restarts the development server while preserving dev3000's monitoring, logs, and browser connection.\n\n🎯 **SMART RESTART LOGIC:**\n• First tries nextjs-dev MCP restart (if available and user has Next.js canary)\n• Falls back to dev3000's own restart mechanism:\n - Kills the old server process on the app port\n - Waits for clean shutdown\n - Spawns a new server with the same command that was originally used\n - Keeps dev3000's MCP server, browser monitoring, and screenshot capture running\n• All logging continues seamlessly - no data loss\n• Browser monitoring stays connected - no need to relaunch Chrome\n\n⚡ **WHEN TO USE:**\n• After modifying next.config.js, middleware, or environment variables\n• When you need a clean restart to clear server state\n• After significant code changes that Next.js HMR can't handle\n• When debugging persistent state or memory issues\n\n⚠️ **CRITICAL - DO NOT:**\n• ❌ NEVER manually run kill commands on the dev server like `pkill -f \"next dev\"` or `lsof -ti :3000 | xargs kill`\n• ❌ NEVER manually start the dev server with `npm run dev`, `pnpm dev`, `next dev`, etc.\n• ✅ ALWAYS use this tool for dev server restarts - it preserves all dev3000 infrastructure\n\n⚠️ **IMPORTANT:**\n• AVOID using this unnecessarily - Next.js HMR handles most changes automatically\n• Only restart when truly needed for config changes or state issues\n• The server will be offline for a few seconds during restart\n• Browser may show connection error briefly while server restarts\n\n💡 **PERFECT FOR:** 'restart the dev server', 'clean restart', 'reload the server' - but only when actually needed, not for regular code changes."
|
|
27
|
+
"🔄 **DEV SERVER RESTART** - Safely restarts the development server while preserving dev3000's monitoring, logs, and browser connection.\n\n🎯 **SMART RESTART LOGIC:**\n• First tries nextjs-dev MCP restart (if available and user has Next.js canary)\n• Falls back to dev3000's own restart mechanism:\n - Kills the old server process on the app port\n - Waits for clean shutdown\n - Spawns a new server with the same command that was originally used\n - Keeps dev3000's MCP server, browser monitoring, and screenshot capture running\n• All logging continues seamlessly - no data loss\n• Browser monitoring stays connected - no need to relaunch Chrome\n\n⚡ **WHEN TO USE:**\n• After modifying next.config.js, middleware, or environment variables\n• When you need a clean restart to clear server state\n• After significant code changes that Next.js HMR can't handle\n• When debugging persistent state or memory issues\n\n⚠️ **CRITICAL - DO NOT:**\n• ❌ NEVER manually run kill commands on the dev server like `pkill -f \"next dev\"` or `lsof -ti :3000 | xargs kill`\n• ❌ NEVER manually start the dev server with `npm run dev`, `pnpm dev`, `next dev`, etc.\n• ✅ ALWAYS use this tool for dev server restarts - it preserves all dev3000 infrastructure\n\n⚠️ **IMPORTANT:**\n• AVOID using this unnecessarily - Next.js HMR handles most changes automatically\n• Only restart when truly needed for config changes or state issues\n• The server will be offline for a few seconds during restart\n• Browser may show connection error briefly while server restarts\n\n💡 **PERFECT FOR:** 'restart the dev server', 'clean restart', 'reload the server' - but only when actually needed, not for regular code changes.",
|
|
28
|
+
|
|
29
|
+
crawl_app:
|
|
30
|
+
"🕷️ **APP CRAWLER** - Discovers all URLs in your app by crawling links starting from the homepage. Perfect for finding every page before running fixes or tests across your entire site.\n\n🎯 **SMART CRAWLING:**\n• Starts at your app's homepage (localhost)\n• Discovers all unique URLs at specified depth\n• Depth 1 = homepage links only\n• Depth 2 = homepage + links from those pages\n• Depth 'all' = exhaustive crawl until no new links found\n• Only follows same-origin links (stays within your app)\n• Deduplicates URLs automatically\n\n📊 **OUTPUT:**\n• List of all discovered URLs\n• Total count of unique pages\n• Depth reached\n• Ready to use with fix_my_app or other tools\n\n💡 **PERFECT FOR:**\n• 'crawl my app' or 'crawl my shit' - discover all pages\n• 'crawl my app and fix my shit' - find all pages then run fixes\n• Site-wide testing and debugging\n• Verifying all routes work before deployment\n\n⚡ **USAGE:**\n• Default: depth 1 (just homepage links)\n• Specify depth: 'crawl at depth 2' or depth=2\n• Full crawl: 'crawl all pages' or depth='all'"
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
// Types
|
|
@@ -3606,3 +3609,187 @@ export async function restartDevServer(params: {
|
|
|
3606
3609
|
}
|
|
3607
3610
|
}
|
|
3608
3611
|
}
|
|
3612
|
+
|
|
3613
|
+
// Crawl app - discover all URLs
|
|
3614
|
+
export interface CrawlAppParams {
|
|
3615
|
+
depth?: number | "all"
|
|
3616
|
+
projectName?: string
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
export async function crawlApp(params: CrawlAppParams) {
|
|
3620
|
+
const { depth = 1, projectName } = params
|
|
3621
|
+
|
|
3622
|
+
try {
|
|
3623
|
+
// Find active session
|
|
3624
|
+
const sessions = findActiveSessions()
|
|
3625
|
+
const session = projectName ? sessions.find((s) => s.projectName === projectName) : sessions[0]
|
|
3626
|
+
|
|
3627
|
+
if (!session) {
|
|
3628
|
+
return {
|
|
3629
|
+
content: [
|
|
3630
|
+
{
|
|
3631
|
+
type: "text" as const,
|
|
3632
|
+
text: projectName
|
|
3633
|
+
? `❌ No active session found for project "${projectName}". Available projects: ${sessions.map((s) => s.projectName).join(", ") || "none"}`
|
|
3634
|
+
: "❌ No active dev3000 sessions found. Start dev3000 first with `d3k` in your project directory."
|
|
3635
|
+
}
|
|
3636
|
+
]
|
|
3637
|
+
}
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
// Get CDP URL and app port from session
|
|
3641
|
+
const sessionData = JSON.parse(readFileSync(session.sessionFile, "utf-8"))
|
|
3642
|
+
const cdpUrl = sessionData.cdpUrl?.replace("http://", "ws://")
|
|
3643
|
+
const appPort = sessionData.appPort || "3000"
|
|
3644
|
+
const baseUrl = `http://localhost:${appPort}`
|
|
3645
|
+
|
|
3646
|
+
if (!cdpUrl) {
|
|
3647
|
+
return {
|
|
3648
|
+
content: [
|
|
3649
|
+
{
|
|
3650
|
+
type: "text" as const,
|
|
3651
|
+
text: "❌ No Chrome DevTools connection found. Browser monitoring must be active to crawl."
|
|
3652
|
+
}
|
|
3653
|
+
]
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
logToDevFile(`Crawl App: Starting crawl at depth ${depth} for ${baseUrl}`)
|
|
3658
|
+
|
|
3659
|
+
// Connect to CDP
|
|
3660
|
+
const ws = new WebSocket(cdpUrl)
|
|
3661
|
+
await new Promise((resolve, reject) => {
|
|
3662
|
+
ws.on("open", resolve)
|
|
3663
|
+
ws.on("error", reject)
|
|
3664
|
+
setTimeout(() => reject(new Error("CDP connection timeout")), 5000)
|
|
3665
|
+
})
|
|
3666
|
+
|
|
3667
|
+
let messageId = 2000
|
|
3668
|
+
// biome-ignore lint/suspicious/noExplicitAny: CDP protocol responses are dynamic
|
|
3669
|
+
const sendCommand = (method: string, params: Record<string, unknown> = {}): Promise<any> => {
|
|
3670
|
+
return new Promise((resolve, reject) => {
|
|
3671
|
+
const id = messageId++
|
|
3672
|
+
const message = JSON.stringify({ id, method, params })
|
|
3673
|
+
|
|
3674
|
+
const handler = (data: Buffer) => {
|
|
3675
|
+
const response = JSON.parse(data.toString())
|
|
3676
|
+
if (response.id === id) {
|
|
3677
|
+
ws.off("message", handler)
|
|
3678
|
+
if (response.error) {
|
|
3679
|
+
reject(new Error(response.error.message))
|
|
3680
|
+
} else {
|
|
3681
|
+
resolve(response.result)
|
|
3682
|
+
}
|
|
3683
|
+
}
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3686
|
+
ws.on("message", handler)
|
|
3687
|
+
ws.send(message)
|
|
3688
|
+
|
|
3689
|
+
setTimeout(() => {
|
|
3690
|
+
ws.off("message", handler)
|
|
3691
|
+
reject(new Error("Command timeout"))
|
|
3692
|
+
}, 10000)
|
|
3693
|
+
})
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
// Enable necessary domains
|
|
3697
|
+
await sendCommand("Runtime.enable")
|
|
3698
|
+
await sendCommand("Page.enable")
|
|
3699
|
+
|
|
3700
|
+
// Discovered URLs
|
|
3701
|
+
const discovered = new Set<string>([baseUrl])
|
|
3702
|
+
const visited = new Set<string>()
|
|
3703
|
+
const toVisit: string[] = [baseUrl]
|
|
3704
|
+
|
|
3705
|
+
let currentDepth = 0
|
|
3706
|
+
const maxDepth = depth === "all" ? Number.POSITIVE_INFINITY : depth
|
|
3707
|
+
|
|
3708
|
+
while (toVisit.length > 0 && currentDepth <= maxDepth) {
|
|
3709
|
+
const currentLevelUrls = [...toVisit]
|
|
3710
|
+
toVisit.length = 0
|
|
3711
|
+
|
|
3712
|
+
logToDevFile(`Crawl App: Processing depth ${currentDepth} with ${currentLevelUrls.length} URLs`)
|
|
3713
|
+
|
|
3714
|
+
for (const url of currentLevelUrls) {
|
|
3715
|
+
if (visited.has(url)) continue
|
|
3716
|
+
visited.add(url)
|
|
3717
|
+
|
|
3718
|
+
try {
|
|
3719
|
+
// Navigate to URL
|
|
3720
|
+
logToDevFile(`Crawl App: Visiting ${url}`)
|
|
3721
|
+
await sendCommand("Page.navigate", { url })
|
|
3722
|
+
|
|
3723
|
+
// Wait for page load
|
|
3724
|
+
await new Promise((resolve) => setTimeout(resolve, 2000))
|
|
3725
|
+
|
|
3726
|
+
// Extract all links
|
|
3727
|
+
const result = await sendCommand("Runtime.evaluate", {
|
|
3728
|
+
expression: `
|
|
3729
|
+
Array.from(document.querySelectorAll('a[href]')).map(a => {
|
|
3730
|
+
try {
|
|
3731
|
+
const url = new URL(a.href, window.location.href);
|
|
3732
|
+
// Only return same-origin links
|
|
3733
|
+
if (url.origin === window.location.origin) {
|
|
3734
|
+
// Remove hash and query params for deduplication
|
|
3735
|
+
return url.origin + url.pathname;
|
|
3736
|
+
}
|
|
3737
|
+
} catch {}
|
|
3738
|
+
return null;
|
|
3739
|
+
}).filter(Boolean)
|
|
3740
|
+
`,
|
|
3741
|
+
returnByValue: true
|
|
3742
|
+
})
|
|
3743
|
+
|
|
3744
|
+
const links = result.result?.value || []
|
|
3745
|
+
|
|
3746
|
+
for (const link of links) {
|
|
3747
|
+
if (!discovered.has(link)) {
|
|
3748
|
+
discovered.add(link)
|
|
3749
|
+
if (currentDepth < maxDepth) {
|
|
3750
|
+
toVisit.push(link)
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
logToDevFile(`Crawl App: Found ${links.length} links on ${url}`)
|
|
3756
|
+
} catch (error) {
|
|
3757
|
+
logToDevFile(`Crawl App: Error visiting ${url} - ${error}`)
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
|
|
3761
|
+
currentDepth++
|
|
3762
|
+
|
|
3763
|
+
// For "all" mode, stop when no new URLs are found
|
|
3764
|
+
if (depth === "all" && toVisit.length === 0) {
|
|
3765
|
+
break
|
|
3766
|
+
}
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3769
|
+
ws.close()
|
|
3770
|
+
|
|
3771
|
+
const urls = Array.from(discovered).sort()
|
|
3772
|
+
const depthReached = depth === "all" ? currentDepth - 1 : Math.min(currentDepth - 1, maxDepth)
|
|
3773
|
+
|
|
3774
|
+
logToDevFile(`Crawl App: Complete - discovered ${urls.length} URLs at depth ${depthReached}`)
|
|
3775
|
+
|
|
3776
|
+
return {
|
|
3777
|
+
content: [
|
|
3778
|
+
{
|
|
3779
|
+
type: "text" as const,
|
|
3780
|
+
text: `🕷️ **APP CRAWL COMPLETE**\n\n📊 **SUMMARY:**\n• Base URL: ${baseUrl}\n• Depth: ${depthReached}${depth === "all" ? " (exhaustive)" : ""}\n• Total URLs: ${urls.length}\n\n📍 **DISCOVERED URLs:**\n${urls.map((url) => `• ${url}`).join("\n")}\n\n💡 **NEXT STEPS:**\n• Use fix_my_app to check for errors across all pages\n• Use execute_browser_action to test specific pages\n• Verify all routes are working correctly`
|
|
3781
|
+
}
|
|
3782
|
+
]
|
|
3783
|
+
}
|
|
3784
|
+
} catch (error) {
|
|
3785
|
+
logToDevFile(`Crawl App: Error - ${error}`)
|
|
3786
|
+
return {
|
|
3787
|
+
content: [
|
|
3788
|
+
{
|
|
3789
|
+
type: "text" as const,
|
|
3790
|
+
text: `❌ **CRAWL FAILED**\n\n${error instanceof Error ? error.message : String(error)}`
|
|
3791
|
+
}
|
|
3792
|
+
]
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev3000",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.102",
|
|
4
4
|
"description": "AI-powered development tools with browser monitoring and MCP server integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"chalk": "^5.3.0",
|
|
64
64
|
"commander": "^14.0.1",
|
|
65
65
|
"ink": "^6.3.1",
|
|
66
|
+
"ink-spinner": "^5.0.0",
|
|
66
67
|
"next": "16.0.0-canary.18",
|
|
67
68
|
"ora": "^9.0.0",
|
|
68
69
|
"package-manager-detector": "^1.3.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk"
|
|
2
2
|
import { createReadStream, unwatchFile, watchFile } from "fs"
|
|
3
3
|
import { Box, render, Text, useInput, useStdout } from "ink"
|
|
4
|
+
import Spinner from "ink-spinner"
|
|
4
5
|
import { useEffect, useRef, useState } from "react"
|
|
5
6
|
import type { Readable } from "stream"
|
|
6
7
|
import { LOG_COLORS } from "./constants/log-colors.js"
|
|
@@ -46,6 +47,7 @@ const TUIApp = ({
|
|
|
46
47
|
const [scrollOffset, setScrollOffset] = useState(0)
|
|
47
48
|
const [initStatus, setInitStatus] = useState<string | null>("Initializing...")
|
|
48
49
|
const [appPort, setAppPort] = useState<string>(initialAppPort)
|
|
50
|
+
const [portConfirmed, setPortConfirmed] = useState<boolean>(false)
|
|
49
51
|
const logIdCounter = useRef(0)
|
|
50
52
|
const [clearFromLogId, setClearFromLogId] = useState<number>(0) // Track log ID to clear from
|
|
51
53
|
const { stdout } = useStdout()
|
|
@@ -112,6 +114,7 @@ const TUIApp = ({
|
|
|
112
114
|
useEffect(() => {
|
|
113
115
|
onAppPortUpdate((port: string) => {
|
|
114
116
|
setAppPort(port)
|
|
117
|
+
setPortConfirmed(true)
|
|
115
118
|
})
|
|
116
119
|
}, [onAppPortUpdate])
|
|
117
120
|
|
|
@@ -332,7 +335,10 @@ const TUIApp = ({
|
|
|
332
335
|
|
|
333
336
|
{/* Info on the right */}
|
|
334
337
|
<Box flexDirection="column" flexGrow={1}>
|
|
335
|
-
<
|
|
338
|
+
<Box>
|
|
339
|
+
<Text color="cyan">🌐 App: http://localhost:{appPort} </Text>
|
|
340
|
+
{!portConfirmed && <Spinner type="dots" />}
|
|
341
|
+
</Box>
|
|
336
342
|
<Text color="cyan">🤖 MCP: http://localhost:{mcpPort}</Text>
|
|
337
343
|
<Text color="cyan">
|
|
338
344
|
📸 Logs: http://localhost:{mcpPort}/logs
|
/package/mcp-server/.next/static/{eVcHKbTsqk-_vUXyVOoaO → 4DzBVkDIn_yRVz53mYMf8}/_buildManifest.js
RENAMED
|
File without changes
|
|
File without changes
|
/package/mcp-server/.next/static/{eVcHKbTsqk-_vUXyVOoaO → 4DzBVkDIn_yRVz53mYMf8}/_ssgManifest.js
RENAMED
|
File without changes
|