@_davideast/stitch-mcp 0.5.1 → 0.5.2

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 (56) hide show
  1. package/dist/chunk-1fbzpreg.js +137 -0
  2. package/dist/chunk-1fbzpreg.js.map +10 -0
  3. package/dist/chunk-4zqw9exz.js +370 -0
  4. package/dist/chunk-4zqw9exz.js.map +16 -0
  5. package/dist/chunk-9g1t32qk.js +273 -0
  6. package/dist/chunk-9g1t32qk.js.map +10 -0
  7. package/dist/chunk-aa5ptn4s.js +768 -0
  8. package/dist/chunk-aa5ptn4s.js.map +18 -0
  9. package/dist/chunk-b9nzx4rf.js +19 -0
  10. package/dist/chunk-b9nzx4rf.js.map +9 -0
  11. package/dist/chunk-c87d10w8.js +109 -0
  12. package/dist/chunk-c87d10w8.js.map +10 -0
  13. package/dist/chunk-d0ffvq20.js +19 -0
  14. package/dist/chunk-d0ffvq20.js.map +9 -0
  15. package/dist/chunk-d8nttd6z.js +683 -0
  16. package/dist/chunk-d8nttd6z.js.map +17 -0
  17. package/dist/chunk-e4q3v109.js +31464 -0
  18. package/dist/chunk-e4q3v109.js.map +245 -0
  19. package/dist/chunk-etcps0m5.js +1495 -0
  20. package/dist/chunk-etcps0m5.js.map +23 -0
  21. package/dist/chunk-f89ve6pt.js +256 -0
  22. package/dist/chunk-f89ve6pt.js.map +11 -0
  23. package/dist/chunk-gydabgsn.js +10 -0
  24. package/dist/chunk-gydabgsn.js.map +9 -0
  25. package/dist/chunk-m4fp3pqc.js +167 -0
  26. package/dist/chunk-m4fp3pqc.js.map +10 -0
  27. package/dist/chunk-nnep362g.js +124 -0
  28. package/dist/chunk-nnep362g.js.map +12 -0
  29. package/dist/chunk-pgqvwkcy.js +736 -0
  30. package/dist/chunk-pgqvwkcy.js.map +16 -0
  31. package/dist/chunk-q8cr9t2z.js +415 -0
  32. package/dist/chunk-q8cr9t2z.js.map +20 -0
  33. package/dist/chunk-s2d39pkr.js +19 -0
  34. package/dist/chunk-s2d39pkr.js.map +9 -0
  35. package/dist/chunk-ststnnry.js +44150 -0
  36. package/dist/chunk-ststnnry.js.map +237 -0
  37. package/dist/chunk-sv2nt87j.js +24 -0
  38. package/dist/chunk-sv2nt87j.js.map +9 -0
  39. package/dist/chunk-t2razx5k.js +69 -0
  40. package/dist/chunk-t2razx5k.js.map +10 -0
  41. package/dist/commands/doctor/command.js +10 -6
  42. package/dist/commands/doctor/command.js.map +4 -4
  43. package/dist/commands/doctor/spec.d.ts +6 -0
  44. package/dist/commands/init/command.js +17 -9
  45. package/dist/commands/init/command.js.map +4 -4
  46. package/dist/commands/init/spec.d.ts +6 -0
  47. package/dist/commands/proxy/command.js +2 -3
  48. package/dist/commands/proxy/command.js.map +3 -3
  49. package/dist/commands/screens/command.js +2 -2
  50. package/dist/commands/serve/command.js +3 -3
  51. package/dist/commands/site/command.js +1 -1
  52. package/dist/commands/snapshot/command.js +1 -1
  53. package/dist/commands/tool/command.js +1 -1
  54. package/dist/commands/view/command.js +1 -1
  55. package/dist/index.js +2 -2
  56. package/package.json +1 -1
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/commands/site/ui/SiteBuilder.tsx", "../node_modules/ink-spinner/build/index.js", "../node_modules/ink-text-input/build/index.js", "../src/commands/site/utils/SiteManifest.ts", "../src/commands/site/ui/components/StatusIcon.tsx", "../src/commands/site/ui/ScreenList.tsx", "../src/commands/site/hooks/useProjectHydration.ts"],
4
+ "sourcesContent": [
5
+ "import React, { useState, useEffect, useMemo, useCallback } from 'react';\nimport { Box, Text, useInput, useApp } from 'ink';\nimport Spinner from 'ink-spinner';\nimport TextInput from 'ink-text-input';\nimport { SiteService } from '../../../lib/services/site/SiteService.js';\nimport { StitchViteServer } from '../../../lib/server/vite/StitchViteServer.js';\nimport { openUrl } from '../../../platform/browser.js';\nimport { SiteManifest } from '../utils/SiteManifest.js';\nimport { fetchWithRetry } from '../utils/fetchWithRetry.js';\nimport { ScreenList } from './ScreenList.js';\nimport { useProjectHydration } from '../hooks/useProjectHydration.js';\nimport type { UIScreen, SiteConfig } from '../../../lib/services/site/types.js';\nimport type { Stitch } from '@google/stitch-sdk';\n\ninterface SiteBuilderProps {\n projectId: string;\n client: Stitch;\n onExit: (config: SiteConfig | null, htmlContent?: Map<string, string>) => void;\n}\n\nexport const SiteBuilder: React.FC<SiteBuilderProps> = ({ projectId, client, onExit }) => {\n const { exit } = useApp();\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // New state\n const [screens, setScreens] = useState<UIScreen[]>([]);\n const [showSelectedOnly, setShowSelectedOnly] = useState(false);\n const [activeIndex, setActiveIndex] = useState(0);\n const [viewMode, setViewMode] = useState<'default' | 'discarded'>('default');\n\n const siteManifest = useMemo(() => new SiteManifest(projectId), [projectId]);\n\n const [isEditingRoute, setIsEditingRoute] = useState(false);\n const [routeValue, setRouteValue] = useState('');\n\n const [followMode, setFollowMode] = useState(true);\n const [showAllKeys, setShowAllKeys] = useState(false);\n const [serverUrl, setServerUrl] = useState<string | null>(null);\n const [server, setServer] = useState<StitchViteServer | null>(null);\n\n // Initialize\n useEffect(() => {\n let mounted = true;\n const srv = new StitchViteServer();\n setServer(srv);\n\n const init = async () => {\n try {\n // Start server\n const url = await srv.start(0);\n if (mounted) setServerUrl(url);\n\n // Fetch screens\n const project = client.project(projectId);\n const sdkScreens = await project.screens();\n\n // Convert to UIScreen\n const uiScreens = await Promise.all(\n sdkScreens.map(async (s: any) => ({\n id: s.screenId,\n title: s.title ?? s.screenId,\n status: 'ignored' as const,\n route: '',\n downloadUrl: await s.getHtml().catch(() => null)\n }))\n ) as UIScreen[];\n\n // Load saved screen state (status + routes)\n const saved = await siteManifest.load();\n for (const screen of uiScreens) {\n const state = saved.get(screen.id);\n if (state?.status) screen.status = state.status;\n if (state?.route) screen.route = state.route;\n }\n\n if (mounted) {\n setScreens(uiScreens);\n setLoading(false);\n }\n } catch (e: any) {\n if (mounted) setError(e.message);\n }\n };\n\n init();\n\n return () => {\n mounted = false;\n srv.stop();\n };\n }, [projectId, client]);\n\n // Derived display list\n const displayList = useMemo(() => {\n let list = screens.map((s, i) => ({ screen: s, sourceIndex: i }));\n\n if (viewMode === 'discarded') {\n return list.filter(item => item.screen.status === 'discarded');\n }\n\n // Default: hide discarded\n list = list.filter(item => item.screen.status !== 'discarded');\n\n if (showSelectedOnly) {\n list = list.filter(item => item.screen.status === 'included');\n }\n\n return list;\n }, [screens, viewMode, showSelectedOnly]);\n\n // Clamp activeIndex when list changes\n useEffect(() => {\n setActiveIndex(prev => {\n if (displayList.length === 0) return 0;\n return Math.min(prev, Math.max(0, displayList.length - 1));\n });\n }, [displayList.length]);\n\n // Hydration logic\n const activeItem = displayList[activeIndex];\n const activeScreenId = activeItem?.screen.id;\n\n // Stable fetchContent reference using fetchWithRetry directly\n const fetchContent = useCallback((url: string) => fetchWithRetry(url), []);\n\n const { hydrationStatus, progress, htmlContent } = useProjectHydration(screens, server, fetchContent, activeScreenId);\n\n // Navigate effect (Follow Mode)\n useEffect(() => {\n if (server && followMode && hydrationStatus === 'ready' && activeScreenId) {\n server.navigate(`/_preview/${activeScreenId}`);\n }\n }, [activeScreenId, followMode, server, hydrationStatus]);\n\n // Input handling\n useInput((input, key) => {\n if (loading || error) return;\n\n // When editing route, TextInput handles input.\n // We only listen for Escape to cancel or Enter to submit (handled by TextInput onSubmit/onChange logic?)\n // Actually ink-text-input handles value updates, but we need to handle commit/cancel.\n // However, if we use useInput here, it might conflict if not careful.\n // ink-text-input captures input if focused? No, it just renders.\n // We need to capture input here if NOT editing.\n if (isEditingRoute) {\n if (key.escape) {\n setIsEditingRoute(false);\n setRouteValue(''); // Reset or keep? Reset seems better for cancel.\n }\n return;\n }\n\n if (key.upArrow) {\n setActiveIndex(prev => Math.max(0, prev - 1));\n }\n if (key.downArrow) {\n setActiveIndex(prev => Math.min(displayList.length - 1, prev + 1));\n }\n\n if (input === ' ') {\n if (activeItem) {\n const originalIndex = activeItem.sourceIndex;\n setScreens(prev => {\n const next = [...prev];\n const s = next[originalIndex];\n if (s) {\n s.status = s.status === 'included' ? 'ignored' : 'included';\n }\n siteManifest.save(next);\n return next;\n });\n }\n }\n\n if (key.return) {\n if (activeItem) {\n setRouteValue(activeItem.screen.route);\n setIsEditingRoute(true);\n }\n }\n\n if (input === 't') {\n setShowSelectedOnly(prev => !prev);\n }\n\n if (input === 'f') {\n setFollowMode(prev => !prev);\n }\n\n if (input === 'x') {\n const item = displayList[activeIndex];\n if (!item) return;\n\n if (viewMode === 'discarded') {\n // Undiscard → set to 'ignored'\n const idx = item.sourceIndex;\n setScreens(prev => {\n const next = [...prev];\n if (next[idx]) next[idx]!.status = 'ignored';\n siteManifest.save(next);\n return next;\n });\n } else {\n // Discard\n const idx = item.sourceIndex;\n setScreens(prev => {\n const next = [...prev];\n if (next[idx]) next[idx]!.status = 'discarded';\n siteManifest.save(next);\n return next;\n });\n }\n }\n\n if (input === 'd') {\n setViewMode(prev => prev === 'default' ? 'discarded' : 'default');\n setActiveIndex(0);\n }\n\n if (input === 'o') {\n if (serverUrl && activeScreenId) {\n const target = `${serverUrl}/_preview/${activeScreenId}`;\n openUrl(target);\n }\n }\n\n if (input === 'g') {\n // Validate\n const included = screens.filter(s => s.status === 'included');\n const invalid = included.find(s => !s.route || s.route.trim() === '');\n\n if (invalid) {\n // Can't show error easily without new state, maybe console error or alert?\n // For now, maybe just don't generate?\n // Or better, set an error message in UI?\n // Since we don't have a persistent error UI, let's just do nothing or maybe flash?\n // Plan didn't specify error UI.\n // \"Show a warning and refuse to generate.\"\n // I'll reuse 'error' state but that might be blocking.\n // Let's rely on validation during generation or maybe a quick alert line.\n // I'll assume valid for now or maybe just alert if I can.\n // I'll prevent exit.\n return;\n }\n\n const finalConfig: SiteConfig = {\n projectId,\n routes: included.map(s => ({\n screenId: s.id,\n route: s.route,\n status: s.status as 'included' | 'ignored'\n }))\n };\n onExit(finalConfig, htmlContent);\n exit();\n }\n\n if (input === 'e') {\n const included = screens.filter(s => s.status === 'included');\n const exportData = {\n projectId,\n routes: included.map(s => ({\n screenId: s.id,\n route: s.route,\n })),\n };\n process.stdout.write(JSON.stringify(exportData, null, 2) + '\\n');\n }\n\n if (input === '?') {\n setShowAllKeys(prev => !prev);\n }\n\n if (input === 'q') {\n onExit(null);\n exit();\n }\n });\n\n const handleRouteSubmit = (val: string) => {\n if (activeItem) {\n const originalIndex = activeItem.sourceIndex;\n setScreens(prev => {\n const next = [...prev];\n if (next[originalIndex]) {\n next[originalIndex]!.route = val;\n }\n siteManifest.save(next);\n return next;\n });\n setIsEditingRoute(false);\n // Move to next\n setActiveIndex(prev => Math.min(displayList.length - 1, prev + 1));\n }\n };\n\n if (error) {\n return <Text color=\"red\">Error: {error}</Text>;\n }\n\n if (loading) {\n return (\n <Box>\n <Text color=\"green\"><Spinner type=\"dots\" /> Loading project...</Text>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" height=\"100%\">\n {/* Header */}\n <Box borderStyle=\"single\" borderColor=\"cyan\" paddingX={1}>\n <Text>Stitch Site Builder</Text>\n <Box marginLeft={2}>\n <Text color=\"gray\">{serverUrl}</Text>\n </Box>\n <Box marginLeft={2}>\n {viewMode === 'discarded' ? (\n <Text color=\"red\">Viewing Discarded ({displayList.length})</Text>\n ) : (\n <Text>Filter: {showSelectedOnly ? 'Selected' : 'All'} ({displayList.length})</Text>\n )}\n </Box>\n {viewMode === 'default' && screens.filter(s => s.status === 'discarded').length > 0 && (\n <Box marginLeft={2}>\n <Text dimColor>{screens.filter(s => s.status === 'discarded').length} discarded (press d to view)</Text>\n </Box>\n )}\n <Box marginLeft={2}>\n {hydrationStatus === 'downloading' && (\n <Text color=\"yellow\">\n <Spinner type=\"dots\" /> Downloading... {Math.round(progress * 100)}%\n </Text>\n )}\n {hydrationStatus === 'ready' && <Text color=\"green\">Ready</Text>}\n </Box>\n </Box>\n\n {/* List */}\n <ScreenList items={displayList} activeIndex={activeIndex} />\n\n {/* Route Editor */}\n <Box borderStyle=\"single\" borderColor={isEditingRoute ? \"green\" : \"gray\"} paddingX={1} flexDirection=\"column\">\n {activeItem ? (\n <>\n <Text bold>Route for: {activeItem.screen.title}</Text>\n {isEditingRoute ? (\n <Box>\n <Text color=\"green\">{'> '}</Text>\n <TextInput\n value={routeValue}\n onChange={setRouteValue}\n onSubmit={handleRouteSubmit}\n />\n </Box>\n ) : (\n <Box>\n <Text color=\"gray\">{activeItem.screen.route || 'No route defined'}</Text>\n <Box marginLeft={2}>\n <Text dimColor>Press Enter to edit</Text>\n </Box>\n </Box>\n )}\n </>\n ) : (\n <Text color=\"gray\">No screen selected</Text>\n )}\n </Box>\n\n {/* Keymap */}\n <Box borderStyle=\"single\" borderColor=\"gray\" paddingX={1}>\n <Text dimColor>\n {viewMode === 'discarded'\n ? '[x] Undiscard [d] Back to All [q] Quit'\n : showAllKeys\n ? `[Space] Toggle [Enter] Edit Route [x] Discard [d] View Discarded [t] Filter [f] Follow: ${followMode ? 'ON' : 'OFF'} [o] Open [g] Generate [e] Export [q] Quit [?] Less`\n : '[Space] Toggle [Enter] Edit Route [g] Generate [x] Discard [o] Open [q] Quit [?] More'\n }\n </Text>\n </Box>\n </Box>\n );\n};\n",
6
+ "import React, { useState, useEffect } from 'react';\nimport { Text } from 'ink';\nimport spinners from 'cli-spinners';\n/**\n * Spinner.\n */\nfunction Spinner({ type = 'dots' }) {\n const [frame, setFrame] = useState(0);\n const spinner = spinners[type];\n useEffect(() => {\n const timer = setInterval(() => {\n setFrame(previousFrame => {\n const isLastFrame = previousFrame === spinner.frames.length - 1;\n return isLastFrame ? 0 : previousFrame + 1;\n });\n }, spinner.interval);\n return () => {\n clearInterval(timer);\n };\n }, [spinner]);\n return React.createElement(Text, null, spinner.frames[frame]);\n}\nexport default Spinner;\n//# sourceMappingURL=index.js.map",
7
+ "import React, { useState, useEffect } from 'react';\nimport { Text, useInput } from 'ink';\nimport chalk from 'chalk';\nfunction TextInput({ value: originalValue, placeholder = '', focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit, }) {\n const [state, setState] = useState({\n cursorOffset: (originalValue || '').length,\n cursorWidth: 0,\n });\n const { cursorOffset, cursorWidth } = state;\n useEffect(() => {\n setState(previousState => {\n if (!focus || !showCursor) {\n return previousState;\n }\n const newValue = originalValue || '';\n if (previousState.cursorOffset > newValue.length - 1) {\n return {\n cursorOffset: newValue.length,\n cursorWidth: 0,\n };\n }\n return previousState;\n });\n }, [originalValue, focus, showCursor]);\n const cursorActualWidth = highlightPastedText ? cursorWidth : 0;\n const value = mask ? mask.repeat(originalValue.length) : originalValue;\n let renderedValue = value;\n let renderedPlaceholder = placeholder ? chalk.grey(placeholder) : undefined;\n // Fake mouse cursor, because it's too inconvenient to deal with actual cursor and ansi escapes\n if (showCursor && focus) {\n renderedPlaceholder =\n placeholder.length > 0\n ? chalk.inverse(placeholder[0]) + chalk.grey(placeholder.slice(1))\n : chalk.inverse(' ');\n renderedValue = value.length > 0 ? '' : chalk.inverse(' ');\n let i = 0;\n for (const char of value) {\n renderedValue +=\n i >= cursorOffset - cursorActualWidth && i <= cursorOffset\n ? chalk.inverse(char)\n : char;\n i++;\n }\n if (value.length > 0 && cursorOffset === value.length) {\n renderedValue += chalk.inverse(' ');\n }\n }\n useInput((input, key) => {\n if (key.upArrow ||\n key.downArrow ||\n (key.ctrl && input === 'c') ||\n key.tab ||\n (key.shift && key.tab)) {\n return;\n }\n if (key.return) {\n if (onSubmit) {\n onSubmit(originalValue);\n }\n return;\n }\n let nextCursorOffset = cursorOffset;\n let nextValue = originalValue;\n let nextCursorWidth = 0;\n if (key.leftArrow) {\n if (showCursor) {\n nextCursorOffset--;\n }\n }\n else if (key.rightArrow) {\n if (showCursor) {\n nextCursorOffset++;\n }\n }\n else if (key.backspace || key.delete) {\n if (cursorOffset > 0) {\n nextValue =\n originalValue.slice(0, cursorOffset - 1) +\n originalValue.slice(cursorOffset, originalValue.length);\n nextCursorOffset--;\n }\n }\n else {\n nextValue =\n originalValue.slice(0, cursorOffset) +\n input +\n originalValue.slice(cursorOffset, originalValue.length);\n nextCursorOffset += input.length;\n if (input.length > 1) {\n nextCursorWidth = input.length;\n }\n }\n if (cursorOffset < 0) {\n nextCursorOffset = 0;\n }\n if (cursorOffset > originalValue.length) {\n nextCursorOffset = originalValue.length;\n }\n setState({\n cursorOffset: nextCursorOffset,\n cursorWidth: nextCursorWidth,\n });\n if (nextValue !== originalValue) {\n onChange(nextValue);\n }\n }, { isActive: focus });\n return (React.createElement(Text, null, placeholder\n ? value.length > 0\n ? renderedValue\n : renderedPlaceholder\n : renderedValue));\n}\nexport default TextInput;\nexport function UncontrolledTextInput({ initialValue = '', ...props }) {\n const [value, setValue] = useState(initialValue);\n return React.createElement(TextInput, { ...props, value: value, onChange: setValue });\n}\n//# sourceMappingURL=index.js.map",
8
+ "import fs from 'fs-extra';\nimport path from 'path';\nimport os from 'os';\n\ninterface ScreenState {\n status?: 'included' | 'ignored' | 'discarded';\n route?: string;\n}\n\ninterface SiteManifestData {\n screens: Record<string, ScreenState>;\n}\n\ninterface LegacyDiscardData {\n discardedScreenIds: string[];\n}\n\nexport class SiteManifest {\n private filePath: string;\n private legacyPath: string;\n\n constructor(projectId: string) {\n const dir = path.join(os.homedir(), '.stitch-mcp', 'site', projectId);\n this.filePath = path.join(dir, 'site-manifest.json');\n this.legacyPath = path.join(dir, 'discarded.json');\n }\n\n async load(): Promise<Map<string, ScreenState>> {\n try {\n const data: SiteManifestData = await fs.readJson(this.filePath);\n return new Map(Object.entries(data.screens || {}));\n } catch {\n // site-manifest.json doesn't exist or is corrupted — try legacy migration\n }\n\n try {\n const legacy: LegacyDiscardData = await fs.readJson(this.legacyPath);\n const map = new Map<string, ScreenState>();\n for (const id of legacy.discardedScreenIds || []) {\n map.set(id, { status: 'discarded' });\n }\n return map;\n } catch {\n return new Map();\n }\n }\n\n async save(screens: { id: string; status: string; route: string }[]): Promise<void> {\n const record: Record<string, ScreenState> = {};\n for (const screen of screens) {\n const entry: ScreenState = {};\n if (screen.status !== 'ignored') {\n entry.status = screen.status as ScreenState['status'];\n }\n if (screen.route !== '') {\n entry.route = screen.route;\n }\n if (entry.status || entry.route) {\n record[screen.id] = entry;\n }\n }\n await fs.ensureDir(path.dirname(this.filePath));\n const data: SiteManifestData = { screens: record };\n await fs.writeJson(this.filePath, data, { spaces: 2 });\n }\n}\n",
9
+ "import React from 'react';\nimport { Text } from 'ink';\n\ninterface StatusIconProps {\n status: 'included' | 'ignored' | 'discarded';\n}\n\nexport const StatusIcon: React.FC<StatusIconProps> = ({ status }) => {\n if (status === 'included') {\n return <Text color=\"green\">✔ </Text>;\n }\n if (status === 'discarded') {\n return <Text color=\"red\">✖ </Text>;\n }\n return <Text color=\"gray\">- </Text>;\n};\n",
10
+ "import React from 'react';\nimport { Box, Text, useStdout } from 'ink';\nimport type { UIScreen } from './types.js';\nimport { StatusIcon } from './components/StatusIcon.js';\n\ninterface ScreenListProps {\n items: { screen: UIScreen; sourceIndex: number }[];\n activeIndex: number;\n}\n\nexport const ScreenList: React.FC<ScreenListProps> = ({ items, activeIndex }) => {\n const { stdout } = useStdout();\n const height = stdout ? stdout.rows : 20; // Default to 20 if unavailable\n const LIST_HEIGHT = Math.max(5, height - 10); // Reserve space for header/footer\n\n // Adjust start to keep active item in view\n let start = 0;\n if (activeIndex >= LIST_HEIGHT) {\n start = activeIndex - LIST_HEIGHT + 1;\n }\n start = Math.max(0, activeIndex - Math.floor(LIST_HEIGHT / 2));\n const end = Math.min(items.length, start + LIST_HEIGHT);\n\n // Correction if near end\n if (end - start < LIST_HEIGHT && items.length > LIST_HEIGHT) {\n start = Math.max(0, items.length - LIST_HEIGHT);\n }\n\n const visibleItems = items.slice(start, end);\n\n return (\n <Box flexDirection=\"column\" flexGrow={1} borderStyle=\"single\" borderColor=\"blue\">\n {start > 0 && (\n <Box paddingLeft={1}>\n <Text color=\"gray\">... {start} more above ...</Text>\n </Box>\n )}\n\n {visibleItems.map((item, i) => {\n const index = start + i;\n const isActive = index === activeIndex;\n const { screen } = item;\n\n return (\n <Box key={screen.id}>\n <Text color={isActive ? 'cyan' : undefined}>\n {isActive ? '> ' : ' '}\n </Text>\n <StatusIcon status={screen.status} />\n <Text color={isActive ? 'cyan' : undefined} wrap=\"truncate\">\n {screen.title}\n </Text>\n {screen.route && (\n <Text color=\"gray\">{' -> '}{screen.route}</Text>\n )}\n </Box>\n );\n })}\n\n {end < items.length && (\n <Box paddingLeft={1}>\n <Text color=\"gray\">... {items.length - end} more below ...</Text>\n </Box>\n )}\n </Box>\n );\n};\n",
11
+ "import { useState, useEffect, useRef } from 'react';\nimport { StitchViteServer } from '../../../lib/server/vite/StitchViteServer.js';\nimport type { UIScreen } from '../../../lib/services/site/types.js';\nimport pLimit from 'p-limit';\n\nexport type HydrationStatus = 'idle' | 'downloading' | 'ready' | 'error';\n\nexport type FetchContentFn = (url: string) => Promise<string>;\n\nexport function useProjectHydration(\n screens: UIScreen[],\n server: StitchViteServer | null,\n fetchContent: FetchContentFn,\n activeScreenId?: string\n) {\n const [hydrationStatus, setHydrationStatus] = useState<HydrationStatus>('idle');\n const [progress, setProgress] = useState(0);\n const contentCache = useRef<Map<string, string>>(new Map());\n const [htmlContent, setHtmlContent] = useState<Map<string, string>>(new Map());\n\n useEffect(() => {\n if (!server || screens.length === 0) return;\n\n let mounted = true;\n\n const hydrate = async () => {\n // Determine what needs to be downloaded\n // 1. All included screens\n // 2. The active screen (for preview), even if ignored\n const toDownload = screens.filter(s => {\n if (contentCache.current.has(s.id)) return false;\n return s.status === 'included' || s.id === activeScreenId;\n });\n\n if (toDownload.length === 0) {\n // If nothing to download, ensure server has everything mounted\n // (Just in case activeScreenId changed to something already cached but not mounted?\n // Actually server mount is persistent as long as server is running.\n // But if we have cached content, we should ensure it is mounted.)\n\n // Also check if we should update status to ready\n if (hydrationStatus === 'idle' || hydrationStatus === 'downloading') {\n setHydrationStatus('ready');\n setHtmlContent(new Map(contentCache.current));\n }\n\n // Mount cached content to server if not already?\n // It's safer to re-mount or check.\n // For now, let's just mount the active one to be sure if it's cached.\n if (activeScreenId && contentCache.current.has(activeScreenId)) {\n server.mount(`/_preview/${activeScreenId}`, contentCache.current.get(activeScreenId)!);\n }\n\n return;\n }\n\n setHydrationStatus('downloading');\n const limit = pLimit(3);\n let completed = 0;\n const total = toDownload.length;\n\n try {\n await Promise.all(toDownload.map(screen => limit(async () => {\n if (!mounted) return;\n\n if (!screen.downloadUrl) return;\n\n try {\n const html = await fetchContent(screen.downloadUrl);\n if (mounted) {\n contentCache.current.set(screen.id, html);\n server.mount(`/_preview/${screen.id}`, html);\n }\n } catch (e) {\n console.error(`Failed to hydrate ${screen.id}`, e);\n }\n\n if (mounted) {\n completed++;\n setProgress(completed / total);\n }\n })));\n\n if (mounted) {\n setHtmlContent(new Map(contentCache.current));\n setHydrationStatus('ready');\n }\n } catch (e) {\n if (mounted) setHydrationStatus('error');\n }\n };\n\n hydrate();\n\n return () => { mounted = false; };\n }, [screens, server, fetchContent, activeScreenId]);\n\n return { hydrationStatus, progress, htmlContent };\n}\n"
12
+ ],
13
+ "mappings": "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",
14
+ "debugId": "BA12672C2AC4B82664756E2164756E21",
15
+ "names": []
16
+ }
@@ -0,0 +1,415 @@
1
+ import {
2
+ downloadText
3
+ } from "./chunk-34w2wfyp.js";
4
+ import {
5
+ fetchWithRetry
6
+ } from "./chunk-6gw9apqb.js";
7
+ import"./chunk-akd997ec.js";
8
+ import {
9
+ StitchToolClient,
10
+ stitch
11
+ } from "./chunk-e4q3v109.js";
12
+ import {
13
+ pLimit
14
+ } from "./chunk-a5xra9jn.js";
15
+ import {
16
+ runSteps
17
+ } from "./chunk-f2hq6bfv.js";
18
+ import"./chunk-4jygt4d6.js";
19
+ import"./chunk-tz7wnw4s.js";
20
+ import"./chunk-c6ge431q.js";
21
+ import"./chunk-9wyra8hs.js";
22
+
23
+ // src/commands/tool/virtual-tools/get-screen-code.ts
24
+ var getScreenCodeTool = {
25
+ name: "get_screen_code",
26
+ description: "(Virtual) Retrieves a screen and downloads its HTML code content.",
27
+ inputSchema: {
28
+ type: "object",
29
+ properties: {
30
+ projectId: {
31
+ type: "string",
32
+ description: "Required. The project ID of screen to retrieve."
33
+ },
34
+ screenId: {
35
+ type: "string",
36
+ description: "Required. The name of screen to retrieve."
37
+ }
38
+ },
39
+ required: ["projectId", "screenId"]
40
+ },
41
+ execute: async (client, args, stitch2) => {
42
+ if (!stitch2)
43
+ throw new Error("get_screen_code requires a Stitch instance");
44
+ const { projectId, screenId } = args;
45
+ const screen = await stitch2.project(projectId).getScreen(screenId);
46
+ let htmlContent = null;
47
+ try {
48
+ const htmlUrl = await screen.getHtml();
49
+ if (htmlUrl) {
50
+ htmlContent = await downloadText(htmlUrl);
51
+ }
52
+ } catch (e) {
53
+ console.error(`Error downloading HTML code: ${e}`);
54
+ }
55
+ return {
56
+ screenId: screen.screenId,
57
+ projectId: screen.projectId,
58
+ htmlContent
59
+ };
60
+ }
61
+ };
62
+ // src/commands/tool/virtual-tools/get-screen-image.ts
63
+ var getScreenImageTool = {
64
+ name: "get_screen_image",
65
+ description: "(Virtual) Retrieves a screen and downloads its screenshot image content.",
66
+ inputSchema: {
67
+ type: "object",
68
+ properties: {
69
+ projectId: {
70
+ type: "string",
71
+ description: "Required. The project ID of screen to retrieve."
72
+ },
73
+ screenId: {
74
+ type: "string",
75
+ description: "Required. The name of screen to retrieve."
76
+ }
77
+ },
78
+ required: ["projectId", "screenId"]
79
+ },
80
+ execute: async (client, args, stitch2) => {
81
+ if (!stitch2)
82
+ throw new Error("get_screen_image requires a Stitch instance");
83
+ const { projectId, screenId } = args;
84
+ const screen = await stitch2.project(projectId).getScreen(screenId);
85
+ let imageContent = null;
86
+ try {
87
+ const imageUrl = await screen.getImage();
88
+ if (imageUrl) {
89
+ const response = await fetch(imageUrl);
90
+ const arrayBuffer = await response.arrayBuffer();
91
+ const buffer = Buffer.from(arrayBuffer);
92
+ imageContent = buffer.toString("base64");
93
+ }
94
+ } catch (e) {
95
+ console.error(`Error downloading screenshot: ${e}`);
96
+ }
97
+ return {
98
+ screenId: screen.screenId,
99
+ projectId: screen.projectId,
100
+ imageContent
101
+ };
102
+ }
103
+ };
104
+ // src/commands/tool/virtual-tools/build-site.ts
105
+ var buildSiteTool = {
106
+ name: "build_site",
107
+ description: "(Virtual) Builds a site from a Stitch project by mapping screens to routes. Returns the design HTML for each page to use as context for code generation.",
108
+ inputSchema: {
109
+ type: "object",
110
+ properties: {
111
+ projectId: {
112
+ type: "string",
113
+ description: "Required. The project ID to build a site from."
114
+ },
115
+ routes: {
116
+ type: "array",
117
+ description: "Required. Array of screen-to-route mappings.",
118
+ items: {
119
+ type: "object",
120
+ properties: {
121
+ screenId: {
122
+ type: "string",
123
+ description: "The screen ID to use for this route."
124
+ },
125
+ route: {
126
+ type: "string",
127
+ description: 'The route path (e.g. "/" or "/about").'
128
+ }
129
+ },
130
+ required: ["screenId", "route"]
131
+ }
132
+ }
133
+ },
134
+ required: ["projectId", "routes"]
135
+ },
136
+ execute: async (client, args, stitch2) => {
137
+ if (!stitch2)
138
+ throw new Error("build_site requires a Stitch instance");
139
+ const { projectId, routes } = args;
140
+ if (!Array.isArray(routes)) {
141
+ throw new Error("routes must be an array");
142
+ }
143
+ if (routes.length === 0) {
144
+ throw new Error("routes must be a non-empty array");
145
+ }
146
+ for (const entry of routes) {
147
+ if (!entry.screenId || typeof entry.screenId !== "string") {
148
+ throw new Error('Each route entry must have a "screenId" string');
149
+ }
150
+ if (!entry.route || typeof entry.route !== "string") {
151
+ throw new Error('Each route entry must have a "route" string');
152
+ }
153
+ }
154
+ const routePaths = routes.map((r) => r.route);
155
+ const uniqueRoutes = new Set(routePaths);
156
+ if (uniqueRoutes.size !== routePaths.length) {
157
+ const duplicates = routePaths.filter((r, i) => routePaths.indexOf(r) !== i);
158
+ throw new Error(`Duplicate route paths found: ${[...new Set(duplicates)].join(", ")}`);
159
+ }
160
+ const project = stitch2.project(projectId);
161
+ const sdkScreens = await project.screens();
162
+ const screenMap = new Map(sdkScreens.map((s) => [s.screenId, s]));
163
+ const missingIds = routes.map((r) => r.screenId).filter((id) => !screenMap.has(id));
164
+ if (missingIds.length > 0) {
165
+ throw new Error(`Screen IDs not found in project: ${missingIds.join(", ")}`);
166
+ }
167
+ const limit = pLimit(3);
168
+ const htmlContent = new Map;
169
+ const errors = [];
170
+ await Promise.all(routes.map((r) => limit(async () => {
171
+ const screen = screenMap.get(r.screenId);
172
+ try {
173
+ const htmlUrl = await screen.getHtml();
174
+ if (htmlUrl) {
175
+ const html = await fetchWithRetry(htmlUrl);
176
+ htmlContent.set(r.screenId, html);
177
+ } else {
178
+ htmlContent.set(r.screenId, "");
179
+ }
180
+ } catch (e) {
181
+ errors.push(`${r.screenId}: ${e.message}`);
182
+ }
183
+ })));
184
+ if (errors.length > 0) {
185
+ throw new Error(`Failed to fetch HTML for screens: ${errors.join("; ")}`);
186
+ }
187
+ const pages = routes.map((r) => ({
188
+ screenId: r.screenId,
189
+ route: r.route,
190
+ title: screenMap.get(r.screenId).title ?? r.screenId,
191
+ html: htmlContent.get(r.screenId)
192
+ }));
193
+ return {
194
+ success: true,
195
+ pages,
196
+ message: `Built ${pages.length} page(s) with design HTML`
197
+ };
198
+ }
199
+ };
200
+ // src/commands/tool/virtual-tools/list-tools.ts
201
+ var listToolsTool = {
202
+ name: "list_tools",
203
+ description: "List all available tools with their descriptions and schemas.",
204
+ inputSchema: {
205
+ type: "object",
206
+ properties: {}
207
+ },
208
+ execute: async (client, _args) => {
209
+ const result = await client.listTools();
210
+ return result.tools || [];
211
+ }
212
+ };
213
+ // src/commands/tool/virtual-tools/index.ts
214
+ var virtualTools = [
215
+ getScreenCodeTool,
216
+ getScreenImageTool,
217
+ buildSiteTool,
218
+ listToolsTool
219
+ ];
220
+
221
+ // src/commands/tool/steps/ListToolsStep.ts
222
+ class ListToolsStep {
223
+ id = "list-tools";
224
+ name = "List available tools";
225
+ async shouldRun(context) {
226
+ const name = context.input.toolName?.toLowerCase();
227
+ return !name || name === "list" || name === "listtools" || name === "list_tools";
228
+ }
229
+ async run(context) {
230
+ const result = await context.client.listTools();
231
+ const serverTools = result.tools || [];
232
+ const tools = [
233
+ ...context.virtualTools.map((t) => ({ name: t.name, description: t.description, inputSchema: t.inputSchema, virtual: true })),
234
+ ...serverTools.map((t) => ({ ...t, virtual: false }))
235
+ ];
236
+ context.result = { success: true, data: tools };
237
+ return { success: true };
238
+ }
239
+ }
240
+
241
+ // src/commands/tool/steps/ShowSchemaStep.ts
242
+ class ShowSchemaStep {
243
+ id = "show-schema";
244
+ name = "Show tool schema";
245
+ async shouldRun(context) {
246
+ return !!context.input.toolName && context.input.toolName !== "list" && context.input.showSchema;
247
+ }
248
+ async run(context) {
249
+ const toolName = context.input.toolName;
250
+ const result = await context.client.listTools();
251
+ const serverTools = result.tools || [];
252
+ const allTools = [...context.virtualTools, ...serverTools];
253
+ const tool = allTools.find((t) => t.name === toolName);
254
+ if (!tool) {
255
+ context.result = { success: false, error: `Tool not found: ${toolName}` };
256
+ return { success: false, error: new Error(`Tool not found: ${toolName}`) };
257
+ }
258
+ context.result = { success: true, data: this.formatSchema(tool) };
259
+ return { success: true };
260
+ }
261
+ formatSchema(tool) {
262
+ const schema = tool.inputSchema;
263
+ const args = {};
264
+ if (schema?.properties) {
265
+ for (const [key, prop] of Object.entries(schema.properties)) {
266
+ const required = schema.required?.includes(key) ? "(required)" : "(optional)";
267
+ args[key] = `${prop.type} ${required}${prop.description ? " - " + prop.description : ""}`;
268
+ }
269
+ }
270
+ return {
271
+ name: tool.name,
272
+ description: tool.description,
273
+ virtual: tool.virtual ?? false,
274
+ arguments: args,
275
+ example: this.generateExample(tool)
276
+ };
277
+ }
278
+ generateExample(tool) {
279
+ const exampleArgs = {};
280
+ if (tool.inputSchema?.properties) {
281
+ for (const [key, prop] of Object.entries(tool.inputSchema.properties)) {
282
+ exampleArgs[key] = prop.type === "string" ? `<${key}>` : `<${prop.type}>`;
283
+ }
284
+ }
285
+ return `stitch-mcp tool ${tool.name} -d '${JSON.stringify(exampleArgs)}'`;
286
+ }
287
+ }
288
+
289
+ // src/commands/tool/steps/ParseArgsStep.ts
290
+ class ParseArgsStep {
291
+ id = "parse-args";
292
+ name = "Parse tool arguments";
293
+ async shouldRun(context) {
294
+ return !!context.input.toolName && context.input.toolName !== "list" && !context.input.showSchema;
295
+ }
296
+ async run(context) {
297
+ let args = {};
298
+ if (context.input.data) {
299
+ args = JSON.parse(context.input.data);
300
+ } else if (context.input.dataFile) {
301
+ const content = await Bun.file(context.input.dataFile.replace("@", "")).text();
302
+ args = JSON.parse(content);
303
+ }
304
+ context.parsedArgs = args;
305
+ return { success: true };
306
+ }
307
+ }
308
+
309
+ // src/commands/tool/steps/ValidateToolStep.ts
310
+ class ValidateToolStep {
311
+ id = "validate-tool";
312
+ name = "Validate tool exists";
313
+ async shouldRun(context) {
314
+ return !!context.input.toolName && context.input.toolName !== "list" && !context.input.showSchema && context.parsedArgs !== undefined;
315
+ }
316
+ async run(context) {
317
+ const toolName = context.input.toolName;
318
+ const result = await context.client.listTools();
319
+ const serverTools = result.tools || [];
320
+ const allTools = [...context.virtualTools, ...serverTools];
321
+ const found = allTools.find((t) => t.name === toolName);
322
+ if (!found) {
323
+ const availableNames = allTools.map((t) => t.name).sort();
324
+ context.result = {
325
+ success: false,
326
+ error: `Tool not found: "${toolName}". Use "list_tools" to see available tools.`,
327
+ data: {
328
+ requestedTool: toolName,
329
+ availableTools: availableNames,
330
+ hint: 'Call "list_tools" to see all available tools with descriptions and schemas.'
331
+ }
332
+ };
333
+ return { success: false, error: new Error(`Tool not found: ${toolName}`) };
334
+ }
335
+ return { success: true };
336
+ }
337
+ }
338
+
339
+ // src/commands/tool/steps/ExecuteToolStep.ts
340
+ class ExecuteToolStep {
341
+ id = "execute-tool";
342
+ name = "Execute tool";
343
+ async shouldRun(context) {
344
+ return context.parsedArgs !== undefined;
345
+ }
346
+ async run(context) {
347
+ const toolName = context.input.toolName;
348
+ const args = context.parsedArgs;
349
+ const virtualTool = context.virtualTools.find((t) => t.name === toolName);
350
+ if (virtualTool) {
351
+ try {
352
+ const result2 = await virtualTool.execute(context.client, args, context.stitch);
353
+ context.result = { success: true, data: result2 };
354
+ return { success: true };
355
+ } catch (e) {
356
+ context.result = { success: false, error: `Virtual tool execution failed: ${e.message || String(e)}` };
357
+ return { success: false, error: e };
358
+ }
359
+ }
360
+ const result = await context.client.callTool(toolName, args);
361
+ context.result = { success: true, data: result };
362
+ return { success: true };
363
+ }
364
+ }
365
+
366
+ // src/commands/tool/handler.ts
367
+ var deps = {
368
+ runSteps,
369
+ ListToolsStep,
370
+ ShowSchemaStep,
371
+ ParseArgsStep,
372
+ ValidateToolStep,
373
+ ExecuteToolStep
374
+ };
375
+
376
+ class ToolCommandHandler {
377
+ client;
378
+ stitchInstance;
379
+ tools;
380
+ steps;
381
+ constructor(client, tools, stitchInstance) {
382
+ this.client = client || new StitchToolClient;
383
+ this.stitchInstance = stitchInstance || stitch;
384
+ this.tools = tools || virtualTools;
385
+ this.steps = [
386
+ new deps.ListToolsStep,
387
+ new deps.ShowSchemaStep,
388
+ new deps.ParseArgsStep,
389
+ new deps.ValidateToolStep,
390
+ new deps.ExecuteToolStep
391
+ ];
392
+ }
393
+ async execute(input) {
394
+ const context = {
395
+ input,
396
+ client: this.client,
397
+ stitch: this.stitchInstance,
398
+ virtualTools: this.tools
399
+ };
400
+ try {
401
+ await deps.runSteps(this.steps, context, {
402
+ onAfterStep: (_step, _result, ctx) => ctx.result !== undefined
403
+ });
404
+ } finally {
405
+ await this.client.close();
406
+ }
407
+ return context.result ?? { success: false, error: "No step produced a result" };
408
+ }
409
+ }
410
+ export {
411
+ deps,
412
+ ToolCommandHandler
413
+ };
414
+
415
+ //# debugId=7A003C51AFD3BD2C64756E2164756E21
@@ -0,0 +1,20 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/commands/tool/virtual-tools/get-screen-code.ts", "../src/commands/tool/virtual-tools/get-screen-image.ts", "../src/commands/tool/virtual-tools/build-site.ts", "../src/commands/tool/virtual-tools/list-tools.ts", "../src/commands/tool/virtual-tools/index.ts", "../src/commands/tool/steps/ListToolsStep.ts", "../src/commands/tool/steps/ShowSchemaStep.ts", "../src/commands/tool/steps/ParseArgsStep.ts", "../src/commands/tool/steps/ValidateToolStep.ts", "../src/commands/tool/steps/ExecuteToolStep.ts", "../src/commands/tool/handler.ts"],
4
+ "sourcesContent": [
5
+ "import type { StitchToolClient, Stitch } from '@google/stitch-sdk';\nimport { downloadText } from '../../../ui/copy-behaviors/clipboard.js';\nimport type { VirtualTool } from '../spec.js';\n\nexport const getScreenCodeTool: VirtualTool = {\n name: 'get_screen_code',\n description: '(Virtual) Retrieves a screen and downloads its HTML code content.',\n inputSchema: {\n type: 'object',\n properties: {\n projectId: {\n type: 'string',\n description: 'Required. The project ID of screen to retrieve.',\n },\n screenId: {\n type: 'string',\n description: 'Required. The name of screen to retrieve.',\n },\n },\n required: ['projectId', 'screenId'],\n },\n execute: async (client: StitchToolClient, args: any, stitch?: Stitch) => {\n if (!stitch) throw new Error('get_screen_code requires a Stitch instance');\n const { projectId, screenId } = args;\n\n // 1. Get the screen details using the injected SDK instance\n const screen = await stitch.project(projectId).getScreen(screenId);\n\n // 2. Fetch HTML Code\n let htmlContent: string | null = null;\n try {\n const htmlUrl = await screen.getHtml();\n if (htmlUrl) {\n htmlContent = await downloadText(htmlUrl);\n }\n } catch (e) {\n console.error(`Error downloading HTML code: ${e}`);\n }\n\n // 3. Return screen with code content\n return {\n screenId: screen.screenId,\n projectId: screen.projectId,\n htmlContent,\n };\n },\n};\n",
6
+ "import type { StitchToolClient, Stitch } from '@google/stitch-sdk';\nimport type { VirtualTool } from '../spec.js';\n\nexport const getScreenImageTool: VirtualTool = {\n name: 'get_screen_image',\n description: '(Virtual) Retrieves a screen and downloads its screenshot image content.',\n inputSchema: {\n type: 'object',\n properties: {\n projectId: {\n type: 'string',\n description: 'Required. The project ID of screen to retrieve.',\n },\n screenId: {\n type: 'string',\n description: 'Required. The name of screen to retrieve.',\n },\n },\n required: ['projectId', 'screenId'],\n },\n execute: async (client: StitchToolClient, args: any, stitch?: Stitch) => {\n if (!stitch) throw new Error('get_screen_image requires a Stitch instance');\n const { projectId, screenId } = args;\n\n // 1. Get the screen details using the injected SDK instance\n const screen = await stitch.project(projectId).getScreen(screenId);\n\n // 2. Fetch Image Content\n let imageContent: string | null = null;\n try {\n const imageUrl = await screen.getImage();\n if (imageUrl) {\n const response = await fetch(imageUrl);\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n imageContent = buffer.toString('base64');\n }\n } catch (e) {\n console.error(`Error downloading screenshot: ${e}`);\n }\n\n // 3. Return screen with image content\n return {\n screenId: screen.screenId,\n projectId: screen.projectId,\n imageContent,\n };\n },\n};\n",
7
+ "import type { StitchToolClient, Stitch } from '@google/stitch-sdk';\nimport type { VirtualTool } from '../spec.js';\nimport pLimit from 'p-limit';\nimport { fetchWithRetry } from '../../site/utils/fetchWithRetry.js';\n\nexport const buildSiteTool: VirtualTool = {\n name: 'build_site',\n description: '(Virtual) Builds a site from a Stitch project by mapping screens to routes. Returns the design HTML for each page to use as context for code generation.',\n inputSchema: {\n type: 'object',\n properties: {\n projectId: {\n type: 'string',\n description: 'Required. The project ID to build a site from.',\n },\n routes: {\n type: 'array',\n description: 'Required. Array of screen-to-route mappings.',\n items: {\n type: 'object',\n properties: {\n screenId: {\n type: 'string',\n description: 'The screen ID to use for this route.',\n },\n route: {\n type: 'string',\n description: 'The route path (e.g. \"/\" or \"/about\").',\n },\n },\n required: ['screenId', 'route'],\n },\n },\n },\n required: ['projectId', 'routes'],\n },\n execute: async (client: StitchToolClient, args: any, stitch?: Stitch) => {\n if (!stitch) throw new Error('build_site requires a Stitch instance');\n const { projectId, routes } = args;\n\n // Validate routes\n if (!Array.isArray(routes)) {\n throw new Error('routes must be an array');\n }\n if (routes.length === 0) {\n throw new Error('routes must be a non-empty array');\n }\n for (const entry of routes) {\n if (!entry.screenId || typeof entry.screenId !== 'string') {\n throw new Error('Each route entry must have a \"screenId\" string');\n }\n if (!entry.route || typeof entry.route !== 'string') {\n throw new Error('Each route entry must have a \"route\" string');\n }\n }\n\n // Check for duplicate routes\n const routePaths = routes.map((r: any) => r.route);\n const uniqueRoutes = new Set(routePaths);\n if (uniqueRoutes.size !== routePaths.length) {\n const duplicates = routePaths.filter((r: string, i: number) => routePaths.indexOf(r) !== i);\n throw new Error(`Duplicate route paths found: ${[...new Set(duplicates)].join(', ')}`);\n }\n\n // Fetch project screens via injected SDK instance\n const project = stitch.project(projectId);\n const sdkScreens = await project.screens();\n const screenMap = new Map(sdkScreens.map((s: any) => [s.screenId, s]));\n\n // Validate all requested screenIds exist\n const missingIds = routes\n .map((r: any) => r.screenId)\n .filter((id: string) => !screenMap.has(id));\n if (missingIds.length > 0) {\n throw new Error(`Screen IDs not found in project: ${missingIds.join(', ')}`);\n }\n\n // Fetch HTML for each screen with concurrency limit\n const limit = pLimit(3);\n const htmlContent = new Map<string, string>();\n const errors: string[] = [];\n\n await Promise.all(\n routes.map((r: any) =>\n limit(async () => {\n const screen = screenMap.get(r.screenId)!;\n try {\n const htmlUrl = await screen.getHtml();\n if (htmlUrl) {\n const html = await fetchWithRetry(htmlUrl);\n htmlContent.set(r.screenId, html);\n } else {\n htmlContent.set(r.screenId, '');\n }\n } catch (e: any) {\n errors.push(`${r.screenId}: ${e.message}`);\n }\n })\n )\n );\n\n if (errors.length > 0) {\n throw new Error(`Failed to fetch HTML for screens: ${errors.join('; ')}`);\n }\n\n // Return raw HTML content for each page\n const pages = routes.map((r: any) => ({\n screenId: r.screenId,\n route: r.route,\n title: screenMap.get(r.screenId)!.title ?? r.screenId,\n html: htmlContent.get(r.screenId)!,\n }));\n\n return {\n success: true,\n pages,\n message: `Built ${pages.length} page(s) with design HTML`,\n };\n },\n};\n",
8
+ "import type { VirtualTool } from '../spec.js';\nimport type { StitchToolClient } from '@google/stitch-sdk';\n\nexport const listToolsTool: VirtualTool = {\n name: 'list_tools',\n description: 'List all available tools with their descriptions and schemas.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n execute: async (client: StitchToolClient, _args: any) => {\n const result = await client.listTools();\n return result.tools || [];\n },\n};\n",
9
+ "export type { VirtualTool } from '../spec.js';\nexport { getScreenCodeTool } from './get-screen-code.js';\nexport { getScreenImageTool } from './get-screen-image.js';\nexport { buildSiteTool } from './build-site.js';\nexport { listToolsTool } from './list-tools.js';\n\nimport { getScreenCodeTool } from './get-screen-code.js';\nimport { getScreenImageTool } from './get-screen-image.js';\nimport { buildSiteTool } from './build-site.js';\nimport { listToolsTool } from './list-tools.js';\nimport type { VirtualTool } from '../spec.js';\n\nexport const virtualTools: VirtualTool[] = [\n getScreenCodeTool,\n getScreenImageTool,\n buildSiteTool,\n listToolsTool,\n];\n",
10
+ "import type { CommandStep, StepResult } from '../../../framework/CommandStep.js';\nimport type { ToolContext } from '../context.js';\n\nexport class ListToolsStep implements CommandStep<ToolContext> {\n id = 'list-tools';\n name = 'List available tools';\n\n async shouldRun(context: ToolContext): Promise<boolean> {\n const name = context.input.toolName?.toLowerCase();\n return !name || name === 'list' || name === 'listtools' || name === 'list_tools';\n }\n\n async run(context: ToolContext): Promise<StepResult> {\n const result = await context.client.listTools();\n const serverTools = result.tools || [];\n const tools = [\n ...context.virtualTools.map(t => ({ name: t.name, description: t.description, inputSchema: t.inputSchema, virtual: true as const })),\n ...serverTools.map(t => ({ ...t, virtual: false as const })),\n ];\n context.result = { success: true, data: tools };\n return { success: true };\n }\n}\n",
11
+ "import type { CommandStep, StepResult } from '../../../framework/CommandStep.js';\nimport type { ToolContext } from '../context.js';\nimport type { ToolInfo } from '../spec.js';\n\nexport class ShowSchemaStep implements CommandStep<ToolContext> {\n id = 'show-schema';\n name = 'Show tool schema';\n\n async shouldRun(context: ToolContext): Promise<boolean> {\n return !!context.input.toolName && context.input.toolName !== 'list' && context.input.showSchema;\n }\n\n async run(context: ToolContext): Promise<StepResult> {\n const toolName = context.input.toolName!;\n\n // Get all tools to find the one we need\n const result = await context.client.listTools();\n const serverTools = result.tools || [];\n const allTools = [...context.virtualTools, ...serverTools];\n const tool = allTools.find(t => t.name === toolName);\n\n if (!tool) {\n context.result = { success: false, error: `Tool not found: ${toolName}` };\n return { success: false, error: new Error(`Tool not found: ${toolName}`) };\n }\n\n context.result = { success: true, data: this.formatSchema(tool) };\n return { success: true };\n }\n\n private formatSchema(tool: ToolInfo): object {\n const schema = tool.inputSchema;\n const args: Record<string, string> = {};\n\n if (schema?.properties) {\n for (const [key, prop] of Object.entries(schema.properties)) {\n const required = schema.required?.includes(key) ? '(required)' : '(optional)';\n args[key] = `${prop.type} ${required}${prop.description ? ' - ' + prop.description : ''}`;\n }\n }\n\n return {\n name: tool.name,\n description: tool.description,\n virtual: tool.virtual ?? false,\n arguments: args,\n example: this.generateExample(tool),\n };\n }\n\n private generateExample(tool: ToolInfo): string {\n const exampleArgs: Record<string, any> = {};\n if (tool.inputSchema?.properties) {\n for (const [key, prop] of Object.entries(tool.inputSchema.properties)) {\n exampleArgs[key] = prop.type === 'string' ? `<${key}>` : `<${prop.type}>`;\n }\n }\n return `stitch-mcp tool ${tool.name} -d '${JSON.stringify(exampleArgs)}'`;\n }\n}\n",
12
+ "import type { CommandStep, StepResult } from '../../../framework/CommandStep.js';\nimport type { ToolContext } from '../context.js';\n\nexport class ParseArgsStep implements CommandStep<ToolContext> {\n id = 'parse-args';\n name = 'Parse tool arguments';\n\n async shouldRun(context: ToolContext): Promise<boolean> {\n return !!context.input.toolName\n && context.input.toolName !== 'list'\n && !context.input.showSchema;\n }\n\n async run(context: ToolContext): Promise<StepResult> {\n let args: Record<string, any> = {};\n\n if (context.input.data) {\n args = JSON.parse(context.input.data);\n } else if (context.input.dataFile) {\n const content = await Bun.file(context.input.dataFile.replace('@', '')).text();\n args = JSON.parse(content);\n }\n\n context.parsedArgs = args;\n return { success: true };\n }\n}\n",
13
+ "import type { CommandStep, StepResult } from '../../../framework/CommandStep.js';\nimport type { ToolContext } from '../context.js';\n\nexport class ValidateToolStep implements CommandStep<ToolContext> {\n id = 'validate-tool';\n name = 'Validate tool exists';\n\n async shouldRun(context: ToolContext): Promise<boolean> {\n return !!context.input.toolName\n && context.input.toolName !== 'list'\n && !context.input.showSchema\n && context.parsedArgs !== undefined;\n }\n\n async run(context: ToolContext): Promise<StepResult> {\n const toolName = context.input.toolName!;\n\n const result = await context.client.listTools();\n const serverTools = result.tools || [];\n const allTools = [...context.virtualTools, ...serverTools];\n const found = allTools.find(t => t.name === toolName);\n\n if (!found) {\n const availableNames = allTools.map(t => t.name).sort();\n context.result = {\n success: false,\n error: `Tool not found: \"${toolName}\". Use \"list_tools\" to see available tools.`,\n data: {\n requestedTool: toolName,\n availableTools: availableNames,\n hint: 'Call \"list_tools\" to see all available tools with descriptions and schemas.',\n },\n };\n return { success: false, error: new Error(`Tool not found: ${toolName}`) };\n }\n\n return { success: true };\n }\n}\n",
14
+ "import type { CommandStep, StepResult } from '../../../framework/CommandStep.js';\nimport type { ToolContext } from '../context.js';\n\nexport class ExecuteToolStep implements CommandStep<ToolContext> {\n id = 'execute-tool';\n name = 'Execute tool';\n\n async shouldRun(context: ToolContext): Promise<boolean> {\n return context.parsedArgs !== undefined;\n }\n\n async run(context: ToolContext): Promise<StepResult> {\n const toolName = context.input.toolName!;\n const args = context.parsedArgs!;\n\n // Check if it's a virtual tool\n const virtualTool = context.virtualTools.find(t => t.name === toolName);\n if (virtualTool) {\n try {\n const result = await virtualTool.execute(context.client, args, context.stitch);\n context.result = { success: true, data: result };\n return { success: true };\n } catch (e: any) {\n context.result = { success: false, error: `Virtual tool execution failed: ${e.message || String(e)}` };\n return { success: false, error: e };\n }\n }\n\n const result = await context.client.callTool(toolName, args);\n context.result = { success: true, data: result };\n return { success: true };\n }\n}\n",
15
+ "import { StitchToolClient, stitch as defaultStitch } from '@google/stitch-sdk';\nimport type { Stitch } from '@google/stitch-sdk';\nimport type { CommandStep } from '../../framework/CommandStep.js';\nimport { runSteps } from '../../framework/StepRunner.js';\nimport type { ToolCommandInput, ToolCommandResult, VirtualTool } from './spec.js';\n\nimport type { ToolContext } from './context.js';\nimport { virtualTools as defaultVirtualTools } from './virtual-tools/index.js';\nimport { ListToolsStep } from './steps/ListToolsStep.js';\nimport { ShowSchemaStep } from './steps/ShowSchemaStep.js';\nimport { ParseArgsStep } from './steps/ParseArgsStep.js';\nimport { ValidateToolStep } from './steps/ValidateToolStep.js';\nimport { ExecuteToolStep } from './steps/ExecuteToolStep.js';\n\nexport const deps = {\n runSteps,\n ListToolsStep,\n ShowSchemaStep,\n ParseArgsStep,\n ValidateToolStep,\n ExecuteToolStep,\n};\n\nexport class ToolCommandHandler {\n private client: StitchToolClient;\n private stitchInstance: Stitch;\n private tools: VirtualTool[];\n private steps: CommandStep<ToolContext>[];\n\n constructor(client?: StitchToolClient, tools?: VirtualTool[], stitchInstance?: Stitch) {\n this.client = client || new StitchToolClient();\n this.stitchInstance = stitchInstance || defaultStitch;\n this.tools = tools || defaultVirtualTools;\n this.steps = [\n new deps.ListToolsStep(),\n new deps.ShowSchemaStep(),\n new deps.ParseArgsStep(),\n new deps.ValidateToolStep(),\n new deps.ExecuteToolStep(),\n ];\n }\n\n async execute(input: ToolCommandInput): Promise<ToolCommandResult> {\n const context: ToolContext = {\n input,\n client: this.client,\n stitch: this.stitchInstance,\n virtualTools: this.tools,\n };\n\n try {\n await deps.runSteps(this.steps, context, {\n onAfterStep: (_step, _result, ctx) => ctx.result !== undefined,\n });\n } finally {\n await this.client.close();\n }\n\n return context.result ?? { success: false, error: 'No step produced a result' };\n }\n}\n"
16
+ ],
17
+ "mappings": "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",
18
+ "debugId": "7A003C51AFD3BD2C64756E2164756E21",
19
+ "names": []
20
+ }
@@ -0,0 +1,19 @@
1
+ import {
2
+ InitHandler
3
+ } from "./chunk-etcps0m5.js";
4
+ import"./chunk-py8fhw0k.js";
5
+ import"./chunk-jyem6j6k.js";
6
+ import"./chunk-nq68kghz.js";
7
+ import"./chunk-q6sv0243.js";
8
+ import"./chunk-f2hq6bfv.js";
9
+ import"./chunk-4jygt4d6.js";
10
+ import"./chunk-tz7wnw4s.js";
11
+ import"./chunk-kbtqrkwh.js";
12
+ import"./chunk-3sfn889r.js";
13
+ import"./chunk-c6ge431q.js";
14
+ import"./chunk-9wyra8hs.js";
15
+ export {
16
+ InitHandler
17
+ };
18
+
19
+ //# debugId=383410DAD74C59F864756E2164756E21
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [
5
+ ],
6
+ "mappings": "",
7
+ "debugId": "383410DAD74C59F864756E2164756E21",
8
+ "names": []
9
+ }