@wolfstar/cli 2.1.0 → 2.3.0-next-20261004131917
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 +203 -42
- package/dist/{_shared-B-hRZDRS.js → _shared-BIQK0Bhm.js} +12 -5
- package/dist/_shared-BIQK0Bhm.js.map +1 -0
- package/dist/bridge-BvkmlAOZ.js +410 -0
- package/dist/bridge-BvkmlAOZ.js.map +1 -0
- package/dist/{build-CPnSLYME.js → build-DJcc95Yq.js} +5 -5
- package/dist/{build-CPnSLYME.js.map → build-DJcc95Yq.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{codegen-BqpLGLLs.js → codegen-aJSyPz-J.js} +4 -4
- package/dist/{codegen-BqpLGLLs.js.map → codegen-aJSyPz-J.js.map} +1 -1
- package/dist/command-diff-BK912Hjc.js +78 -0
- package/dist/command-diff-BK912Hjc.js.map +1 -0
- package/dist/commands-CIPWQtF0.js +3 -0
- package/dist/commands-Clpbqq3K.js +15 -0
- package/dist/commands-Clpbqq3K.js.map +1 -0
- package/dist/{commands-ExM8HILu.js → commands-DVC7ky6f.js} +259 -9
- package/dist/commands-DVC7ky6f.js.map +1 -0
- package/dist/completions-D2KYtrrv.js +161 -0
- package/dist/completions-D2KYtrrv.js.map +1 -0
- package/dist/{dev-4wpEQC7l.js → dev-oPPVR7d_.js} +432 -45
- package/dist/dev-oPPVR7d_.js.map +1 -0
- package/dist/{diagnostics-CZBVxlpj.js → diagnostics-BysbNnPD.js} +38 -1
- package/dist/diagnostics-BysbNnPD.js.map +1 -0
- package/dist/doctor-DkVUwgDd.js +334 -0
- package/dist/doctor-DkVUwgDd.js.map +1 -0
- package/dist/{errors-Crt4hu0b.js → errors-COFWKKKw.js} +5 -2
- package/dist/errors-COFWKKKw.js.map +1 -0
- package/dist/hooks-Cy6F2bhH.js +332 -0
- package/dist/hooks-Cy6F2bhH.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/{info-CdiQajgn.js → info-CKJVMWIT.js} +16 -5
- package/dist/info-CKJVMWIT.js.map +1 -0
- package/dist/{locales-C7X8VNmK.js → locales-BJAP4HYf.js} +5 -5
- package/dist/{locales-C7X8VNmK.js.map → locales-BJAP4HYf.js.map} +1 -1
- package/dist/log-view-B7uJEnMR.js +342 -0
- package/dist/log-view-B7uJEnMR.js.map +1 -0
- package/dist/{nitro-sP2F3SQu.js → nitro-B8u1iVgf.js} +2 -2
- package/dist/{nitro-sP2F3SQu.js.map → nitro-B8u1iVgf.js.map} +1 -1
- package/dist/{plain-B6z85uQP.js → plain-DG7cy0Kk.js} +7 -2
- package/dist/plain-DG7cy0Kk.js.map +1 -0
- package/dist/{prepare-B4ysyG6H.js → prepare-BM93i3Rm.js} +9 -5
- package/dist/prepare-BM93i3Rm.js.map +1 -0
- package/dist/{project-MD4dIo2X.js → project-zlQStwsf.js} +2 -2
- package/dist/{project-MD4dIo2X.js.map → project-zlQStwsf.js.map} +1 -1
- package/dist/{run-Ddwrxe1O.js → run-DMM2YlP3.js} +3 -13
- package/dist/run-DMM2YlP3.js.map +1 -0
- package/dist/{theme-3Fc_LI-2.js → theme-yS2h5dd_.js} +25 -1
- package/dist/theme-yS2h5dd_.js.map +1 -0
- package/dist/tsc-C5l5TQGC.js +3 -0
- package/dist/{tsc-DO7D_uCl.js → tsc-puVAcwmo.js} +24 -5
- package/dist/tsc-puVAcwmo.js.map +1 -0
- package/dist/{tsdown-CD68G8_U.js → tsdown-Dwt3JhPw.js} +2 -2
- package/dist/{tsdown-CD68G8_U.js.map → tsdown-Dwt3JhPw.js.map} +1 -1
- package/dist/{tui-BRddrLQP.js → tui-nldGSD4c.js} +913 -141
- package/dist/tui-nldGSD4c.js.map +1 -0
- package/dist/{vite-CLyB6wl7.js → vite-YZUtv2Hk.js} +2 -2
- package/dist/{vite-CLyB6wl7.js.map → vite-YZUtv2Hk.js.map} +1 -1
- package/package.json +5 -4
- package/dist/_shared-B-hRZDRS.js.map +0 -1
- package/dist/commands-ExM8HILu.js.map +0 -1
- package/dist/dev-4wpEQC7l.js.map +0 -1
- package/dist/diagnostics-CZBVxlpj.js.map +0 -1
- package/dist/errors-Crt4hu0b.js.map +0 -1
- package/dist/hooks-H9kjLCMk.js +0 -148
- package/dist/hooks-H9kjLCMk.js.map +0 -1
- package/dist/info-CdiQajgn.js.map +0 -1
- package/dist/log-buffer-CY82aqnb.js +0 -72
- package/dist/log-buffer-CY82aqnb.js.map +0 -1
- package/dist/plain-B6z85uQP.js.map +0 -1
- package/dist/prepare-B4ysyG6H.js.map +0 -1
- package/dist/run-Ddwrxe1O.js.map +0 -1
- package/dist/theme-3Fc_LI-2.js.map +0 -1
- package/dist/tsc-DO7D_uCl.js.map +0 -1
- package/dist/tsc-YnAWKn3n.js +0 -3
- package/dist/tui-BRddrLQP.js.map +0 -1
- package/dist/tunnel-DT1FH6oA.js +0 -175
- package/dist/tunnel-DT1FH6oA.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui-nldGSD4c.js","names":["LEVEL_TOKENS","KEYS"],"sources":["../src/dev/tui/ink/hooks/useLogVersion.ts","../src/dev/tui/ink/theme.tsx","../src/dev/tui/ink/components/LogPane.tsx","../src/dev/tui/ink/components/PromptCard.tsx","../src/dev/tui/panel-logic.ts","../src/dev/tui/ink/hooks/useUptime.ts","../src/dev/tui/ink/components/Sidebar.tsx","../src/dev/tui/ink/components/Dashboard.tsx","../src/dev/tui/ink/components/HelpOverlay.tsx","../src/dev/tui/ink/components/Hints.tsx","../src/dev/tui/ink/components/LogBrowser.tsx","../src/dev/tui/ink/hooks/useDevStatus.ts","../src/dev/tui/ink/components/InfoOverlay.tsx","../src/dev/tui/ink/components/Panel.tsx","../src/dev/tui/ink/hooks/useLogCounters.ts","../src/dev/tui/ink/hooks/useBuildClock.ts","../src/dev/open-url.ts","../src/dev/tui/ink/components/ThemeOverlay.tsx","../src/dev/tui/ink/DevApp.tsx","../src/dev/tui/capture-output.ts","../src/dev/tui/tui.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport type { LogBuffer } from '../../../../utils/log-buffer.js';\n\n/** Bumps whenever the buffer changes, so a consumer can re-derive a filtered view without re-filtering on every render. */\nexport function useLogVersion(logs: LogBuffer): number {\n\tconst [version, setVersion] = useState(0);\n\n\tuseEffect(() => {\n\t\tconst bump = () => setVersion((current) => current + 1);\n\t\tlogs.on('entry', bump);\n\t\tlogs.on('clear', bump);\n\t\tbump();\n\t\treturn () => {\n\t\t\tlogs.off('entry', bump);\n\t\t\tlogs.off('clear', bump);\n\t\t};\n\t}, [logs]);\n\n\treturn version;\n}\n","import { createContext, useContext, type ReactNode } from 'react';\nimport { THEMES, type ThemeName, type ThemeToken } from '../../../utils/theme.js';\n\ninterface ThemeState {\n\t/** Whether the UI may use colour. */\n\tcolor: boolean;\n\ttheme: ThemeName;\n}\n\n/**\n * `stars dev` decides once whether the UI may use colour (`NO_COLOR`, `FORCE_COLOR`, TTY detection) and which theme\n * to paint with; every component reads both from here instead of re-deriving them.\n */\nconst ThemeContext = createContext<ThemeState>({ color: true, theme: 'dark' });\n\nexport function ThemeProvider({ color, theme, children }: ThemeState & { children: ReactNode }) {\n\treturn <ThemeContext value={{ color, theme }}>{children}</ThemeContext>;\n}\n\n/**\n * Returns a theme colour only when colour is enabled, so `<Text color={usePaint()('success')}>` degrades to plain text.\n */\nexport function usePaint(): (token: ThemeToken) => string | undefined {\n\tconst { color, theme } = useContext(ThemeContext);\n\treturn (token) => (color ? THEMES[theme][token] : undefined);\n}\n\nexport function useColorEnabled(): boolean {\n\treturn useContext(ThemeContext).color;\n}\n","import { Box, Text } from 'ink';\nimport type { ThemeToken } from '../../../../utils/theme.js';\nimport { formatClock, highlight, levelBadge, type LogRow, type TokenKind } from '../../log-view.js';\nimport { useColorEnabled, usePaint } from '../theme.js';\n\nexport interface LogPaneProps {\n\trows: readonly LogRow[];\n\t/** One past the last row shown; rows above it fill the pane. */\n\tend: number;\n\twidth: number;\n\theight: number;\n\t/** The width the channel column is padded to. */\n\tchannelWidth: number;\n\t/** The entry the view jumped to (`e`), marked in the gutter. */\n\tmarked: number | null;\n}\n\nconst LEVEL_TOKENS = { trace: 'trace', debug: 'debug', info: 'info', success: 'success', warn: 'warning', error: 'error' } as const;\nconst SEGMENT_TOKENS: Record<TokenKind, ThemeToken | null> = {\n\turl: 'url',\n\tpath: null,\n\tnumber: 'accent',\n\tname: 'trace',\n\tdim: null,\n\tok: 'success',\n\twarn: 'warning',\n\terror: 'error'\n};\n/** The colours a channel's dot is picked from, by name, so a channel keeps its colour for the whole session. */\nconst CHANNEL_TOKENS: readonly ThemeToken[] = ['info', 'debug', 'trace', 'accent', 'url', 'tunnel'];\n\nexport function channelToken(channel: string): ThemeToken {\n\tlet hash = 0;\n\tfor (const character of channel) hash = (hash * 31 + character.codePointAt(0)!) >>> 0;\n\treturn CHANNEL_TOKENS[hash % CHANNEL_TOKENS.length]!;\n}\n\n/** The log stream: one line per row, the newest at the bottom unless the view is scrolled. */\nexport function LogPane({ rows, end, width, height, channelWidth, marked }: LogPaneProps) {\n\tconst paint = usePaint();\n\tconst color = useColorEnabled();\n\tconst visible = rows.slice(Math.max(0, end - height), end);\n\t// ` B hh:mm:ss channel ● `, which detail lines are indented by.\n\tconst gutter = ' '.repeat(3 + 2 + 8 + 2 + channelWidth + 1);\n\n\treturn (\n\t\t<Box flexDirection=\"column\" width={width} height={height} overflow=\"hidden\" justifyContent=\"flex-end\">\n\t\t\t{visible.length === 0 && <Text dimColor> no matching logs</Text>}\n\t\t\t{visible.map((row, index) => {\n\t\t\t\tconst key = `${end - visible.length + index}`;\n\t\t\t\tif (row.kind === 'rule') {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Text key={key} dimColor wrap=\"truncate-end\">\n\t\t\t\t\t\t\t{'─'.repeat(width)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (row.kind === 'header') {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t\t\t\t<Text bold color={paint(channelToken(row.channel))}>{` ${row.channel}`}</Text>\n\t\t\t\t\t\t\t<Text dimColor>{` · ${row.count}`}</Text>\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst { entry } = row;\n\t\t\t\tconst failed = entry.level === 'error';\n\t\t\t\tif (row.kind === 'detail') {\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t\t\t\t{gutter}\n\t\t\t\t\t\t\t<Text dimColor>{'│ '}</Text>\n\t\t\t\t\t\t\t<Message text={row.text} channel={entry.channel} color={failed ? paint('error') : undefined} dim={!failed} />\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst level = LEVEL_TOKENS[entry.level];\n\t\t\t\treturn (\n\t\t\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t\t\t{color ? (\n\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\tbold\n\t\t\t\t\t\t\t\tbackgroundColor={paint(level)}\n\t\t\t\t\t\t\t\tcolor={paint(failed ? 'onError' : 'onBright')}\n\t\t\t\t\t\t\t>{` ${levelBadge(entry.level)} `}</Text>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Text bold>{`[${levelBadge(entry.level)}]`}</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Text color={paint('brand')}>{entry.id === marked ? '▎' : ' '}</Text>{' '}\n\t\t\t\t\t\t<Text dimColor={!failed} color={failed ? paint('error') : undefined}>\n\t\t\t\t\t\t\t{formatClock(entry.time)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t<Text bold={failed} color={failed ? paint('error') : undefined}>\n\t\t\t\t\t\t\t{entry.channel.slice(0, channelWidth).padStart(channelWidth)}\n\t\t\t\t\t\t</Text>{' '}\n\t\t\t\t\t\t<Text color={paint(channelToken(entry.channel))}>●</Text>{' '}\n\t\t\t\t\t\t<Message text={row.text} channel={entry.channel} color={entry.level === 'warn' ? paint('warning') : undefined} />\n\t\t\t\t\t</Text>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Box>\n\t);\n}\n\nfunction Message({ text, channel, color, dim = false }: { text: string; channel: string; color?: string | undefined; dim?: boolean }) {\n\tconst paint = usePaint();\n\treturn (\n\t\t<Text color={color} dimColor={dim}>\n\t\t\t{highlight(text, channel).map((segment, index) => {\n\t\t\t\tif (segment.token === undefined) return segment.text;\n\t\t\t\tconst token = SEGMENT_TOKENS[segment.token];\n\t\t\t\treturn (\n\t\t\t\t\t<Text key={index} color={token === null ? color : paint(token)} dimColor={token === null || dim} bold={segment.token === 'name'}>\n\t\t\t\t\t\t{segment.text}\n\t\t\t\t\t</Text>\n\t\t\t\t);\n\t\t\t})}\n\t\t</Text>\n\t);\n}\n","import { Box, Text } from 'ink';\nimport { describeCommand } from '../../../../utils/command-diff.js';\nimport type { DevPrompt } from '../../../dev-service.js';\nimport { usePaint } from '../theme.js';\n\n/** The rows a prompt takes, border included, so the log pane above it can be sized. */\nexport function promptHeight(prompt: DevPrompt, available: number): number {\n\treturn Math.min(Math.max(4, available), prompt.changes.length + 4);\n}\n\n/**\n * The card under the log stream that asks before the bot's commands are deployed again: a redeploy changes what\n * every user of the application sees, so it is never done behind the developer's back.\n */\nexport function PromptCard({ prompt, width, height }: { prompt: DevPrompt; width: number; height: number }) {\n\tconst paint = usePaint();\n\t// Border (2), title and question leave the rest to the list.\n\tconst room = Math.max(0, height - 4);\n\tconst shown = prompt.changes.slice(0, prompt.changes.length > room ? Math.max(0, room - 1) : room);\n\tconst more = prompt.changes.length - shown.length;\n\n\treturn (\n\t\t<Box flexDirection=\"column\" width={width} height={height} borderStyle=\"single\" borderColor={paint('accent')} paddingX={1}>\n\t\t\t<Text bold color={paint('accent')} wrap=\"truncate-end\">\n\t\t\t\tCommands updated:\n\t\t\t</Text>\n\t\t\t{shown.map((change) => (\n\t\t\t\t<Text key={`${change.guild}:${change.type}:${change.name}`} wrap=\"truncate-end\">\n\t\t\t\t\t<Text dimColor>{'- '}</Text>\n\t\t\t\t\t<Text color={paint(change.kind === 'removed' ? 'error' : change.kind === 'added' ? 'success' : 'url')}>\n\t\t\t\t\t\t{describeCommand(change)}\n\t\t\t\t\t</Text>\n\t\t\t\t\t<Text dimColor>{` ${change.kind}`}</Text>\n\t\t\t\t</Text>\n\t\t\t))}\n\t\t\t{more > 0 && <Text dimColor>{` and ${more} more`}</Text>}\n\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\tRefresh commands? <Text dimColor>(y/n)</Text>\n\t\t\t</Text>\n\t\t</Box>\n\t);\n}\n","import type { DevStatus } from '../dev-service.js';\n\nexport type Badge = 'starting' | 'building' | 'restarting' | 'ready' | 'error' | 'stopped';\n\n/** Whether the badge describes work in progress, as opposed to a state the session rests in. */\nexport function isBusy(badge: Badge): boolean {\n\treturn badge === 'starting' || badge === 'building' || badge === 'restarting';\n}\n\n/**\n * The badge and standing description for the panel's status row, mirroring the states Nuxt CLI v4's own dev panel\n * cycles through (`STARTING`/`BUILDING`/`RESTART`/`READY`/`ERROR`).\n */\nexport function describeBadge(status: DevStatus): { badge: Badge; note: string } {\n\tif (status.build === 'building') return { badge: status.startedAt === null ? 'starting' : 'building', note: status.progress.message };\n\tif (status.process === 'starting') return { badge: 'starting', note: 'starting the bot' };\n\tif (status.paused) return { badge: 'stopped', note: 'the bot is stopped, press r to start it' };\n\tif (status.process === 'stopping') return { badge: 'restarting', note: 'restarting the bot' };\n\tif (status.build === 'failed') return { badge: 'error', note: 'build failed, waiting for changes' };\n\tif (status.process === 'crashed') return { badge: 'error', note: 'the bot crashed, press r to restart' };\n\tif (status.health === 'down') return { badge: 'error', note: 'health check failed' };\n\tif (status.typecheck === 'failed') return { badge: 'error', note: 'type check failed, press e to view it' };\n\tif (status.process === 'stopped') return { badge: 'error', note: 'the bot stopped, press r to restart' };\n\tif (status.progress.fraction < 1) return { badge: 'starting', note: status.progress.message };\n\tif (status.process === 'running') return { badge: 'ready', note: 'watching for changes' };\n\treturn { badge: 'starting', note: 'waiting for the first build' };\n}\n\n/** Formats an uptime the way a status line reads it: `35s`, `3m 35s`, `2h 04m`. */\nexport function formatUptime(milliseconds: number): string {\n\tconst total = Math.max(0, Math.floor(milliseconds / 1000));\n\tconst seconds = total % 60;\n\tconst minutes = Math.floor(total / 60) % 60;\n\tconst hours = Math.floor(total / 3600);\n\tif (hours > 0) return `${hours}h ${minutes.toString().padStart(2, '0')}m`;\n\treturn minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;\n}\n\n/** Formats a duration the way a dev session reads it: `mm:ss` under an hour, `h:mm:ss` above. */\nexport function formatDuration(milliseconds: number): string {\n\tconst total = Math.max(0, Math.floor(milliseconds / 1000));\n\tconst seconds = total % 60;\n\tconst minutes = Math.floor(total / 60) % 60;\n\tconst hours = Math.floor(total / 3600);\n\tconst pad = (value: number) => value.toString().padStart(2, '0');\n\n\treturn hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${pad(minutes)}:${pad(seconds)}`;\n}\n","import { useEffect, useState } from 'react';\n\n/**\n * Re-renders once a second while the bot is up, so the uptime in the header keeps counting.\n */\nexport function useUptime(startedAt: number | null): number | null {\n\tconst [now, setNow] = useState(() => Date.now());\n\n\tuseEffect(() => {\n\t\tif (startedAt === null) return;\n\n\t\tsetNow(Date.now());\n\t\tconst timer = setInterval(() => setNow(Date.now()), 1000);\n\t\treturn () => clearInterval(timer);\n\t}, [startedAt]);\n\n\treturn startedAt === null ? null : now - startedAt;\n}\n","import { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport type { ResolvedStarsConfig, StarsLogLevel } from '@wolfstar/schema';\nimport { displayPath } from '@wolfstar/schema';\nimport { findInstalledVersion } from '../../../../utils/project.js';\nimport { readOwnPackageJson } from '../../../../utils/version.js';\nimport type { DevStatus } from '../../../dev-service.js';\nimport { isChannelVisible, VIEW_LEVELS, windowAround, wrapLabels, type LogViewFilter } from '../../log-view.js';\nimport { describeBadge, formatUptime, isBusy } from '../../panel-logic.js';\nimport { useUptime } from '../hooks/useUptime.js';\nimport { usePaint } from '../theme.js';\nimport type { LogCounters } from '../hooks/useLogCounters.js';\nimport { channelToken } from './LogPane.js';\n\nexport type SidebarGroup = 'channels' | 'levels';\n\nexport interface SidebarFocus {\n\tgroup: SidebarGroup;\n\tindex: number;\n}\n\nexport interface SidebarProps {\n\tstatus: DevStatus;\n\tconfig: ResolvedStarsConfig;\n\tcounters: LogCounters;\n\tfilter: LogViewFilter;\n\tchannels: readonly string[];\n\tfocus: SidebarFocus;\n\tcollapsed: Readonly<Record<SidebarGroup, boolean>>;\n\t/** Whether the log pane follows the newest entry. */\n\tlive: boolean;\n\tgrouped: boolean;\n\tframe: number;\n\telapsedMs: number;\n\twidth: number;\n\theight: number;\n\tconfirmQuit: boolean;\n}\n\nconst LEVEL_TOKENS = { error: 'error', warn: 'warning', info: 'info', debug: 'debug', trace: 'trace' } as const;\nconst SPINNER = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst KEYS: readonly (readonly [key: string, label: string])[][] = [\n\t[\n\t\t['←→', 'select'],\n\t\t['tab', 'group'],\n\t\t['space', 'filter'],\n\t\t['s', 'solo']\n\t],\n\t[\n\t\t['q', 'quit'],\n\t\t['r', 'restart'],\n\t\t['d', 'disconnect'],\n\t\t['c', 'clear'],\n\t\t['↑↓', 'scroll'],\n\t\t['g/G', 'top/bottom'],\n\t\t['?', 'help']\n\t]\n];\n\nlet frameworkVersion: { root: string; version: string | null } | null = null;\n\n/** Looked up once per project: it walks `node_modules`, and the sidebar repaints on every log entry. */\nfunction readFrameworkVersion(root: string): string | null {\n\tif (frameworkVersion?.root !== root) frameworkVersion = { root, version: findInstalledVersion(root, '@wolfstar/http-framework') };\n\treturn frameworkVersion.version;\n}\n\n/**\n * The left column of the dashboard: what the session is doing, the filters of the log stream, and the keys. Under a\n * short terminal the key help goes first, then the filters' own hints: the status and the filters are what it is for.\n */\nexport function Sidebar(props: SidebarProps) {\n\tconst { status, config, counters, filter, channels, focus, collapsed, live, grouped, frame, elapsedMs, width, height, confirmQuit } = props;\n\tconst paint = usePaint();\n\tconst uptime = useUptime(status.startedAt);\n\tconst state = describeBadge(status);\n\tconst busy = isBusy(state.badge);\n\tconst failed = state.badge === 'error';\n\tconst name = config.packageJson?.name ?? 'stars project';\n\tconst inner = Math.max(1, width - 2);\n\n\tconst row = (label: string, value: ReactNode, key = label) => (\n\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t<Text dimColor>{label.padEnd(8)}</Text>\n\t\t\t{value}\n\t\t</Text>\n\t);\n\n\tconst stateColor = paint(failed ? 'error' : busy || state.badge === 'stopped' ? 'busy' : 'success');\n\tconst tunnel =\n\t\tstatus.tunnel === 'up' ? (\n\t\t\t<Text color={paint('tunnel')}>live</Text>\n\t\t) : status.tunnel === 'starting' ? (\n\t\t\t<Text color={paint('busy')}>connecting</Text>\n\t\t) : status.tunnel === 'failed' ? (\n\t\t\t<Text color={paint('error')}>failed</Text>\n\t\t) : (\n\t\t\t<Text dimColor>off</Text>\n\t\t);\n\tconst port = status.port ?? (status.url ? new URL(status.url).port || null : null);\n\tconst framework = readFrameworkVersion(config.root);\n\n\tconst head: ReactNode[] = [\n\t\t<Text key=\"title\" wrap=\"truncate-end\">\n\t\t\t<Text bold color={paint('brand')}>\n\t\t\t\t{name}\n\t\t\t</Text>\n\t\t\t<Text dimColor>{` • stars v${readOwnPackageJson().version}`}</Text>\n\t\t</Text>,\n\t\t<Text key=\"gap-title\"> </Text>,\n\t\t<Text key=\"state\" wrap=\"truncate-end\">\n\t\t\t<Text color={stateColor}>{busy ? SPINNER[frame % SPINNER.length] : failed ? '✖' : '●'}</Text>{' '}\n\t\t\t<Text bold color={stateColor}>\n\t\t\t\t{confirmQuit ? 'quit?' : state.badge === 'ready' ? 'running' : state.badge}\n\t\t\t</Text>\n\t\t\t{busy && <Text dimColor>{` ${Math.round(status.progress.fraction * 100)}% · ${(elapsedMs / 1000).toFixed(1)}s`}</Text>}\n\t\t</Text>,\n\t\t<Text key=\"note\" wrap=\"truncate-end\">\n\t\t\t{confirmQuit ? (\n\t\t\t\t<Text dimColor>press y to confirm, esc to stay</Text>\n\t\t\t) : state.badge === 'ready' ? (\n\t\t\t\t<>\n\t\t\t\t\t<Text bold>{name}</Text> is ready!\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<Text dimColor>{state.note}</Text>\n\t\t\t)}\n\t\t</Text>,\n\t\trow('http', framework ? `v${framework}` : <Text dimColor>not installed</Text>),\n\t\trow('up', uptime === null ? <Text dimColor>—</Text> : formatUptime(uptime)),\n\t\trow('port', port ?? <Text dimColor>—</Text>),\n\t\trow('tunnel', tunnel),\n\t\trow('logs', config.dev.logFile ? displayPath(config.root, config.dev.logFile) : <Text dimColor>off</Text>),\n\t\t...(config.dev.typecheck.enabled\n\t\t\t? [\n\t\t\t\t\trow(\n\t\t\t\t\t\t'types',\n\t\t\t\t\t\tstatus.typecheck === 'failed' ? (\n\t\t\t\t\t\t\t<Text color={paint('error')}>{`${status.typeErrors} ${status.typeErrors === 1 ? 'error' : 'errors'}`}</Text>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\tstatus.typecheck\n\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t\t]\n\t\t\t: []),\n\t\t...(counters.errors > 0 || counters.warnings > 0\n\t\t\t? [\n\t\t\t\t\t<Text key=\"counters\" wrap=\"truncate-end\">\n\t\t\t\t\t\t{counters.errors > 0 && <Text bold color={paint('error')}>{`✖ ${counters.errors} `}</Text>}\n\t\t\t\t\t\t{counters.warnings > 0 && <Text color={paint('warning')}>{`⚠ ${counters.warnings}`}</Text>}\n\t\t\t\t\t</Text>\n\t\t\t\t]\n\t\t\t: [])\n\t];\n\n\tconst groupHeader = (group: SidebarGroup, suffix = '') => (\n\t\t<Text key={`${group}-header`} wrap=\"truncate-end\">\n\t\t\t<Text color={focus.group === group ? paint('brand') : undefined}>{collapsed[group] ? '▸' : '▾'}</Text>{' '}\n\t\t\t<Text bold={focus.group === group} dimColor={focus.group !== group}>\n\t\t\t\t{group}\n\t\t\t</Text>\n\t\t\t{group === 'channels' && grouped && <Text dimColor> · grouped</Text>}\n\t\t\t{suffix && <Text dimColor>{suffix}</Text>}\n\t\t</Text>\n\t);\n\n\tconst item = (group: SidebarGroup, index: number, label: string, on: boolean, token: Parameters<typeof paint>[0]) => {\n\t\tconst focused = focus.group === group && focus.index === index;\n\t\treturn (\n\t\t\t<Text key={label} color={on ? paint(token) : undefined} dimColor={!on} strikethrough={!on} underline={focused} bold={focused}>\n\t\t\t\t{label}\n\t\t\t</Text>\n\t\t);\n\t};\n\n\tconst budget = Math.max(1, height - 1);\n\tconst labelWidth = Math.max(1, inner - 2);\n\tconst lines = (group: SidebarGroup, labels: readonly string[], nodes: readonly ReactNode[], range: [number, number] = [0, Infinity]) =>\n\t\twrapLabels(labels, labelWidth)\n\t\t\t.slice(...range)\n\t\t\t.map((line, index) => (\n\t\t\t\t<Text key={`${group}-${index}`} wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t{line.flatMap((label, position) => (position > 0 ? [' ', nodes[label]] : [nodes[label]]))}\n\t\t\t\t</Text>\n\t\t\t));\n\n\tconst levelNodes = VIEW_LEVELS.map((level: StarsLogLevel, index) => item('levels', index, level, filter.levels.has(level), LEVEL_TOKENS[level]));\n\tconst levelLines = collapsed.levels ? [] : lines('levels', VIEW_LEVELS, levelNodes);\n\tconst channelNodes = channels.map((channel, index) => item('channels', index, channel, isChannelVisible(filter, channel), channelToken(channel)));\n\t// The levels always stay in sight: many channels scroll inside the rows left over, around the selected one.\n\tconst channelLayout = wrapLabels(channels, labelWidth);\n\tconst focusedLine =\n\t\tfocus.group === 'channels'\n\t\t\t? Math.max(\n\t\t\t\t\t0,\n\t\t\t\t\tchannelLayout.findIndex((line) => line.includes(focus.index))\n\t\t\t\t)\n\t\t\t: 0;\n\tconst range = windowAround(channelLayout.length, focusedLine, Math.max(1, budget - head.length - 3 - levelLines.length));\n\tconst hiddenChannels = channelLayout.length - (range[1] - range[0]);\n\n\tconst filters: ReactNode[] = [\n\t\t<Text key=\"gap-filters\"> </Text>,\n\t\tgroupHeader('channels', !collapsed.channels && hiddenChannels > 0 ? ` · ${range[0] + 1}-${range[1]}/${channelLayout.length}` : ''),\n\t\t...(collapsed.channels ? [] : lines('channels', channels, channelNodes, range)),\n\t\tgroupHeader('levels'),\n\t\t...levelLines\n\t];\n\n\tconst keys = KEYS.map((section, sectionIndex) => [\n\t\t<Text key={`gap-keys-${sectionIndex}`}> </Text>,\n\t\t...section.map(([key, label]) => (\n\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t<Text bold color={paint('url')}>\n\t\t\t\t\t{key}\n\t\t\t\t</Text>{' '}\n\t\t\t\t<Text dimColor>{label}</Text>\n\t\t\t</Text>\n\t\t))\n\t]);\n\n\t// The footer keeps the last line; everything else is dropped from the bottom up when the terminal is short.\n\tlet body = [...head, ...filters, ...keys.flat()];\n\tif (body.length > budget) body = [...head, ...filters, ...keys[1]!];\n\tif (body.length > budget) body = [...head, ...filters];\n\tbody = body.slice(0, budget);\n\n\treturn (\n\t\t<Box flexDirection=\"column\" width={width} height={height} paddingX={1}>\n\t\t\t{body.map((node, index) => (\n\t\t\t\t<Box key={index} height={1} width={inner}>\n\t\t\t\t\t{node}\n\t\t\t\t</Box>\n\t\t\t))}\n\t\t\t<Box flexGrow={1} />\n\t\t\t<Box height={1} width={inner} justifyContent=\"flex-end\">\n\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t<Text color={paint(live ? 'error' : 'busy')}>●</Text> <Text dimColor>{live ? 'live' : 'paused'}</Text>\n\t\t\t\t</Text>\n\t\t\t</Box>\n\t\t</Box>\n\t);\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useEffect, useMemo, useState } from 'react';\nimport type { DevService, DevStatus } from '../../../dev-service.js';\nimport {\n\tbuildRows,\n\tmatchesView,\n\tnewestErrorRow,\n\tpinAt,\n\tpinnedEnd,\n\tsoloChannel,\n\tsoloLevel,\n\ttoggleChannel,\n\ttoggleLevel,\n\tVIEW_LEVELS,\n\ttype LogPin,\n\ttype LogViewFilter\n} from '../../log-view.js';\nimport type { LogCounters } from '../hooks/useLogCounters.js';\nimport { useLogVersion } from '../hooks/useLogVersion.js';\nimport { usePaint } from '../theme.js';\nimport { LogPane } from './LogPane.js';\nimport { PromptCard, promptHeight } from './PromptCard.js';\nimport { Sidebar, type SidebarFocus, type SidebarGroup } from './Sidebar.js';\n\nexport interface DashboardProps {\n\tservice: DevService;\n\tstatus: DevStatus;\n\tcounters: LogCounters;\n\tframe: number;\n\telapsedMs: number;\n\twidth: number;\n\theight: number;\n\tconfirmQuit: boolean;\n\t/** The filter the session starts with (`dev.logs`, `--channel`, `--level`). */\n\tinitialFilter: LogViewFilter;\n\t/** Whether the dashboard is the view on screen: an overlay above it takes the keys. */\n\tactive: boolean;\n\t/** Tells the app that typed characters are text (the search box), not shortcuts. */\n\tonCapture: (capturing: boolean) => void;\n}\n\n/** The sidebar takes about a quarter of the terminal, within what its longest lines need and can spare. */\nexport function sidebarWidth(columns: number): number {\n\treturn Math.max(24, Math.min(34, Math.floor(columns * 0.26)));\n}\n\n/**\n * The full-screen dev view: the session's state and the log filters on the left, the log stream on the right, and a\n * card under the stream when `stars dev` has something to ask. Everything it shows comes from the service; the keys\n * here only change what is looked at.\n */\nexport function Dashboard(props: DashboardProps) {\n\tconst { service, status, counters, frame, elapsedMs, width, height, confirmQuit, initialFilter, active, onCapture } = props;\n\tconst paint = usePaint();\n\tconst [filter, setFilter] = useState(initialFilter);\n\tconst [focus, setFocus] = useState<SidebarFocus>({ group: 'channels', index: 0 });\n\tconst [collapsed, setCollapsed] = useState<Record<SidebarGroup, boolean>>({ channels: false, levels: false });\n\tconst [grouped, setGrouped] = useState(false);\n\tconst [searching, setSearching] = useState(false);\n\t// Where the view stops while scrolled back; `null` follows the newest entry.\n\tconst [pinned, setPinned] = useState<LogPin | null>(null);\n\tconst [marked, setMarked] = useState<number | null>(null);\n\tconst version = useLogVersion(service.logs);\n\n\tconst channels = useMemo(\n\t\t() => [...new Set([...(initialFilter.allow ?? []), ...service.logs.channels()])].sort(),\n\t\t[service, initialFilter, version]\n\t);\n\tconst rows = useMemo(\n\t\t() =>\n\t\t\tbuildRows(\n\t\t\t\tservice.logs.entries().filter((entry) => matchesView(entry, filter)),\n\t\t\t\t{ group: grouped }\n\t\t\t),\n\t\t[service, filter, grouped, version]\n\t);\n\n\tuseEffect(() => {\n\t\tonCapture(searching);\n\t\t// Unmounted with the search box open (the terminal shrank to the panel): the keys go back to the app.\n\t\treturn () => onCapture(false);\n\t}, [searching, onCapture]);\n\n\tconst side = sidebarWidth(width);\n\t// The pane's left border takes one column.\n\tconst mainWidth = Math.max(1, width - side - 1);\n\tconst searchRows = searching || filter.query ? 1 : 0;\n\tconst cardRows = status.prompt ? promptHeight(status.prompt, Math.max(4, height - searchRows - 3)) : 0;\n\tconst paneHeight = Math.max(1, height - searchRows - cardRows);\n\tconst end = pinnedEnd(rows, pinned, paneHeight);\n\tconst channelWidth = Math.min(12, Math.max(3, ...channels.map((channel) => channel.length)));\n\tconst items = focus.group === 'channels' ? channels : VIEW_LEVELS;\n\n\tconst change = (next: LogViewFilter) => {\n\t\tsetFilter(next);\n\t\tsetPinned(null);\n\t};\n\tconst scroll = (delta: number) => {\n\t\tsetPinned(pinAt(rows, Math.max(Math.min(paneHeight, rows.length), end + delta)));\n\t};\n\n\tuseInput(\n\t\t(input, key) => {\n\t\t\tif (key.ctrl || confirmQuit) return;\n\t\t\tif (searching) {\n\t\t\t\tif (key.escape) {\n\t\t\t\t\tsetSearching(false);\n\t\t\t\t\tchange({ ...filter, query: '' });\n\t\t\t\t} else if (key.return) setSearching(false);\n\t\t\t\telse if (key.backspace || key.delete) change({ ...filter, query: [...filter.query].slice(0, -1).join('') });\n\t\t\t\telse if (input && !key.upArrow && !key.downArrow && !key.leftArrow && !key.rightArrow && !key.tab) {\n\t\t\t\t\tchange({ ...filter, query: filter.query + input });\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (key.escape) {\n\t\t\t\tif (filter.query) change({ ...filter, query: '' });\n\t\t\t\telse setPinned(null);\n\t\t\t\treturn setMarked(null);\n\t\t\t}\n\t\t\tif (input === '/') return setSearching(true);\n\t\t\tif (key.tab) return setFocus((current) => ({ group: current.group === 'channels' ? 'levels' : 'channels', index: 0 }));\n\t\t\tif (key.leftArrow || key.rightArrow) {\n\t\t\t\tif (items.length === 0) return;\n\t\t\t\tconst delta = key.leftArrow ? -1 : 1;\n\t\t\t\treturn setFocus((current) => ({ ...current, index: (current.index + delta + items.length) % items.length }));\n\t\t\t}\n\t\t\tif (key.return) return setCollapsed((current) => ({ ...current, [focus.group]: !current[focus.group] }));\n\t\t\tif (input === ' ' || input === 's') {\n\t\t\t\tconst target = items[Math.min(focus.index, items.length - 1)];\n\t\t\t\tif (target === undefined) return;\n\t\t\t\tif (focus.group === 'channels') return change(input === ' ' ? toggleChannel(filter, target) : soloChannel(filter, target));\n\t\t\t\tconst level = target as (typeof VIEW_LEVELS)[number];\n\t\t\t\treturn change(input === ' ' ? toggleLevel(filter, level) : soloLevel(filter, level));\n\t\t\t}\n\t\t\tif (input === 'a') return change({ ...filter, allow: null, hidden: new Set(), levels: new Set(VIEW_LEVELS), query: '' });\n\t\t\tif (input === 'b') {\n\t\t\t\tsetGrouped((current) => !current);\n\t\t\t\treturn setPinned(null);\n\t\t\t}\n\t\t\tif (key.upArrow || input === 'k') return scroll(-1);\n\t\t\tif (key.downArrow || input === 'j') return scroll(1);\n\t\t\tif (key.pageUp) return scroll(-Math.max(1, paneHeight - 1));\n\t\t\tif (key.pageDown) return scroll(Math.max(1, paneHeight - 1));\n\t\t\tif (key.home || input === 'g') return setPinned(pinAt(rows, Math.min(paneHeight, rows.length)));\n\t\t\tif (key.end || input === 'G') return setPinned(null);\n\t\t\tif (input === 'e') {\n\t\t\t\t// The most recent error of what is shown: grouped by channel, that is not the last row.\n\t\t\t\tconst index = newestErrorRow(rows);\n\t\t\t\tif (index < 0) return;\n\t\t\t\tconst row = rows[index]!;\n\t\t\t\tsetMarked(row.kind === 'entry' ? row.entry.id : null);\n\t\t\t\tsetPinned(pinAt(rows, Math.max(paneHeight, index + Math.ceil(paneHeight / 2))));\n\t\t\t}\n\t\t},\n\t\t{ isActive: active }\n\t);\n\n\treturn (\n\t\t<Box width={width} height={height}>\n\t\t\t<Sidebar\n\t\t\t\tstatus={status}\n\t\t\t\tconfig={service.config}\n\t\t\t\tcounters={counters}\n\t\t\t\tfilter={filter}\n\t\t\t\tchannels={channels}\n\t\t\t\tfocus={focus}\n\t\t\t\tcollapsed={collapsed}\n\t\t\t\tlive={pinned === null}\n\t\t\t\tgrouped={grouped}\n\t\t\t\tframe={frame}\n\t\t\t\telapsedMs={elapsedMs}\n\t\t\t\twidth={side}\n\t\t\t\theight={height}\n\t\t\t\tconfirmQuit={confirmQuit}\n\t\t\t/>\n\t\t\t<Box\n\t\t\t\tflexDirection=\"column\"\n\t\t\t\twidth={mainWidth + 1}\n\t\t\t\theight={height}\n\t\t\t\tborderStyle=\"single\"\n\t\t\t\tborderTop={false}\n\t\t\t\tborderRight={false}\n\t\t\t\tborderBottom={false}\n\t\t\t\tborderDimColor\n\t\t\t>\n\t\t\t\t<LogPane rows={rows} end={end} width={mainWidth} height={paneHeight} channelWidth={channelWidth} marked={marked} />\n\t\t\t\t{status.prompt && <PromptCard prompt={status.prompt} width={mainWidth} height={cardRows} />}\n\t\t\t\t{searchRows > 0 && (\n\t\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t\t<Text bold color={paint('url')}>\n\t\t\t\t\t\t\t{' / '}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t{filter.query}\n\t\t\t\t\t\t{searching ? '▏' : <Text dimColor> · esc clears</Text>}\n\t\t\t\t\t</Text>\n\t\t\t\t)}\n\t\t\t</Box>\n\t\t</Box>\n\t);\n}\n","import { Box, Text, useInput } from 'ink';\nimport { usePaint } from '../theme.js';\n\nconst KEYS: [string, string][] = [\n\t['r', 'restart the bot now'],\n\t['d', 'disconnect: stop the bot until the next r'],\n\t['o', 'open the local URL in a browser'],\n\t['t', 'toggle the public tunnel'],\n\t['i', 'show versions, URLs and session info'],\n\t['T', 'pick a colour theme (dark, light, colour-blind friendly, ANSI)'],\n\t['v', 'switch between the dashboard and the compact panel'],\n\t['l', 'open the logs (select, copy, filter by source or level)'],\n\t['e', 'jump to the last error, keeping its context'],\n\t['y / n', 'answer a prompt (refresh the commands)'],\n\t['c / Ctrl+L', 'clear the log history'],\n\t['q / Ctrl+C', 'stop the bot and quit'],\n\t['?', 'toggle this help'],\n\t['', ''],\n\t['dashboard', ''],\n\t['← / →', 'select a channel or a level'],\n\t['tab', 'switch between channels and levels'],\n\t['space', 'show or hide the selected one'],\n\t['s', 'solo: only the selected one, again for all'],\n\t['a', 'show every channel and level'],\n\t['enter', 'fold or unfold the selected group'],\n\t['b', 'group the stream by channel'],\n\t['↑ / ↓', 'scroll (PgUp/PgDn by page)'],\n\t['g / G', 'top / back to live'],\n\t['/', 'search (Esc clears)']\n];\n\nexport interface HelpOverlayProps {\n\theight: number;\n\twidth: number;\n\tonClose: () => void;\n}\n\n/** The static keys reference, opened with `?` from the pinned panel. */\nexport function HelpOverlay({ height, width, onClose }: HelpOverlayProps) {\n\tconst paint = usePaint();\n\tuseInput((input, key) => {\n\t\tif (!key.ctrl && (key.escape || ['q', 'h', '?'].includes(input))) onClose();\n\t});\n\n\treturn (\n\t\t<Box flexDirection=\"column\" height={height}>\n\t\t\t<Text bold> keyboard shortcuts</Text>\n\t\t\t<Text dimColor>{'─'.repeat(width)}</Text>\n\t\t\t{KEYS.slice(0, Math.max(0, height - 3)).map(([key, description], index) => (\n\t\t\t\t<Text key={index} wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t<Text bold color={paint('text')}>\n\t\t\t\t\t\t{key.padEnd(14)}\n\t\t\t\t\t</Text>\n\t\t\t\t\t<Text dimColor>{description}</Text>\n\t\t\t\t</Text>\n\t\t\t))}\n\t\t\t<Box flexGrow={1} />\n\t\t\t<Text dimColor> q close</Text>\n\t\t</Box>\n\t);\n}\n","import { Text } from 'ink';\n\nexport interface Hint {\n\tkey: string;\n\tlabel: string;\n\tpriority: number;\n}\n\nexport const PANEL_HINTS: Hint[] = [\n\t{ key: 'r', label: 'restart', priority: 80 },\n\t{ key: 'o', label: 'open', priority: 40 },\n\t{ key: 't', label: 'tunnel', priority: 60 },\n\t{ key: 'i', label: 'info', priority: 50 },\n\t{ key: 'T', label: 'theme', priority: 30 },\n\t{ key: 'l', label: 'logs', priority: 70 },\n\t{ key: '?', label: 'help', priority: 100 },\n\t{ key: 'q', label: 'quit', priority: 90 }\n];\n\n/** Drop the lowest-priority shortcuts first; help and the last error survive narrow panes. */\nexport function Hints({ hints, width }: { hints: readonly Hint[]; width: number }) {\n\tconst shown = [...hints];\n\tconst length = () => shown.reduce((size, hint) => size + hint.key.length + hint.label.length + 4, -2);\n\twhile (shown.length > 1 && length() > width) {\n\t\tconst weakest = shown.reduce((a, b) => (a.priority <= b.priority ? a : b));\n\t\tshown.splice(shown.indexOf(weakest), 1);\n\t}\n\treturn (\n\t\t<Text wrap=\"truncate-end\">\n\t\t\t{' '}\n\t\t\t{shown.map(({ key, label }, i) => (\n\t\t\t\t<Text key={key}>\n\t\t\t\t\t{i > 0 && <Text dimColor> · </Text>}\n\t\t\t\t\t<Text bold>{key}</Text>\n\t\t\t\t\t<Text dimColor>{` ${label}`}</Text>\n\t\t\t\t</Text>\n\t\t\t))}\n\t\t</Text>\n\t);\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useMemo, useState } from 'react';\nimport { stripVTControlCharacters } from 'node:util';\nimport type { DevService } from '../../../dev-service.js';\nimport { isErrorDetail, type LogEntry, type LogLevel } from '../../../../utils/log-buffer.js';\nimport { useLogVersion } from '../hooks/useLogVersion.js';\nimport { usePaint } from '../theme.js';\nimport { Hints } from './Hints.js';\n\nexport interface LogBrowserProps {\n\tservice: DevService;\n\theight: number;\n\twidth: number;\n\tlastError?: boolean;\n\tonClose: () => void;\n\tonCopy?: (text: string) => void;\n}\n\nconst group = (entry: LogEntry) => (entry.source === 'app' ? 'runtime' : entry.source === 'build' || entry.source === 'tsc' ? 'build' : 'cli');\n\n/** Filterable history, using Nuxt's keys and selecting the last error without discarding its context. */\nexport function LogBrowser({ service, height, width, lastError = false, onClose, onCopy }: LogBrowserProps) {\n\tconst paint = usePaint();\n\tconst [sources, setSources] = useState({ cli: true, build: true, runtime: true });\n\tconst [level, setLevel] = useState<LogLevel | null>(null);\n\tconst [query, setQuery] = useState('');\n\tconst [searching, setSearching] = useState(false);\n\tconst [selected, setSelected] = useState<number | null>(() =>\n\t\tlastError ? (service.logs.entries().findLast((entry) => entry.level === 'error' && !isErrorDetail(entry))?.id ?? null) : null\n\t);\n\tconst version = useLogVersion(service.logs);\n\tconst entries = useMemo(\n\t\t() =>\n\t\t\tservice.logs\n\t\t\t\t.filter({ level })\n\t\t\t\t.filter((entry) => sources[group(entry)] && stripVTControlCharacters(entry.text).toLowerCase().includes(query.toLowerCase())),\n\t\t[service, sources, level, query, version]\n\t);\n\tconst bodyHeight = Math.max(0, height - 3);\n\tconst index = entries.findIndex((entry) => entry.id === selected);\n\tconst rows = entries.flatMap((entry) =>\n\t\tstripVTControlCharacters(entry.text)\n\t\t\t.split('\\n')\n\t\t\t.map((line, i) => ({\n\t\t\t\tentry,\n\t\t\t\ttext: i === 0 ? `${new Date(entry.time).toLocaleTimeString()} ${entry.source.padEnd(6)} ${line}` : ` ${line}`\n\t\t\t}))\n\t);\n\tconst selectedStart = rows.findIndex((row) => row.entry.id === selected);\n\tconst selectedEnd = rows.findLastIndex((row) => row.entry.id === selected) + 1;\n\tconst end =\n\t\tindex < 0 ? rows.length : Math.min(rows.length, selectedStart + Math.max(bodyHeight, Math.min(selectedEnd - selectedStart, bodyHeight)));\n\tconst visible = rows.slice(Math.max(0, end - bodyHeight), end);\n\tconst move = (delta: number) => {\n\t\tif (!entries.length) return;\n\t\tconst next = index < 0 ? (delta < 0 ? entries.length - 1 : 0) : Math.max(0, Math.min(entries.length - 1, index + delta));\n\t\tsetSelected(entries[next]!.id);\n\t};\n\n\tuseInput((input, key) => {\n\t\tif (key.ctrl) return;\n\t\tif (searching) {\n\t\t\tif (key.escape) {\n\t\t\t\tsetSearching(false);\n\t\t\t\tsetQuery('');\n\t\t\t} else if (key.return) setSearching(false);\n\t\t\telse if (key.backspace || key.delete) setQuery((value) => [...value].slice(0, -1).join(''));\n\t\t\telse if (input && !key.upArrow && !key.downArrow) setQuery((value) => value + input);\n\t\t\tsetSelected(null);\n\t\t\treturn;\n\t\t}\n\t\tif (key.escape || input === 'l' || input === 'q') return onClose();\n\t\tif (input === '/') return setSearching(true);\n\t\tif (input === 'e' || input === 'w' || input === 'a') {\n\t\t\tconst next = input === 'e' ? 'error' : input === 'w' ? 'warn' : null;\n\t\t\tsetLevel((current) => (current === next ? null : next));\n\t\t\treturn setSelected(null);\n\t\t}\n\t\tif (input === 'c' || input === 'b' || input === 'r') {\n\t\t\tconst source = input === 'c' ? 'cli' : input === 'b' ? 'build' : 'runtime';\n\t\t\tsetSources((current) => {\n\t\t\t\tconst next = { ...current, [source]: !current[source] };\n\t\t\t\treturn Object.values(next).some(Boolean) ? next : current;\n\t\t\t});\n\t\t\treturn setSelected(null);\n\t\t}\n\t\tif (input === 'x') {\n\t\t\tservice.clearLogs();\n\t\t\treturn setSelected(null);\n\t\t}\n\t\tif (key.upArrow || input === 'k') return move(-1);\n\t\tif (key.downArrow || input === 'j') return move(1);\n\t\tif (key.pageUp) return move(-Math.max(1, bodyHeight));\n\t\tif (key.pageDown) return move(Math.max(1, bodyHeight));\n\t\tif (key.home || input === 'g') return setSelected(entries[0]?.id ?? null);\n\t\tif (key.end || input === 'G') return setSelected(null);\n\t\tif ((key.return || input === 'y') && index >= 0) onCopy?.(stripVTControlCharacters(entries[index]!.text));\n\t});\n\n\tconst hints = searching\n\t\t? [\n\t\t\t\t['enter', 'apply'],\n\t\t\t\t['esc', 'cancel']\n\t\t\t]\n\t\t: [\n\t\t\t\t['↑/↓', 'select'],\n\t\t\t\t['g/G', 'top/bottom'],\n\t\t\t\t['e', 'errors'],\n\t\t\t\t['w', 'warnings'],\n\t\t\t\t['a', 'all'],\n\t\t\t\t['c/b/r', 'sources'],\n\t\t\t\t['/', 'search'],\n\t\t\t\t['x', 'clear'],\n\t\t\t\t['enter', 'copy'],\n\t\t\t\t['q', 'close']\n\t\t\t];\n\treturn (\n\t\t<Box flexDirection=\"column\" height={height}>\n\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t{' '}\n\t\t\t\t<Text bold>logs</Text>\n\t\t\t\t<Text dimColor>{` · ${Object.entries(sources)\n\t\t\t\t\t.filter(([, shown]) => shown)\n\t\t\t\t\t.map(([source]) => source)\n\t\t\t\t\t.join(\n\t\t\t\t\t\t'+'\n\t\t\t\t\t)} · ${level ? `${level}+ only` : 'all levels'}${query || searching ? ` · search ${query}${searching ? '▏' : ''}` : ''}`}</Text>\n\t\t\t</Text>\n\t\t\t<Text dimColor>{'─'.repeat(width)}</Text>\n\t\t\t<Box flexDirection=\"column\" height={bodyHeight} overflow=\"hidden\">\n\t\t\t\t{visible.length === 0 && <Text dimColor> no matching logs</Text>}\n\t\t\t\t{visible.map(({ entry, text }, i) => (\n\t\t\t\t\t<Text key={`${entry.id}-${i}`} wrap=\"truncate-end\">\n\t\t\t\t\t\t<Text color={paint('brand')}>{entry.id === selected ? '▎ ' : ' '}</Text>\n\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\tcolor={paint(\n\t\t\t\t\t\t\t\tentry.level === 'error'\n\t\t\t\t\t\t\t\t\t? 'error'\n\t\t\t\t\t\t\t\t\t: entry.level === 'warn'\n\t\t\t\t\t\t\t\t\t\t? 'warning'\n\t\t\t\t\t\t\t\t\t\t: entry.level === 'success'\n\t\t\t\t\t\t\t\t\t\t\t? 'success'\n\t\t\t\t\t\t\t\t\t\t\t: 'text'\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\tdimColor={isErrorDetail(entry)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{text}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Text>\n\t\t\t\t))}\n\t\t\t</Box>\n\t\t\t<Hints\n\t\t\t\twidth={width}\n\t\t\t\thints={hints.map(([key, label], i) => ({ key: key!, label: label!, priority: i === hints.length - 1 ? 100 : hints.length - i }))}\n\t\t\t/>\n\t\t</Box>\n\t);\n}\n","import { useEffect, useState } from 'react';\nimport type { DevService, DevStatus } from '../../../dev-service.js';\n\n/**\n * Mirrors the service's status into React state. The service stays the single source of truth: the UI only\n * subscribes to it, exactly like the plain renderer does.\n */\nexport function useDevStatus(service: DevService): DevStatus {\n\tconst [status, setStatus] = useState<DevStatus>(() => service.status);\n\n\tuseEffect(() => {\n\t\tconst onStatus = (next: DevStatus) => setStatus(next);\n\t\tservice.on('status', onStatus);\n\t\tsetStatus(service.status);\n\t\treturn () => {\n\t\t\tservice.off('status', onStatus);\n\t\t};\n\t}, [service]);\n\n\treturn status;\n}\n","import { Box, Text, useInput } from 'ink';\nimport type { DevService } from '../../../dev-service.js';\nimport { useDevStatus } from '../hooks/useDevStatus.js';\nimport { useUptime } from '../hooks/useUptime.js';\nimport { formatDuration } from '../../panel-logic.js';\n\nexport function InfoOverlay({ service, height, width, onClose }: { service: DevService; height: number; width: number; onClose: () => void }) {\n\tconst status = useDevStatus(service);\n\tconst uptime = useUptime(status.startedAt);\n\tuseInput((input, key) => {\n\t\tif (!key.ctrl && (key.escape || ['q', 'i'].includes(input))) onClose();\n\t});\n\tconst lines = [\n\t\t['Project', service.config.packageJson?.name ?? 'stars project'],\n\t\t['Root', service.config.root],\n\t\t['Node', process.version],\n\t\t['Builder', service.builder.tool],\n\t\t['Local', status.url ?? '—'],\n\t\t['Tunnel', status.tunnelUrl ?? status.tunnel],\n\t\t['Process', `${status.process}${status.pid ? ` (${status.pid})` : ''}`],\n\t\t['Uptime', uptime === null ? '—' : formatDuration(uptime)],\n\t\t['Restarts', String(status.restarts)],\n\t\t['Health', service.config.dev.health ? status.health : 'not configured (READY reports process state)'],\n\t\t['Types', `${status.typecheck}${status.typeErrors ? ` (${status.typeErrors} errors)` : ''}`],\n\t\t['Log file', service.config.dev.logFile ?? 'disabled']\n\t];\n\treturn (\n\t\t<Box flexDirection=\"column\" height={height}>\n\t\t\t<Text bold wrap=\"truncate-end\">\n\t\t\t\t{' '}\n\t\t\t\tsession info\n\t\t\t</Text>\n\t\t\t<Text dimColor>{'─'.repeat(width)}</Text>\n\t\t\t{lines.slice(0, Math.max(0, height - 3)).map(([label, value]) => (\n\t\t\t\t<Text key={label} wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t<Text bold>{label!.padEnd(10)}</Text>\n\t\t\t\t\t<Text dimColor>{value}</Text>\n\t\t\t\t</Text>\n\t\t\t))}\n\t\t\t<Box flexGrow={1} />\n\t\t\t<Text dimColor> q close</Text>\n\t\t</Box>\n\t);\n}\n","import { Box, Text } from 'ink';\nimport type { ReactNode } from 'react';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport type { DevStatus } from '../../../dev-service.js';\nimport { readOwnPackageJson } from '../../../../utils/version.js';\nimport type { LogCounters } from '../hooks/useLogCounters.js';\nimport { describeBadge, isBusy } from '../../panel-logic.js';\nimport { usePaint } from '../theme.js';\nimport { Hints, PANEL_HINTS } from './Hints.js';\n\nexport interface PanelProps {\n\tstatus: DevStatus;\n\tconfig: ResolvedStarsConfig;\n\tcounters: LogCounters;\n\tframe: number;\n\telapsedMs: number;\n\twidth: number;\n\theight: number;\n\tconfirmQuit: boolean;\n}\n\n/** Nuxt's wordmark / URLs / progress / status / hints layout, with Stars branding. */\nexport function Panel({ status, config, counters, frame, elapsedMs, width, height, confirmQuit }: PanelProps) {\n\tconst paint = usePaint();\n\tconst state = describeBadge(status);\n\tconst busy = isBusy(state.badge);\n\tconst badge = !busy && counters.errors > 0 ? 'error' : state.badge;\n\tconst note = status.prompt\n\t\t? 'commands updated · press y to refresh them, n to skip'\n\t\t: badge === 'error' && state.badge === 'ready'\n\t\t\t? 'an error was logged · press e to view it'\n\t\t\t: state.note;\n\tconst filled = Math.round(Math.min(1, Math.max(0, status.progress.fraction)) * 20);\n\tconst wordmark = config.dev.banner === false ? [] : (config.dev.banner?.flatMap((line) => line.split('\\n')) ?? [null]);\n\tconst blocks: { name: string; content: ReactNode }[] = [\n\t\t...wordmark.slice(0, 4).map((line, index) => ({\n\t\t\tname: 'wordmark',\n\t\t\tcontent: (\n\t\t\t\t<Box key={index} justifyContent=\"space-between\">\n\t\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t{line === null ? (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t<Text color={paint('brand')}>\n\t\t\t\t\t\t\t\t\t{[...'·✦★✦'].map((cell, i) => (\n\t\t\t\t\t\t\t\t\t\t<Text key={i} dimColor={busy && i !== frame % 4}>\n\t\t\t\t\t\t\t\t\t\t\t{cell}\n\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t<Text bold color={paint('brand')}>\n\t\t\t\t\t\t\t\t\tStars\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<Text dimColor>{` ${readOwnPackageJson().version}`}</Text>\n\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Text color={paint('brand')}>{line}</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Text>\n\t\t\t\t\t{index === 0 && width >= 60 && badge === 'ready' && status.progress.readyMs !== null && (\n\t\t\t\t\t\t<Text dimColor>{`ready in ${(status.progress.readyMs / 1000).toFixed(2)}s `}</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Box>\n\t\t\t)\n\t\t})),\n\t\t{ name: 'space', content: <Text> </Text> },\n\t\t...(status.url\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'urls',\n\t\t\t\t\t\tcontent: (\n\t\t\t\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t<Text dimColor>{'Local '}</Text>\n\t\t\t\t\t\t\t\t<Text color={paint('url')} dimColor={busy}>\n\t\t\t\t\t\t\t\t\t{status.url}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t{busy && <Text color={paint('busy')}>{` ${['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'][frame % 10]}`}</Text>}\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t: []),\n\t\t...(status.tunnelUrl\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'urls',\n\t\t\t\t\t\tcontent: (\n\t\t\t\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t\t\t\t{' '}\n\t\t\t\t\t\t\t\t<Text dimColor>{'Tunnel '}</Text>\n\t\t\t\t\t\t\t\t<Text color={paint('tunnel')}>{status.tunnelUrl}</Text>\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t: []),\n\t\t{ name: 'space', content: <Text> </Text> },\n\t\t{\n\t\t\tname: 'summary',\n\t\t\tcontent: busy ? (\n\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t<Text color={paint('brand')}>{'━'.repeat(filled)}</Text>\n\t\t\t\t\t<Text dimColor>\n\t\t\t\t\t\t{'━'.repeat(20 - filled)}\n\t\t\t\t\t\t{` ${Math.round(status.progress.fraction * 100)}% · ${(elapsedMs / 1000).toFixed(1)}s`}\n\t\t\t\t\t</Text>\n\t\t\t\t</Text>\n\t\t\t) : (\n\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t{counters.warnings > 0 && (\n\t\t\t\t\t\t<Text color={paint('warning')}>{`⚠ ${counters.warnings} ${plural(counters.warnings, 'warning')} `}</Text>\n\t\t\t\t\t)}\n\t\t\t\t\t{counters.errors > 0 && <Text bold color={paint('error')}>{`✖ ${counters.errors} ${plural(counters.errors, 'error')} `}</Text>}\n\t\t\t\t\t{counters.errors === 0 && counters.warnings === 0 && (\n\t\t\t\t\t\t<Text dimColor>\n\t\t\t\t\t\t\t{status.typecheck === 'checking'\n\t\t\t\t\t\t\t\t? 'checking types'\n\t\t\t\t\t\t\t\t: status.tunnel === 'failed'\n\t\t\t\t\t\t\t\t\t? 'tunnel failed · press l to view logs'\n\t\t\t\t\t\t\t\t\t: 'logs folded away · press l to view'}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Text>\n\t\t\t)\n\t\t},\n\t\t{ name: 'space', content: <Text> </Text> },\n\t\t{\n\t\t\tname: 'status',\n\t\t\tcontent: (\n\t\t\t\t<Text wrap=\"truncate-end\">\n\t\t\t\t\t{' '}\n\t\t\t\t\t<Text\n\t\t\t\t\t\tbold\n\t\t\t\t\t\tbackgroundColor={paint(confirmQuit || busy || badge === 'stopped' ? 'busy' : badge === 'error' ? 'error' : 'success')}\n\t\t\t\t\t\tcolor={paint(badge === 'error' && !confirmQuit ? 'onError' : 'onBright')}\n\t\t\t\t\t>{` ${confirmQuit ? 'QUIT?' : badge === 'restarting' ? 'RESTART' : badge.toUpperCase()} `}</Text>\n\t\t\t\t\t{' '}\n\t\t\t\t\t<Text dimColor>{confirmQuit ? 'press y to confirm, esc to stay' : note}</Text>\n\t\t\t\t</Text>\n\t\t\t)\n\t\t},\n\t\t{\n\t\t\tname: 'hints',\n\t\t\tcontent: confirmQuit ? (\n\t\t\t\t<Text> </Text>\n\t\t\t) : (\n\t\t\t\t<Hints width={width} hints={[...(counters.errors ? [{ key: 'e', label: 'last error', priority: Infinity }] : []), ...PANEL_HINTS]} />\n\t\t\t)\n\t\t}\n\t];\n\tlet shown = blocks;\n\tconst budget = Math.max(2, Math.min(height, 14));\n\tfor (const name of ['space', 'summary', 'urls', 'wordmark']) {\n\t\tif (shown.length <= budget) break;\n\t\tshown = shown.filter((block) => block.name !== name);\n\t}\n\tshown = shown.filter((block, i, all) => block.name !== 'space' || (i > 0 && i < all.length - 1 && all[i - 1]?.name !== 'space'));\n\treturn (\n\t\t<Box flexDirection=\"column\">\n\t\t\t{shown.map((block, index) => (\n\t\t\t\t<Box key={index} flexDirection=\"column\" height={1}>\n\t\t\t\t\t{block.content}\n\t\t\t\t</Box>\n\t\t\t))}\n\t\t</Box>\n\t);\n}\n\nfunction plural(count: number, word: string): string {\n\treturn count === 1 ? word : `${word}s`;\n}\n","import { useEffect, useState } from 'react';\nimport type { DevService, DevStatus } from '../../../dev-service.js';\nimport { isErrorDetail, type LogEntry } from '../../../../utils/log-buffer.js';\n\nexport interface LogCounters {\n\twarnings: number;\n\terrors: number;\n}\n\n/**\n * Warnings and errors logged since the last successful build, the way Nuxt CLI v4's own panel counts them: the\n * badge's job is the current state, this line is what happened getting there.\n */\nexport function useLogCounters(service: DevService): LogCounters {\n\tconst count = () =>\n\t\tservice.logs.entries().reduce<LogCounters>(\n\t\t\t(total, entry) => ({\n\t\t\t\twarnings: total.warnings + Number(entry.level === 'warn'),\n\t\t\t\terrors: total.errors + Number(entry.level === 'error' && !isErrorDetail(entry))\n\t\t\t}),\n\t\t\t{ warnings: 0, errors: 0 }\n\t\t);\n\tconst [counters, setCounters] = useState<LogCounters>(count);\n\n\tuseEffect(() => {\n\t\tlet previousBuild: DevStatus['build'] = service.status.build;\n\t\tlet previousStart = service.status.startedAt;\n\n\t\tconst onEntry = (entry: LogEntry) => {\n\t\t\tif (entry.level === 'warn') setCounters((current) => ({ ...current, warnings: current.warnings + 1 }));\n\t\t\telse if (entry.level === 'error' && !isErrorDetail(entry)) setCounters((current) => ({ ...current, errors: current.errors + 1 }));\n\t\t};\n\n\t\tconst onStatus = (status: DevStatus) => {\n\t\t\tif (\n\t\t\t\t(status.build === 'building' && previousBuild !== 'building' && previousBuild !== 'idle') ||\n\t\t\t\t(status.lastRestartReason === 'manual' && status.startedAt !== null && status.startedAt !== previousStart)\n\t\t\t)\n\t\t\t\tsetCounters({ warnings: 0, errors: 0 });\n\t\t\tpreviousBuild = status.build;\n\t\t\tpreviousStart = status.startedAt;\n\t\t};\n\n\t\tservice.logs.on('entry', onEntry);\n\t\tconst onClear = () => setCounters({ warnings: 0, errors: 0 });\n\t\tservice.logs.on('clear', onClear);\n\t\tservice.on('status', onStatus);\n\t\tsetCounters(count());\n\t\treturn () => {\n\t\t\tservice.logs.off('entry', onEntry);\n\t\t\tservice.logs.off('clear', onClear);\n\t\t\tservice.off('status', onStatus);\n\t\t};\n\t}, [service]);\n\n\treturn counters;\n}\n","import { useEffect, useState } from 'react';\n\n/** The clock moves during a long compiler phase; the percentage only moves on real build events. */\nexport function useBuildClock(startedAt: number, active: boolean, reducedMotion: boolean) {\n\tconst [now, setNow] = useState(Date.now);\n\tuseEffect(() => {\n\t\tif (!active) return;\n\t\tsetNow(Date.now());\n\t\tconst timer = setInterval(() => setNow(Date.now()), reducedMotion ? 1000 : 120);\n\t\treturn () => clearInterval(timer);\n\t}, [startedAt, active, reducedMotion]);\n\tconst elapsedMs = Math.max(0, now - startedAt);\n\treturn { elapsedMs, frame: reducedMotion ? 0 : Math.floor(elapsedMs / 120) };\n}\n","import { execFile } from 'node:child_process';\n\n/** Called only on an explicit `o` keypress, with no shell interpolation. */\nexport function openDevUrl(value: string | null): Promise<void> {\n\tif (!value) return Promise.resolve();\n\tconst url = new URL(value);\n\tif (url.protocol !== 'http:' && url.protocol !== 'https:') return Promise.reject(new Error('Only HTTP(S) URLs can be opened.'));\n\tconst [command, args] =\n\t\tprocess.platform === 'win32'\n\t\t\t? (['rundll32', ['url.dll,FileProtocolHandler', url.href]] as const)\n\t\t\t: process.platform === 'darwin'\n\t\t\t\t? (['open', [url.href]] as const)\n\t\t\t\t: (['xdg-open', [url.href]] as const);\n\treturn new Promise((resolve, reject) =>\n\t\texecFile(command, [...args], (error) => (error ? reject(new Error(`Could not open the browser: ${error.message}`)) : resolve()))\n\t);\n}\n","import { Box, Text, useInput } from 'ink';\nimport { useState } from 'react';\nimport { THEME_SETTINGS, THEMES, detectTerminalBackground, type ThemeSetting } from '../../../../utils/theme.js';\nimport { useColorEnabled } from '../theme.js';\n\nconst DESCRIPTIONS: Record<ThemeSetting, string> = {\n\tauto: 'match the terminal background',\n\tdark: 'for dark terminals',\n\tlight: 'for light terminals',\n\t'dark-daltonized': 'dark, colour-blind friendly (blue/orange)',\n\t'light-daltonized': 'light, colour-blind friendly (blue/orange)',\n\t'dark-ansi': 'dark, only your terminal palette',\n\t'light-ansi': 'light, only your terminal palette'\n};\n\nexport interface ThemeOverlayProps {\n\t/** The theme setting in effect when the picker opened. */\n\tcurrent: ThemeSetting;\n\theight: number;\n\twidth: number;\n\t/** Called while moving through the list, so the whole UI previews the highlighted theme. */\n\tonPreview: (setting: ThemeSetting) => void;\n\tonSelect: (setting: ThemeSetting) => void;\n\t/** Closes without saving; the caller restores the theme that was in effect. */\n\tonClose: () => void;\n}\n\n/** Like Claude Code's `/theme`: arrows preview live, `Enter` keeps the choice and saves it, `Esc` restores. */\nexport function ThemeOverlay({ current, height, width, onPreview, onSelect, onClose }: ThemeOverlayProps) {\n\tconst color = useColorEnabled();\n\tconst [index, setIndex] = useState(Math.max(0, THEME_SETTINGS.indexOf(current)));\n\n\tconst move = (delta: number) => {\n\t\tconst next = (index + delta + THEME_SETTINGS.length) % THEME_SETTINGS.length;\n\t\tsetIndex(next);\n\t\tonPreview(THEME_SETTINGS[next]!);\n\t};\n\n\tuseInput((input, key) => {\n\t\tif (key.ctrl) return;\n\t\tif (key.escape || input === 'q' || input === 'T') return onClose();\n\t\tif (key.return) return onSelect(THEME_SETTINGS[index]!);\n\t\tif (key.upArrow || input === 'k') return move(-1);\n\t\tif (key.downArrow || input === 'j') return move(1);\n\t});\n\n\treturn (\n\t\t<Box flexDirection=\"column\" height={height}>\n\t\t\t<Text bold> colour theme</Text>\n\t\t\t<Text dimColor>{'─'.repeat(width)}</Text>\n\t\t\t{THEME_SETTINGS.slice(0, Math.max(0, height - 3)).map((setting, i) => {\n\t\t\t\tconst swatch = THEMES[setting === 'auto' ? detectTerminalBackground() : setting];\n\t\t\t\treturn (\n\t\t\t\t\t<Text key={setting} wrap=\"truncate-end\">\n\t\t\t\t\t\t{i === index ? ' ▎ ' : ' '}\n\t\t\t\t\t\t<Text bold={i === index}>{setting.padEnd(18)}</Text>\n\t\t\t\t\t\t{color && (\n\t\t\t\t\t\t\t<Text>\n\t\t\t\t\t\t\t\t<Text color={swatch.success}>● </Text>\n\t\t\t\t\t\t\t\t<Text color={swatch.warning}>● </Text>\n\t\t\t\t\t\t\t\t<Text color={swatch.error}>● </Text>\n\t\t\t\t\t\t\t\t<Text color={swatch.url}>● </Text>\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<Text dimColor>{` ${DESCRIPTIONS[setting]}${setting === current ? ' (current)' : ''}`}</Text>\n\t\t\t\t\t</Text>\n\t\t\t\t);\n\t\t\t})}\n\t\t\t<Box flexGrow={1} />\n\t\t\t<Text dimColor> ↑/↓ preview · enter save · esc cancel</Text>\n\t\t</Box>\n\t);\n}\n","import { Box, useInput, useWindowSize } from 'ink';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport type { DevService } from '../../dev-service.js';\nimport { Dashboard } from './components/Dashboard.js';\nimport { HelpOverlay } from './components/HelpOverlay.js';\nimport { LogBrowser } from './components/LogBrowser.js';\nimport { InfoOverlay } from './components/InfoOverlay.js';\nimport { Panel } from './components/Panel.js';\nimport { useDevStatus } from './hooks/useDevStatus.js';\nimport { useLogCounters } from './hooks/useLogCounters.js';\nimport { useBuildClock } from './hooks/useBuildClock.js';\nimport { describeBadge, isBusy } from '../panel-logic.js';\nimport { initialLogView, type LogViewFilter } from '../log-view.js';\nimport { openDevUrl } from '../../open-url.js';\nimport { ThemeProvider } from './theme.js';\nimport { ThemeOverlay } from './components/ThemeOverlay.js';\nimport { resolveTheme, type ThemeSetting } from '../../../utils/theme.js';\n\nexport type DevLayout = 'dashboard' | 'panel';\n\nexport interface DevAppProps {\n\tservice: DevService;\n\tcolor: boolean;\n\t/** The theme setting to start with; `auto` follows the terminal background. */\n\ttheme: ThemeSetting;\n\treducedMotion: boolean;\n\t/** `dev.layout` (or `--layout`); `auto` follows the terminal size. */\n\tlayout?: DevLayout | 'auto';\n\t/** The log filter the dashboard starts with; defaults to `dev.logs`. */\n\tfilter?: LogViewFilter;\n\t/** Called when the user asks to quit, so the CLI can stop the bot and exit. */\n\tonQuit: () => void;\n\t/** Called with whether the view about to be painted takes the whole screen (the alternate buffer). */\n\tonViewChange: (fullScreen: boolean) => void;\n\tonCopy: (text: string) => void;\n\t/** Called when the user keeps a theme in the picker, so the CLI can remember it. */\n\tonThemeSave: (setting: ThemeSetting) => void;\n}\n\ntype Overlay = 'logs' | 'errors' | 'help' | 'info' | 'theme';\n\n/** The dashboard needs room for its sidebar next to a readable log line, and for more than a handful of entries. */\nexport const DASHBOARD_MIN_COLUMNS = 90;\nexport const DASHBOARD_MIN_ROWS = 20;\n/** Below this even an explicit `dashboard` falls back to the panel: the sidebar alone would fill the terminal. */\nconst DASHBOARD_HARD_MIN_COLUMNS = 60;\nconst DASHBOARD_HARD_MIN_ROWS = 10;\n\n/** The layout to paint for a terminal size: what was asked for when it fits, the panel otherwise. */\nexport function resolveLayout(layout: DevLayout | 'auto', columns: number, rows: number): DevLayout {\n\tif (layout === 'panel') return 'panel';\n\tif (columns < DASHBOARD_HARD_MIN_COLUMNS || rows < DASHBOARD_HARD_MIN_ROWS) return 'panel';\n\tif (layout === 'dashboard') return 'dashboard';\n\treturn columns >= DASHBOARD_MIN_COLUMNS && rows >= DASHBOARD_MIN_ROWS ? 'dashboard' : 'panel';\n}\n\n/**\n * Two layouts over one service. The dashboard is a full-screen view in the alternate buffer; the panel is pinned to\n * the bottom of the normal buffer with the logs folded away, and is what a small terminal gets. The browsable\n * overlays use the alternate buffer from either, preserving the terminal's history and the panel when they close.\n */\nexport function DevApp({ service, color, theme, reducedMotion, layout = 'auto', filter, onQuit, onViewChange, onCopy, onThemeSave }: DevAppProps) {\n\tconst { columns, rows } = useWindowSize();\n\tconst [overlay, setOverlay] = useState<Overlay | null>(null);\n\tconst [chosen, setChosen] = useState(layout);\n\tconst [confirmQuit, setConfirmQuit] = useState(false);\n\tconst [captured, setCaptured] = useState(false);\n\tconst [, repaint] = useState(0);\n\t// `saved` is what Esc restores after previewing other themes in the picker.\n\tconst [saved, setSaved] = useState(theme);\n\tconst [preview, setPreview] = useState(theme);\n\tconst [initialFilter] = useState(() => filter ?? initialLogView(service.config));\n\n\tconst status = useDevStatus(service);\n\tconst counters = useLogCounters(service);\n\tconst badge = describeBadge(status).badge;\n\tconst busy = isBusy(badge);\n\tconst base = resolveLayout(chosen, columns, rows);\n\tconst clock = useBuildClock(status.progress.startedAt, busy && overlay === null, reducedMotion);\n\n\tconst width = Math.max(1, columns);\n\tconst height = Math.max(2, rows - 1);\n\n\t// The buffer is switched before the view that needs it is painted. A resize that moves `auto` across the\n\t// dashboard's threshold is only seen after the fact, so it switches from the effect and paints once more.\n\tconst fullScreen = overlay !== null || base === 'dashboard';\n\tconst shown = useRef(fullScreen);\n\tconst show = (nextOverlay: Overlay | null, nextChosen: DevLayout | 'auto' = chosen) => {\n\t\tconst next = nextOverlay !== null || resolveLayout(nextChosen, columns, rows) === 'dashboard';\n\t\tshown.current = next;\n\t\tonViewChange(next);\n\t\tsetOverlay(nextOverlay);\n\t\tsetChosen(nextChosen);\n\t};\n\tuseEffect(() => {\n\t\tif (shown.current === fullScreen) return;\n\t\tshown.current = fullScreen;\n\t\tonViewChange(fullScreen);\n\t\trepaint((count) => count + 1);\n\t}, [fullScreen, onViewChange]);\n\n\tconst onCapture = useCallback((capturing: boolean) => setCaptured(capturing), []);\n\n\tuseInput((input, key) => {\n\t\tif (key.ctrl && input === 'c') return onQuit();\n\t\tif (key.ctrl && input === 'l') return service.clearLogs();\n\t\tif (overlay !== null || captured) return;\n\t\tif (confirmQuit) {\n\t\t\tif (input === 'y') return onQuit();\n\t\t\treturn setConfirmQuit(false);\n\t\t}\n\t\tif (key.ctrl && input === 'r') return void service.restart('manual');\n\t\tif (key.ctrl && input === 'd') return busy ? setConfirmQuit(true) : onQuit();\n\t\tif (status.prompt && (input === 'y' || input === 'n')) return service.answerPrompt(input === 'y');\n\n\t\tswitch (input) {\n\t\t\tcase 'q':\n\t\t\t\treturn busy ? setConfirmQuit(true) : onQuit();\n\t\t\tcase 'r':\n\t\t\t\treturn void service.restart('manual');\n\t\t\tcase 'd':\n\t\t\t\treturn void service.disconnect();\n\t\t\tcase 'l':\n\t\t\t\treturn show('logs');\n\t\t\tcase 'e':\n\t\t\t\t// The dashboard jumps to the error in its own log pane.\n\t\t\t\treturn base === 'panel' ? show('errors') : undefined;\n\t\t\tcase 'c':\n\t\t\t\treturn service.clearLogs();\n\t\t\tcase 'o':\n\t\t\t\treturn void openDevUrl(status.url).catch((error: Error) => service.log('stars', 'warn', error.message));\n\t\t\tcase 't':\n\t\t\t\treturn void service.toggleTunnel();\n\t\t\tcase 'i':\n\t\t\t\treturn show('info');\n\t\t\tcase 'T':\n\t\t\t\treturn show('theme');\n\t\t\tcase 'v':\n\t\t\t\treturn show(null, base === 'dashboard' ? 'panel' : 'dashboard');\n\t\t\tcase 'h':\n\t\t\tcase '?':\n\t\t\t\treturn show('help');\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t});\n\n\treturn (\n\t\t<ThemeProvider color={color} theme={resolveTheme(preview)}>\n\t\t\t<Box width={width} height={height} flexDirection=\"column\" justifyContent={fullScreen ? 'flex-start' : 'flex-end'}>\n\t\t\t\t{(overlay === 'logs' || overlay === 'errors') && (\n\t\t\t\t\t<LogBrowser\n\t\t\t\t\t\tservice={service}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\tlastError={overlay === 'errors'}\n\t\t\t\t\t\tonCopy={onCopy}\n\t\t\t\t\t\tonClose={() => show(null)}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{overlay === 'help' && <HelpOverlay height={height} width={width} onClose={() => show(null)} />}\n\t\t\t\t{overlay === 'info' && <InfoOverlay service={service} height={height} width={width} onClose={() => show(null)} />}\n\t\t\t\t{overlay === 'theme' && (\n\t\t\t\t\t<ThemeOverlay\n\t\t\t\t\t\tcurrent={saved}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\tonPreview={setPreview}\n\t\t\t\t\t\tonSelect={(setting) => {\n\t\t\t\t\t\t\tsetSaved(setting);\n\t\t\t\t\t\t\tsetPreview(setting);\n\t\t\t\t\t\t\tonThemeSave(setting);\n\t\t\t\t\t\t\tshow(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonClose={() => {\n\t\t\t\t\t\t\tsetPreview(saved);\n\t\t\t\t\t\t\tshow(null);\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{base === 'dashboard' && (\n\t\t\t\t\t// Kept mounted under an overlay, so the filters and the scroll position survive it.\n\t\t\t\t\t<Box display={overlay === null ? 'flex' : 'none'}>\n\t\t\t\t\t\t<Dashboard\n\t\t\t\t\t\t\tservice={service}\n\t\t\t\t\t\t\tstatus={status}\n\t\t\t\t\t\t\tcounters={counters}\n\t\t\t\t\t\t\t{...clock}\n\t\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\t\theight={height}\n\t\t\t\t\t\t\tconfirmQuit={confirmQuit}\n\t\t\t\t\t\t\tinitialFilter={initialFilter}\n\t\t\t\t\t\t\tactive={overlay === null}\n\t\t\t\t\t\t\tonCapture={onCapture}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\t\t\t\t{base === 'panel' && overlay === null && (\n\t\t\t\t\t<Panel\n\t\t\t\t\t\tstatus={status}\n\t\t\t\t\t\tconfig={service.config}\n\t\t\t\t\t\tcounters={counters}\n\t\t\t\t\t\t{...clock}\n\t\t\t\t\t\twidth={width}\n\t\t\t\t\t\theight={height}\n\t\t\t\t\t\tconfirmQuit={confirmQuit}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Box>\n\t\t</ThemeProvider>\n\t);\n}\n","import { StringDecoder } from 'node:string_decoder';\nimport type { DevService } from '../dev-service.js';\nimport { classifyAppLine, type LogLevel } from '../../utils/log-buffer.js';\n\n/** Capture third-party writes before build plugins run. Ink writes through a separate, unpatched sink. */\nexport function captureOutput(service: DevService, stream: NodeJS.WriteStream, fallback: LogLevel): () => void {\n\tconst original = stream.write;\n\tconst decoder = new StringDecoder('utf8');\n\tlet pending = '';\n\tconst emit = (text: string) => {\n\t\tif (text.trim()) service.log('build', classifyAppLine(text, fallback), text);\n\t};\n\tconst write: typeof stream.write = (chunk: unknown, encoding?: unknown, callback?: unknown) => {\n\t\tpending += typeof chunk === 'string' ? chunk : chunk instanceof Uint8Array ? decoder.write(Buffer.from(chunk)) : String(chunk);\n\t\tconst lines = pending.split(/\\r?\\n/);\n\t\tpending = lines.pop() ?? '';\n\t\tfor (const line of lines) emit(line);\n\t\t// A tool without newlines must not grow the capture indefinitely.\n\t\tif (pending.length > 65536) {\n\t\t\temit(pending);\n\t\t\tpending = '';\n\t\t}\n\t\tconst done = typeof encoding === 'function' ? encoding : callback;\n\t\tif (typeof done === 'function') queueMicrotask(() => done());\n\t\treturn true;\n\t};\n\tstream.write = write;\n\treturn () => {\n\t\tif (stream.write === write) stream.write = original;\n\t\temit(pending + decoder.end());\n\t\tpending = '';\n\t};\n}\n","import { render } from 'ink';\nimport type { DevService } from '../dev-service.js';\nimport { DevApp, resolveLayout, type DevLayout } from './ink/DevApp.js';\nimport type { LogViewFilter } from './log-view.js';\nimport type { Renderer } from './plain.js';\nimport { captureOutput } from './capture-output.js';\nimport { isErrorDetail } from '../../utils/log-buffer.js';\nimport type { ThemeSetting } from '../../utils/theme.js';\n\nexport interface TuiRendererOptions {\n\tstdout?: NodeJS.WriteStream;\n\tstdin?: NodeJS.ReadStream;\n\tcolor?: boolean;\n\t/** Defaults to `auto`. */\n\ttheme?: ThemeSetting;\n\t/** Called when the user keeps a theme in the picker. */\n\tonThemeSave?: (setting: ThemeSetting) => void;\n\t/** Freezes spinners, for `STARS_REDUCED_MOTION=1`. */\n\treducedMotion?: boolean;\n\t/** Caps how often Ink repaints; the default is Ink's own. */\n\tfps?: number;\n\t/** `--layout`; defaults to `dev.layout`. */\n\tlayout?: DevLayout | 'auto';\n\t/** The log filter the dashboard starts with; defaults to `dev.logs`. */\n\tfilter?: LogViewFilter;\n}\n\n/**\n * The full-screen dashboard and the overlays in the alternate buffer, the bottom-aligned panel in the normal one.\n * External output is captured for the log views; the renderer alone writes to the terminal. Switching views and\n * teardown restore the original buffer.\n *\n * `start()` resolves when the user quits, which is what `stars dev` waits on before shutting the bot down.\n */\nexport function createTuiRenderer(service: DevService, options: TuiRendererOptions = {}): Renderer {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst stdin = options.stdin ?? process.stdin;\n\tconst write = stdout.write.bind(stdout);\n\t// Bind methods to the real stream (resize subscriptions included), except write which bypasses capture.\n\tconst sink = new Proxy(stdout, {\n\t\tget(target, property) {\n\t\t\tif (property === 'write') return write;\n\t\t\tconst value = Reflect.get(target, property, target);\n\t\t\treturn typeof value === 'function' ? value.bind(target) : value;\n\t\t}\n\t});\n\tconst restoreOutput =\n\t\tstdout === process.stdout ? [captureOutput(service, process.stdout, 'info'), captureOutput(service, process.stderr, 'warn')] : [];\n\tconst layout = options.layout ?? service.config.dev.layout ?? 'auto';\n\t// The dashboard is painted from the first frame, so its buffer is entered before Ink writes anything.\n\tlet alternate = resolveLayout(layout, stdout.columns ?? 80, stdout.rows ?? 24) === 'dashboard';\n\tif (alternate) write('\\u001B[?1049h\\u001B[H');\n\tlet stopped = false;\n\tconst switchView = (fullScreen: boolean) => {\n\t\tif (fullScreen === alternate || stopped) return;\n\t\tinstance.clear();\n\t\twrite(fullScreen ? '\\u001B[?1049h\\u001B[H' : '\\u001B[?1049l');\n\t\talternate = fullScreen;\n\t};\n\t// Only an interactive UI can answer the bot's questions (`Refresh commands?`).\n\tservice.promptable = true;\n\n\tlet quit!: () => void;\n\tconst quitting = new Promise<void>((resolve) => {\n\t\tquit = resolve;\n\t});\n\n\tconst instance = render(\n\t\t<DevApp\n\t\t\tservice={service}\n\t\t\tcolor={options.color ?? false}\n\t\t\ttheme={options.theme ?? 'auto'}\n\t\t\tonThemeSave={options.onThemeSave ?? (() => {})}\n\t\t\treducedMotion={options.reducedMotion ?? false}\n\t\t\tlayout={layout}\n\t\t\tfilter={options.filter}\n\t\t\tonQuit={quit}\n\t\t\tonViewChange={switchView}\n\t\t\tonCopy={(text) => write(`\\u001B]52;c;${Buffer.from(text.slice(0, 65536)).toString('base64')}\\u0007`)}\n\t\t/>,\n\t\t{\n\t\t\tstdout: sink,\n\t\t\tstdin,\n\t\t\t// `stars dev` owns the shutdown: it stops the bot, then exits with the right code.\n\t\t\texitOnCtrlC: false,\n\t\t\tpatchConsole: false,\n\t\t\t// `createTuiRenderer` only runs once `resolveOutputMode()` already picked 'tui' (never in CI or on a\n\t\t\t// non-TTY stdout), so Ink is told to trust that instead of re-deriving it from `process.env.CI`: on a\n\t\t\t// CI runner that env var is set even for this package's own test process, which would otherwise force\n\t\t\t// Ink's non-interactive mode (no repaint until unmount) despite the fake stdin/stdout looking like a\n\t\t\t// real TTY.\n\t\t\tinteractive: true,\n\t\t\t...(options.fps === undefined ? {} : { maxFps: options.fps })\n\t\t}\n\t);\n\n\treturn {\n\t\tasync start() {\n\t\t\tawait Promise.race([quitting, instance.waitUntilExit()]);\n\t\t},\n\t\tstop() {\n\t\t\tif (stopped) return;\n\t\t\tstopped = true;\n\t\t\tservice.promptable = false;\n\t\t\tif (alternate) instance.clear();\n\t\t\tinstance.unmount();\n\t\t\tif (alternate) write('\\u001B[?1049l');\n\t\t\twrite('\\u001B[?25h');\n\t\t\tfor (const restore of restoreOutput) restore();\n\t\t\t// A fatal startup must not leave the user with only a folded error and no way to read it.\n\t\t\tif (service.status.progress.readyMs === null) {\n\t\t\t\tconst error = service.logs.entries().findLast((entry) => entry.level === 'error' && !isErrorDetail(entry));\n\t\t\t\tif (error) write(`\\n${error.text}\\n`);\n\t\t\t}\n\t\t\tquit();\n\t\t}\n\t};\n}\n\nexport { formatDuration } from './panel-logic.js';\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as pluginRegistrations } from "./plugin-registrations-Dr_BicfC.js";
|
|
2
|
-
import { n as importFromProject } from "./project-
|
|
2
|
+
import { n as importFromProject } from "./project-zlQStwsf.js";
|
|
3
3
|
import { ViteBuilder as ViteBuilder$1 } from "@wolfstar/vite-server";
|
|
4
4
|
|
|
5
5
|
//#region src/builders/vite.ts
|
|
@@ -15,4 +15,4 @@ var ViteBuilder = class extends ViteBuilder$1 {
|
|
|
15
15
|
|
|
16
16
|
//#endregion
|
|
17
17
|
export { ViteBuilder };
|
|
18
|
-
//# sourceMappingURL=vite-
|
|
18
|
+
//# sourceMappingURL=vite-YZUtv2Hk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-
|
|
1
|
+
{"version":3,"file":"vite-YZUtv2Hk.js","names":["ServerBuilder"],"sources":["../src/builders/vite.ts"],"sourcesContent":["import { ViteBuilder as ServerBuilder } from '@wolfstar/vite-server';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { pluginRegistrations } from '../utils/plugin-registrations.js';\nimport { importFromProject } from '../utils/project.js';\n\n/** Connect the server integration to the CLI's diagnostics and plugin discovery. */\nexport class ViteBuilder extends ServerBuilder {\n\tpublic constructor(config: ResolvedStarsConfig) {\n\t\tsuper(config, { importFromProject, pluginRegistrations });\n\t}\n}\n"],"mappings":";;;;;;AAMA,IAAa,cAAb,cAAiCA,cAAc;CAC9C,AAAO,YAAY,QAA6B;EAC/C,MAAM,QAAQ;GAAE;GAAmB;EAAoB,CAAC;CACzD;AACD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wolfstar/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0-next-20261004131917",
|
|
4
4
|
"description": "The stars command line interface for @wolfstar/http-framework projects: typed configuration, dev server, build and project info",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -56,9 +56,10 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@clack/prompts": "^1.8.1",
|
|
58
58
|
"@sapphire/ts-config": "^5.0.3",
|
|
59
|
-
"@wolfstar/
|
|
60
|
-
"@wolfstar/
|
|
61
|
-
"@wolfstar/
|
|
59
|
+
"@wolfstar/kit": "^0.1.1-next-20261004131917",
|
|
60
|
+
"@wolfstar/nitro-server": "^0.2.6-next-20261004131917",
|
|
61
|
+
"@wolfstar/schema": "^0.6.0-next-20261004131917",
|
|
62
|
+
"@wolfstar/vite-server": "^0.4.1-next-20261004131917",
|
|
62
63
|
"chokidar": "^5.0.0",
|
|
63
64
|
"citty": "^0.2.2",
|
|
64
65
|
"colorette": "^2.0.20",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_shared-B-hRZDRS.js","names":[],"sources":["../src/utils/tsconfig.ts","../src/commands/_shared.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { createRequire } from 'node:module';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path';\n\nconst require = createRequire(import.meta.url);\nconst sapphireOptions = Object.assign(\n\t{},\n\t...['@sapphire/ts-config', '@sapphire/ts-config/extra-strict', '@sapphire/ts-config/decorators'].map(\n\t\t(id) => (require(id) as { compilerOptions: Record<string, unknown> }).compilerOptions\n\t)\n) as Record<string, unknown>;\n\n/** Generates an extendable config without changing the project's own tsconfig. */\nexport async function prepareTsconfig(config: ResolvedStarsConfig, check = false) {\n\tconst path = join(config.root, '.stars', 'tsconfig.json');\n\tconst fromGenerated = (target: string) => `./${relative(dirname(path), target).replaceAll('\\\\', '/')}`;\n\tconst paths: Record<string, string[]> = {};\n\tif (config.build.tool === 'tsdown') {\n\t\tconst source = dirname(config.entry);\n\t\tconst defaults = config.build.configFile === null ? { '~': source, '@': source, '~~': config.root, '@@': config.root } : {};\n\t\tconst aliases = { ...defaults, ...(config.tsdown.alias as Record<string, unknown> | undefined) };\n\t\tfor (const [alias, target] of Object.entries(aliases)) {\n\t\t\t// Module redirects belong to the bundler; only filesystem targets become TypeScript paths.\n\t\t\tif (typeof target !== 'string' || (!isAbsolute(target) && !/^\\.\\.?[/\\\\]/.test(target))) continue;\n\t\t\tconst resolved = fromGenerated(resolve(config.root, target));\n\t\t\tpaths[alias] = [resolved];\n\t\t\tpaths[`${alias}/*`] = [`${resolved}/*`];\n\t\t}\n\t} else if (config.experimental.enableNitro) {\n\t\t// `NitroBuilder` turns on Vite's native `resolve.tsconfigPaths` (see https://nitro.build/examples/import-alias),\n\t\t// which reads these `paths` straight out of the generated tsconfig — no `tsdown.alias` equivalent to merge\n\t\t// with, `vite`/Nitro projects only have this file's own `compilerOptions.paths` to extend or replace.\n\t\tconst source = dirname(config.entry);\n\t\tconst defaults = { '~': source, '@': source, '~~': config.root, '@@': config.root };\n\t\tfor (const [alias, target] of Object.entries(defaults)) {\n\t\t\tconst resolved = fromGenerated(resolve(config.root, target));\n\t\t\tpaths[alias] = [resolved];\n\t\t\tpaths[`${alias}/*`] = [`${resolved}/*`];\n\t\t}\n\t}\n\tconst content = `${JSON.stringify(\n\t\t{\n\t\t\tcompilerOptions: {\n\t\t\t\t...sapphireOptions,\n\t\t\t\t// Bundlers emit the application; TypeScript only checks it. Keep Node16 emit for tsc.\n\t\t\t\t...(config.build.tool === 'tsdown' || config.build.tool === 'vite'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmodule: 'ESNext',\n\t\t\t\t\t\t\tmoduleResolution: 'Bundler',\n\t\t\t\t\t\t\tmoduleDetection: 'force',\n\t\t\t\t\t\t\tisolatedModules: true,\n\t\t\t\t\t\t\tverbatimModuleSyntax: true,\n\t\t\t\t\t\t\tallowJs: true,\n\t\t\t\t\t\t\tallowImportingTsExtensions: true,\n\t\t\t\t\t\t\tresolvePackageJsonImports: true,\n\t\t\t\t\t\t\tlib: ['ESNext', 'DOM'],\n\t\t\t\t\t\t\tnoEmit: true\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\ttarget: 'ES2022',\n\t\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\t\tskipLibCheck: true,\n\t\t\t\ttsBuildInfoFile: './tsconfig.tsbuildinfo',\n\t\t\t\tpaths\n\t\t\t},\n\t\t\tinclude: [`${fromGenerated(dirname(config.entry))}/**/*`, ...(config.imports.enabled ? [fromGenerated(config.imports.dts)] : [])],\n\t\t\texclude: [fromGenerated(join(config.root, 'node_modules')), fromGenerated(config.build.outDir)]\n\t\t},\n\t\tnull,\n\t\t2\n\t)}\\n`;\n\tif (check) {\n\t\tconst existing = await readFile(path, 'utf-8').catch(() => null);\n\t\treturn { path, status: existing === content ? ('up-to-date' as const) : ('outdated' as const) };\n\t}\n\tawait mkdir(dirname(path), { recursive: true });\n\tawait writeFile(path, content);\n\treturn { path, status: 'written' as const };\n}\n","import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { loadAutoImportsModule } from '../utils/framework-auto-imports.js';\nimport { formatError } from '../utils/errors.js';\nimport type { StarsHookable } from '../utils/hooks.js';\nimport { prepareTsconfig } from '../utils/tsconfig.js';\n\nexport type PrepareResult =\n\t| { enabled: false; dts: null; status: null }\n\t| { enabled: true; dts: string; status: 'written' | 'up-to-date' | 'outdated' };\n\n/**\n * Regenerates `imports.dts` unconditionally, used by `stars dev`/`stars build` before the first build so the\n * declaration file exists (and is current) even when the user never ran `stars prepare` themselves.\n */\nexport async function prepareAutoImports(config: ResolvedStarsConfig, check = false): Promise<PrepareResult> {\n\tif (!config.imports.enabled) return { enabled: false, dts: null, status: null };\n\n\tconst { dirs, presets, exclude, dts } = config.imports;\n\tconst { generateAutoImportsDts } = await loadAutoImportsModule(config.root);\n\tconst content = await generateAutoImportsDts({ root: config.root, dirs, presets, exclude });\n\n\tif (check) {\n\t\tconst existing = await readFile(dts, 'utf-8').catch(() => null);\n\t\treturn { enabled: true, dts, status: existing === content ? 'up-to-date' : 'outdated' };\n\t}\n\n\tawait mkdir(dirname(dts), { recursive: true });\n\tawait writeFile(dts, content);\n\treturn { enabled: true, dts, status: 'written' };\n}\n\n/** Prepares TypeScript configuration and auto import declarations before building. */\nexport async function prepareProject(config: ResolvedStarsConfig, hooks?: StarsHookable, check = false) {\n\tawait hooks?.callHook('prepare:before', config);\n\tconst tsconfig = await prepareTsconfig(config, check);\n\tconst result = { ...(await prepareAutoImports(config, check)), tsconfig };\n\tawait hooks?.callHook('prepare:done', config, { dts: result.dts, status: result.status });\n\treturn result;\n}\n\n/** Prints the non-fatal configuration diagnostics (e.g. an end-of-life compatibility version). */\nexport async function reportWarnings(config: ResolvedStarsConfig, write: (text: string) => void): Promise<void> {\n\tfor (const warning of config.warnings) write(await formatError(warning));\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands-ExM8HILu.js","names":[],"sources":["../src/utils/discord.ts","../src/utils/prompts.ts","../src/commands/commands.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { cliDiagnostics } from './diagnostics.js';\nimport { readDiscordCredentials } from '../dev/tunnel.js';\n\nconst API = 'https://discord.com/api/v10';\n\nexport interface ApplicationCommand {\n\tid: string;\n\tapplication_id: string;\n\tname: string;\n\tdescription?: string;\n\ttype?: number;\n\tguild_id?: string;\n\tversion?: string;\n}\n\nexport interface DiscordClient {\n\tapplicationId: string;\n\tlistCommands(guildId: string | null): Promise<ApplicationCommand[]>;\n\tdeleteCommand(guildId: string | null, commandId: string): Promise<void>;\n}\n\nexport const COMMAND_TYPE_NAMES: Record<number, string> = { 1: 'chat input', 2: 'user', 3: 'message' };\n\n/**\n * A minimal Discord REST client for what `stars commands` manages. The credentials come from the environment or the\n * project's `.env`, the same place the bot reads them from once it starts.\n */\nexport function createDiscordClient(config: ResolvedStarsConfig, env: NodeJS.ProcessEnv = process.env): DiscordClient {\n\tconst credentials = readDiscordCredentials(config, env);\n\tif (!credentials) {\n\t\tthrow cliDiagnostics.DISCORD_TOKEN_MISSING({});\n\t}\n\n\tif (!credentials.applicationId) {\n\t\tthrow cliDiagnostics.DISCORD_APPLICATION_ID_MISSING({});\n\t}\n\n\tconst applicationId = credentials.applicationId;\n\tconst scope = (guildId: string | null) =>\n\t\tguildId ? `/applications/${applicationId}/guilds/${guildId}/commands` : `/applications/${applicationId}/commands`;\n\n\tconst request = async (method: string, path: string): Promise<unknown> => {\n\t\tconst response = await fetch(`${API}${path}`, {\n\t\t\tmethod,\n\t\t\theaders: { authorization: `Bot ${credentials.token}` },\n\t\t\tsignal: AbortSignal.timeout(15_000)\n\t\t});\n\n\t\tif (response.status === 204) return null;\n\n\t\tconst body: unknown = await response.json().catch(() => null);\n\t\tif (!response.ok) {\n\t\t\tconst detail = typeof body === 'object' && body !== null && 'message' in body ? String((body as { message: unknown }).message) : '';\n\t\t\tthrow cliDiagnostics.DISCORD_REQUEST_FAILED({ status: response.status, detail });\n\t\t}\n\n\t\treturn body;\n\t};\n\n\treturn {\n\t\tapplicationId,\n\t\tasync listCommands(guildId) {\n\t\t\tconst body = await request('GET', scope(guildId));\n\t\t\treturn Array.isArray(body) ? (body as ApplicationCommand[]) : [];\n\t\t},\n\t\tasync deleteCommand(guildId, commandId) {\n\t\t\tawait request('DELETE', `${scope(guildId)}/${commandId}`);\n\t\t}\n\t};\n}\n","import type { Diagnostic } from 'nostics';\nimport type { ApplicationCommand } from './discord.js';\nimport { cliDiagnostics } from './diagnostics.js';\n\nexport interface CommandsPrompt {\n\t/** Asks which of the deployed commands to delete. Returns the chosen ids. */\n\tpick(commands: readonly ApplicationCommand[], scope: string): Promise<string[]>;\n\t/** Final go/no-go before anything is deleted. */\n\tconfirm(message: string): Promise<boolean>;\n}\n\n/**\n * The interactive wizard behind `stars commands clean`: a checklist of what Discord has deployed, then a\n * confirmation, so a destructive cleanup is never one keystroke away. `@clack/prompts` is loaded lazily — the\n * non-interactive paths (`--yes`, `--json`, CI) never pay for it.\n */\nexport function createClackPrompt(): CommandsPrompt {\n\treturn {\n\t\tasync pick(commands, scope) {\n\t\t\tconst { isCancel, multiselect } = await import('@clack/prompts');\n\t\t\tconst answer = await multiselect({\n\t\t\t\tmessage: `Which commands should be deleted from ${scope}?`,\n\t\t\t\toptions: commands.map((command) => ({\n\t\t\t\t\tvalue: command.id,\n\t\t\t\t\tlabel: command.name,\n\t\t\t\t\thint: [describeType(command), command.id].filter(Boolean).join(' · ')\n\t\t\t\t})),\n\t\t\t\trequired: false\n\t\t\t});\n\n\t\t\tif (isCancel(answer)) throw aborted();\n\t\t\treturn answer as string[];\n\t\t},\n\t\tasync confirm(message) {\n\t\t\tconst { confirm, isCancel } = await import('@clack/prompts');\n\t\t\tconst answer = await confirm({ message, initialValue: false });\n\n\t\t\tif (isCancel(answer)) throw aborted();\n\t\t\treturn Boolean(answer);\n\t\t}\n\t};\n}\n\nfunction describeType(command: ApplicationCommand): string {\n\tswitch (command.type) {\n\t\tcase 2:\n\t\t\treturn 'user';\n\t\tcase 3:\n\t\t\treturn 'message';\n\t\tdefault:\n\t\t\treturn 'chat input';\n\t}\n}\n\nfunction aborted(): Diagnostic {\n\treturn cliDiagnostics.ABORTED({});\n}\n","import { loadProject } from '../utils/hooks.js';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport type { Diagnostic } from 'nostics';\nimport { COMMAND_TYPE_NAMES, createDiscordClient, type ApplicationCommand, type DiscordClient } from '../utils/discord.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { createClackPrompt, type CommandsPrompt } from '../utils/prompts.js';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\n\nexport interface CommandsTaskOptions extends ProjectArgs {\n\t/** A guild id to work on the guild-scoped commands instead of the global ones. */\n\tguild?: string;\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n\t/** Overrides the client, for tests. */\n\tclient?: DiscordClient;\n}\n\nexport interface CommandsCleanOptions extends CommandsTaskOptions {\n\t/** Names to delete; without any, the wizard asks which of the deployed commands to remove. */\n\tnames?: string[];\n\t/** Deletes without asking. Required in a non-interactive terminal. */\n\tyes?: boolean;\n\tstdin?: NodeJS.ReadableStream & { isTTY?: boolean };\n\t/** Overrides the interactive wizard, for tests. */\n\tprompt?: CommandsPrompt;\n}\n\n/**\n * Lists the application commands Discord currently has deployed, which is not necessarily what the project would\n * register today: renamed and removed commands stay until something deletes them.\n */\nexport async function runCommandsList(options: CommandsTaskOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild } = await connect(options);\n\tconst commands = await client.listCommands(guild);\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify({ applicationId: client.applicationId, guildId: guild, commands }, null, 2)}\\n`);\n\t\treturn;\n\t}\n\n\tif (commands.length === 0) {\n\t\tstdout.write(`${colors.dim('stars')} no ${guild ? `commands in guild ${guild}` : 'global commands'} are deployed\\n`);\n\t\treturn;\n\t}\n\n\tstdout.write(`${colors.dim('stars')} ${commands.length} ${guild ? `command(s) in guild ${guild}` : 'global command(s)'}\\n`);\n\tfor (const command of commands) stdout.write(` ${colors.bold(describeName(command))} ${colors.dim(command.id)}\\n`);\n}\n\n/**\n * Deletes deployed application commands. Discord keeps whatever was registered last, so this is the way to clear\n * commands a project no longer defines (or a whole guild's test deployment).\n */\nexport async function runCommandsClean(options: CommandsCleanOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild } = await connect(options);\n\tconst deployed = await client.listCommands(guild);\n\tconst wanted = options.names?.filter((name) => name.length > 0) ?? [];\n\n\tconst missing = wanted.filter((name) => !deployed.some((command) => command.name === name));\n\tif (missing.length > 0) {\n\t\tthrow cliDiagnostics.COMMAND_NOT_FOUND({ names: missing.join(', ') });\n\t}\n\n\tif (deployed.length === 0) {\n\t\tif (options.json) stdout.write(`${JSON.stringify({ deleted: [] }, null, 2)}\\n`);\n\t\telse stdout.write(`${colors.dim('stars')} nothing to delete\\n`);\n\t\treturn;\n\t}\n\n\tconst scope = guild ? `guild ${guild}` : 'the global scope';\n\tconst targets = await selectTargets(options, deployed, wanted, scope, stdout, colors);\n\tif (targets.length === 0) {\n\t\tif (options.json) stdout.write(`${JSON.stringify({ deleted: [] }, null, 2)}\\n`);\n\t\telse stdout.write(`${colors.dim('stars')} nothing to delete\\n`);\n\t\treturn;\n\t}\n\n\tfor (const command of targets) {\n\t\tawait client.deleteCommand(guild, command.id);\n\t\tif (!options.json) stdout.write(`${colors.dim('stars')} ${colors.red('deleted')} ${describeName(command)}\\n`);\n\t}\n\n\tif (options.json) stdout.write(`${JSON.stringify({ deleted: targets.map((command) => ({ id: command.id, name: command.name })) }, null, 2)}\\n`);\n}\n\n/**\n * Works out what to delete: `--name` (and `--yes`) keep the command scriptable, while a bare `stars commands clean`\n * on a terminal runs the wizard — a checklist of what Discord has deployed, then a confirmation.\n */\nasync function selectTargets(\n\toptions: CommandsCleanOptions,\n\tdeployed: ApplicationCommand[],\n\twanted: string[],\n\tscope: string,\n\tstdout: NodeJS.WritableStream,\n\tcolors: ReturnType<typeof createColors>\n): Promise<ApplicationCommand[]> {\n\tif (wanted.length > 0) {\n\t\tconst named = deployed.filter((command) => wanted.includes(command.name));\n\t\tif (options.yes) return named;\n\n\t\tawait confirmOrThrow(options, stdout, colors, `delete ${colors.bold(String(named.length))} command(s) from ${scope}?`);\n\t\treturn named;\n\t}\n\n\tif (options.yes) return deployed;\n\n\tconst stdin = options.stdin ?? process.stdin;\n\tif (!options.prompt && !stdin.isTTY) throw confirmationRequired();\n\n\tconst prompt = options.prompt ?? createClackPrompt();\n\tconst chosen = new Set(await prompt.pick(deployed, scope));\n\tconst targets = deployed.filter((command) => chosen.has(command.id));\n\tif (targets.length === 0) return [];\n\n\tconst names = targets.map((command) => command.name).join(', ');\n\tif (!(await prompt.confirm(`Delete ${targets.length} command(s) from ${scope}: ${names}?`))) {\n\t\tthrow cliDiagnostics.ABORTED({});\n\t}\n\n\treturn targets;\n}\n\nasync function connect(options: CommandsTaskOptions): Promise<{ client: DiscordClient; guild: string | null }> {\n\tconst { config } = await loadProject({ cwd: resolveCwd(options), configFile: options.config });\n\treturn { client: options.client ?? createDiscordClient(config), guild: options.guild ?? null };\n}\n\nfunction describeName(command: ApplicationCommand): string {\n\tconst type = command.type && command.type !== 1 ? ` (${COMMAND_TYPE_NAMES[command.type] ?? `type ${command.type}`})` : '';\n\treturn `${command.name}${type}`;\n}\n\n/**\n * Deleting deployed commands is not reversible, so a terminal run asks first; scripts pass `--yes`.\n */\nasync function confirmOrThrow(\n\toptions: CommandsCleanOptions,\n\tstdout: NodeJS.WritableStream,\n\tcolors: ReturnType<typeof createColors>,\n\tquestion: string\n): Promise<void> {\n\tif (options.prompt) {\n\t\tif (await options.prompt.confirm(question)) return;\n\t\tthrow cliDiagnostics.ABORTED({});\n\t}\n\n\tconst stdin = options.stdin ?? process.stdin;\n\tif (!stdin.isTTY) throw confirmationRequired();\n\n\tstdout.write(`${colors.dim('stars')} ${question} [y/N] `);\n\treturn new Promise((resolve, reject) => {\n\t\tstdin.setEncoding?.('utf-8');\n\t\tstdin.once('data', (chunk: string) => {\n\t\t\tstdin.pause?.();\n\t\t\tconst answer = chunk.trim().toLowerCase();\n\t\t\tif (answer === 'y' || answer === 'yes') resolve();\n\t\t\telse reject(cliDiagnostics.ABORTED({}));\n\t\t});\n\t\tstdin.resume?.();\n\t});\n}\n\nfunction confirmationRequired(): Diagnostic {\n\treturn cliDiagnostics.CONFIRMATION_REQUIRED({});\n}\n\nconst scopeArgs = {\n\t...projectArgs,\n\tguild: {\n\t\ttype: 'string',\n\t\tdescription: 'Work on a guild’s commands instead of the global ones'\n\t},\n\tjson: {\n\t\ttype: 'boolean',\n\t\tdescription: 'Print machine-readable JSON',\n\t\tdefault: false\n\t}\n} as const;\n\nconst list = defineCommand({\n\tmeta: { name: 'list', description: 'List the application commands Discord has deployed' },\n\targs: scopeArgs,\n\tasync run({ args }) {\n\t\tawait runCommandsList({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json });\n\t}\n});\n\nconst clean = defineCommand({\n\tmeta: { name: 'clean', description: 'Delete deployed application commands (all of them, or the named ones)' },\n\targs: {\n\t\t...scopeArgs,\n\t\tname: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Only delete the command with this name (repeatable)'\n\t\t},\n\t\tyes: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'y',\n\t\t\tdescription: 'Delete without asking for a confirmation',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst names = Array.isArray(args.name) ? args.name : args.name ? [args.name] : [];\n\t\tawait runCommandsClean({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json, names, yes: args.yes });\n\t}\n});\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'commands',\n\t\tdescription: 'Inspect and clean the application commands deployed to Discord'\n\t},\n\tsubCommands: { list, clean },\n\targs: scopeArgs,\n\tasync run({ args, rawArgs }) {\n\t\t// `stars commands` with no subcommand lists, the way `git branch` does.\n\t\tif (rawArgs.some((argument) => argument === 'list' || argument === 'clean')) return;\n\n\t\tawait runCommandsList({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json });\n\t}\n});\n"],"mappings":"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"}
|
package/dist/dev-4wpEQC7l.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-4wpEQC7l.js","names":[],"sources":["../src/utils/env-import.ts","../src/dev/typechecker.ts","../src/dev/dev-service.ts","../src/dev/host.ts","../src/dev/log-file.ts","../src/commands/dev.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { envModuleSource } from '@wolfstar/vite-server/internal';\nimport { pathToFileURL } from 'node:url';\nimport { resolveFromProject } from './project.js';\n\n/** Build tools whose output never passes through the entry transform that registers `env`. */\nconst UNTRANSFORMED_TOOLS = new Set<string>(['none', 'tsc']);\n\n/**\n * `node` arguments that register `env` before the entry runs, for the build tools the entry transform cannot reach.\n * The preload is a `data:` URL, so `.stars/` gets no generated runtime file; a `data:` URL cannot resolve bare\n * specifiers, so `@wolfstar/env-utilities` is resolved from the project first. When it cannot be resolved nothing is\n * preloaded, and the bot's own import of it reports the missing install.\n */\nexport function envImportArgs(config: ResolvedStarsConfig): string[] {\n\tif (!config.env.enabled || !UNTRANSFORMED_TOOLS.has(config.build.tool)) return [];\n\n\tconst resolved = resolveFromProject(config.root, '@wolfstar/env-utilities');\n\tif (resolved === null) return [];\n\n\tconst source = envModuleSource(config.env.options, pathToFileURL(resolved).href);\n\treturn ['--import', `data:text/javascript,${encodeURIComponent(source)}`];\n}\n","import type { ResolvedStarsConfig, StarsTypechecker } from '@wolfstar/schema';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport type { Diagnostic } from 'nostics';\nimport { resolveTscBinary } from '../builders/tsc.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport type { LogLevel } from '../utils/log-buffer.js';\nimport { createLineSplitter } from '../utils/process-supervisor.js';\nimport { resolveBinary } from '../utils/project.js';\n\nconst WATCH_START = /Starting (incremental )?compilation/;\nconst WATCH_DONE = /Found (\\d+) errors?\\. Watching for file changes/;\nconst ONE_SHOT_DONE = /Found (\\d+) errors?/;\nconst ERROR_LINE = /error TS\\d+:/;\n\nexport type TypecheckState = 'idle' | 'checking' | 'ok' | 'failed';\n\nexport interface TypecheckerEvents {\n\tlog: [level: LogLevel, text: string];\n\tstate: [state: TypecheckState, errors: number];\n}\n\nexport interface TypecheckCommand {\n\t/** The executable, and whether it is a script `node` has to run. */\n\treadonly command: string;\n\treadonly args: readonly string[];\n\treadonly node: boolean;\n\t/** Whether the checker watches the project itself, or has to be re-run after every build. */\n\treadonly watch: boolean;\n}\n\n/**\n * Runs a type checker next to the bot and reports type errors on their own channel, without ever blocking builds or\n * restarts: `stars dev` keeps running whatever the build tool produced, the way Seedcord's `hmr.typecheck` and\n * Vite's `checker` plugin do.\n *\n * `tsc` and `golar` (which forwards to TypeScript) watch the project themselves; `tsz` has no watch mode, so\n * {@link Typechecker.check} re-runs it after every build instead.\n */\nexport class Typechecker extends EventEmitter<TypecheckerEvents> {\n\t#child: ChildProcess | null = null;\n\t#state: TypecheckState = 'idle';\n\t#errors = 0;\n\t#pending = false;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t}\n\n\tpublic get state(): TypecheckState {\n\t\treturn this.#state;\n\t}\n\n\tpublic get errors(): number {\n\t\treturn this.#errors;\n\t}\n\n\t/** Whether the checker re-runs per build instead of watching on its own. */\n\tpublic get oneShot(): boolean {\n\t\treturn this.config.dev.typecheck.enabled && !resolveTypecheckCommand(this.config).watch;\n\t}\n\n\tpublic start(): void {\n\t\tif (!this.config.dev.typecheck.enabled) return;\n\t\tthis.#run();\n\t}\n\n\t/**\n\t * Re-runs a checker that cannot watch. Called after every successful build; a run already in flight is replaced,\n\t * so a fast series of builds only leaves the last check standing.\n\t */\n\tpublic check(): void {\n\t\tif (!this.oneShot) return;\n\t\tif (this.#child) {\n\t\t\tthis.#pending = true;\n\t\t\tthis.#child.kill();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.#run();\n\t}\n\n\tpublic close(): Promise<void> {\n\t\tconst child = this.#child;\n\t\tthis.#child = null;\n\t\tthis.#pending = false;\n\t\tif (!child || child.exitCode !== null) return Promise.resolve();\n\n\t\treturn new Promise((resolve) => {\n\t\t\tchild.once('exit', () => resolve());\n\t\t\tchild.kill();\n\t\t});\n\t}\n\n\t#run(): void {\n\t\tconst { command, args, node, watch } = resolveTypecheckCommand(this.config);\n\t\tconst child = spawn(node ? process.execPath : command, node ? [command, ...args] : [...args], {\n\t\t\tcwd: this.config.root,\n\t\t\tenv: process.env,\n\t\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\t\twindowsHide: true\n\t\t});\n\t\tthis.#child = child;\n\t\tthis.#setState('checking', 0);\n\n\t\tlet errors = 0;\n\t\tconst handleLine = (line: string) => {\n\t\t\tif (ERROR_LINE.test(line)) errors++;\n\t\t\tthis.#handleLine(line);\n\t\t};\n\n\t\tconst stdout = createLineSplitter(handleLine);\n\t\tconst stderr = createLineSplitter(handleLine);\n\t\tchild.stdout?.on('data', stdout.push);\n\t\tchild.stderr?.on('data', stderr.push);\n\n\t\tchild.once('exit', (code) => {\n\t\t\tstdout.flush();\n\t\t\tstderr.flush();\n\t\t\tthis.#child = null;\n\n\t\t\tif (!watch && this.#state === 'checking') {\n\t\t\t\t// A one-shot checker only reports through its exit code when it prints no summary line.\n\t\t\t\tthis.#setState(code === 0 && errors === 0 ? 'ok' : 'failed', errors);\n\t\t\t}\n\n\t\t\tif (this.#pending) {\n\t\t\t\tthis.#pending = false;\n\t\t\t\tthis.#run();\n\t\t\t}\n\t\t});\n\t\tchild.once('error', (error: NodeJS.ErrnoException) => {\n\t\t\tthis.#child = null;\n\t\t\tthis.emit('log', 'error', error.code === 'ENOENT' ? `${command} is not installed` : error.message);\n\t\t\tthis.#setState('failed', this.#errors);\n\t\t});\n\t}\n\n\t#handleLine(line: string): void {\n\t\tconst text = line.trim();\n\t\tif (text.length === 0) return;\n\n\t\tif (WATCH_START.test(text)) {\n\t\t\tthis.#setState('checking', 0);\n\t\t\treturn;\n\t\t}\n\n\t\tif (ERROR_LINE.test(text)) {\n\t\t\tthis.emit('log', 'error', text);\n\t\t\treturn;\n\t\t}\n\n\t\tconst done = WATCH_DONE.exec(text) ?? ONE_SHOT_DONE.exec(text);\n\t\tif (done) {\n\t\t\tconst errors = Number(done[1]);\n\t\t\tthis.#setState(errors === 0 ? 'ok' : 'failed', errors);\n\t\t\tthis.emit('log', errors === 0 ? 'success' : 'error', errors === 0 ? 'No type errors' : `${errors} type error${errors === 1 ? '' : 's'}`);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.emit('log', 'info', text);\n\t}\n\n\t#setState(state: TypecheckState, errors: number): void {\n\t\tthis.#state = state;\n\t\tthis.#errors = errors;\n\t\tthis.emit('state', state, errors);\n\t}\n}\n\n/**\n * Builds the command line of the configured type checker, resolved from the project's own `node_modules`.\n *\n * @throws {Diagnostic} when the checker is not installed in the project.\n */\nexport function resolveTypecheckCommand(config: ResolvedStarsConfig): TypecheckCommand {\n\tconst { checker, tsconfig } = config.dev.typecheck;\n\tconst project = tsconfig!;\n\n\tswitch (checker) {\n\t\tcase 'golar': {\n\t\t\t// `golar tsc` forwards everything after it to the TypeScript CLI, watch mode included.\n\t\t\tconst golar = resolveBinary(config.root, 'golar', 'golar');\n\t\t\tif (!golar) throw missing(config, 'golar', 'Install it with `pnpm add -D golar`');\n\n\t\t\treturn { command: golar, args: ['tsc', ...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\n\t\tcase 'tsz': {\n\t\t\t// `tsz` is an early, tsc-compatible checker with no watch mode; `try-tsz` is its comparison harness.\n\t\t\tconst tsz = resolveBinary(config.root, '@mohsen-azimi/tsz-dev', 'tsz');\n\t\t\tif (tsz) return { command: tsz, args: ['--noEmit', '-p', project], node: true, watch: false };\n\n\t\t\tconst tryTsz = resolveBinary(config.root, 'try-tsz', 'try-tsz');\n\t\t\tif (tryTsz) return { command: tryTsz, args: ['-p', project], node: true, watch: false };\n\n\t\t\tthrow missing(config, 'tsz', 'Install it with `pnpm add -D @mohsen-azimi/tsz-dev` (or `try-tsz`)');\n\t\t}\n\n\t\tdefault: {\n\t\t\tconst tsc = resolveTscBinary(config.root);\n\t\t\tif (!tsc) throw missing(config, 'typescript', 'Install it with `pnpm add -D typescript`');\n\n\t\t\treturn { command: tsc, args: [...WATCH_ARGS, '-p', project], node: true, watch: true };\n\t\t}\n\t}\n}\n\nconst WATCH_ARGS = ['--noEmit', '--watch', '--preserveWatchOutput', '--pretty', 'false'] as const;\n\nfunction missing(config: ResolvedStarsConfig, name: string, install: string): Diagnostic {\n\treturn cliDiagnostics.DEPENDENCY_MISSING({\n\t\tname,\n\t\troot: config.root,\n\t\thint: `${install}, pick another \\`dev.typecheck.checker\\`, or set \\`dev.typecheck\\` to false.`\n\t});\n}\n\nexport type { StarsTypechecker };\n","import { EventEmitter } from 'node:events';\nimport type { Builder, BuildOutcome } from '../builders/types.js';\nimport { displayPath, type ResolvedStarsConfig, type StarsHooks, type StarsRestartReason } from '@wolfstar/schema';\nimport { envImportArgs } from '../utils/env-import.js';\nimport type { StarsHookable } from '../utils/hooks.js';\nimport { classifyAppLine, LogBuffer, type LogLevel, type LogSource } from '../utils/log-buffer.js';\nimport { Locales } from '../utils/locales.js';\nimport { ProcessSupervisor, type ProcessExit, type ProcessState } from '../utils/process-supervisor.js';\nimport { Tunnel, type TunnelState } from './tunnel.js';\nimport { Typechecker, type TypecheckState } from './typechecker.js';\n\nexport type BuildState = 'idle' | 'building' | 'ok' | 'failed';\nexport type HealthState = 'unknown' | 'ok' | 'down';\nexport type RestartReason = StarsRestartReason;\n\nexport interface DevStatus {\n\treadonly progress: { readonly fraction: number; readonly message: string; readonly startedAt: number; readonly readyMs: number | null };\n\treadonly process: ProcessState;\n\treadonly build: BuildState;\n\treadonly health: HealthState;\n\treadonly pid: number | null;\n\treadonly startedAt: number | null;\n\treadonly restarts: number;\n\treadonly lastRestartReason: RestartReason | null;\n\treadonly lastBuild: BuildOutcome | null;\n\treadonly lastExit: ProcessExit | null;\n\treadonly url: string | null;\n\treadonly typecheck: TypecheckState;\n\treadonly typeErrors: number;\n\treadonly tunnel: TunnelState;\n\treadonly tunnelUrl: string | null;\n}\n\nexport interface DevServiceEvents {\n\tstatus: [status: DevStatus];\n}\n\nexport interface DevServiceOptions {\n\tbuilder: Builder;\n\t/** The `stars.config` hooks; `build:*` and `dev:restart` run from here. */\n\thooks?: StarsHookable;\n\tlogs?: LogBuffer;\n\t/** Overrides for tests. */\n\tsupervisor?: ProcessSupervisor;\n\ttypechecker?: Typechecker;\n\ttunnel?: Tunnel;\n\thealthInterval?: number;\n}\n\n/**\n * The headless heart of `stars dev`: builds, (re)starts the bot and exposes state and logs.\n * Renderers (plain or TUI) only subscribe to it, they never own behaviour.\n */\nexport class DevService extends EventEmitter<DevServiceEvents> {\n\tpublic readonly logs: LogBuffer;\n\tpublic readonly builder: Builder;\n\tpublic readonly supervisor: ProcessSupervisor;\n\tpublic readonly typechecker: Typechecker;\n\tpublic readonly tunnel: Tunnel;\n\tpublic readonly locales: Locales;\n\treadonly #hooks: StarsHookable | null;\n\t/** Runs hooks one at a time, so an async `build:done` settles before the next build's hooks or a restart. */\n\t#hookChain: Promise<void> = Promise.resolve();\n\n\t#build: BuildState = 'idle';\n\t#health: HealthState = 'unknown';\n\t#restarts = 0;\n\t#lastRestartReason: RestartReason | null = null;\n\t#lastBuild: BuildOutcome | null = null;\n\t#lastExit: ProcessExit | null = null;\n\t#restartTimer: NodeJS.Timeout | null = null;\n\t#healthTimer: NodeJS.Timeout | null = null;\n\t#pendingReason: RestartReason | null = null;\n\t#stopped = false;\n\t#queue: Promise<void> = Promise.resolve();\n\t#progress = { fraction: 0, message: 'preparing your app', startedAt: Date.now(), readyMs: null as number | null };\n\n\tpublic constructor(\n\t\tpublic readonly config: ResolvedStarsConfig,\n\t\toptions: DevServiceOptions\n\t) {\n\t\tsuper();\n\t\tthis.logs = options.logs ?? new LogBuffer();\n\t\tthis.builder = options.builder;\n\t\tthis.supervisor = options.supervisor ?? createSupervisor(config);\n\t\tthis.typechecker = options.typechecker ?? new Typechecker(config);\n\t\tthis.tunnel = options.tunnel ?? new Tunnel(config);\n\t\tthis.locales = new Locales(config);\n\t\tthis.#hooks = options.hooks ?? null;\n\n\t\tthis.builder.on('start', () => {\n\t\t\tthis.#progress = { fraction: 0, message: 'preparing build', startedAt: Date.now(), readyMs: null };\n\t\t\tthis.#setBuild('building');\n\t\t\tvoid this.#startHook('build:before', this.config);\n\t\t});\n\t\tthis.builder.on('progress', (fraction, message) => {\n\t\t\tthis.#progress = { ...this.#progress, fraction: Math.max(this.#progress.fraction, Math.min(0.75, fraction)), message };\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.builder.on('success', (outcome) => this.#onBuildSuccess(outcome));\n\t\tthis.builder.on('failure', (outcome) => this.#onBuildFailure(outcome));\n\t\tthis.builder.on('log', (level, text) => this.log('build', level, text));\n\n\t\tthis.supervisor.on('state', () => {\n\t\t\tif (this.supervisor.state === 'running') {\n\t\t\t\tthis.#settleProgress();\n\t\t\t\tvoid this.#checkHealth();\n\t\t\t}\n\t\t\tthis.#emitStatus();\n\t\t});\n\t\tthis.supervisor.on('stdout', (line) => this.log('app', classifyAppLine(line, 'info'), line));\n\t\tthis.supervisor.on('stderr', (line) => this.log('app', classifyAppLine(line, 'error'), line));\n\t\tthis.supervisor.on('error', (error) => this.log('stars', 'error', `Failed to start the bot: ${error.message}`));\n\t\tthis.supervisor.on('exit', (exit) => this.#onExit(exit));\n\n\t\tthis.typechecker.on('log', (level, text) => this.log('tsc', level, text));\n\t\tthis.typechecker.on('state', () => this.#emitStatus());\n\t\tthis.tunnel.on('log', (level, text) => this.log('tunnel', level, text));\n\t\tthis.tunnel.on('state', () => this.#emitStatus());\n\t\tthis.locales.on('log', (level, text) => this.log('build', level, text));\n\t\tthis.locales.on('change', () => {\n\t\t\tif (this.#build === 'ok') this.#scheduleRestart('build');\n\t\t});\n\n\t\tif (config.dev.url && config.dev.health) {\n\t\t\tconst interval = options.healthInterval ?? 5000;\n\t\t\tthis.#healthTimer = setInterval(() => void this.#checkHealth(), interval);\n\t\t\tthis.#healthTimer.unref();\n\t\t}\n\t}\n\n\tpublic get status(): DevStatus {\n\t\treturn {\n\t\t\tprogress: this.#progress,\n\t\t\tprocess: this.supervisor.state,\n\t\t\tbuild: this.#build,\n\t\t\thealth: this.#health,\n\t\t\tpid: this.supervisor.pid,\n\t\t\tstartedAt: this.supervisor.startedAt,\n\t\t\trestarts: this.#restarts,\n\t\t\tlastRestartReason: this.#lastRestartReason,\n\t\t\tlastBuild: this.#lastBuild,\n\t\t\tlastExit: this.#lastExit,\n\t\t\turl: this.config.dev.url,\n\t\t\ttypecheck: this.typechecker.state,\n\t\t\ttypeErrors: this.typechecker.errors,\n\t\t\ttunnel: this.tunnel.state,\n\t\t\ttunnelUrl: this.tunnel.url\n\t\t};\n\t}\n\n\tpublic log(source: LogSource, level: LogLevel, text: string): void {\n\t\tthis.logs.push({ source, level, text });\n\t}\n\n\t/**\n\t * Starts watching; the bot starts after the first successful build.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tthis.#stopped = false;\n\t\tconst entry = displayPath(this.config.root, this.config.entry);\n\t\tthis.log('stars', 'info', this.config.build.tool === 'none' ? `Watching ${entry}` : `Watching ${entry} with ${this.config.build.tool}`);\n\t\tif (this.config.dev.typecheck.enabled) this.typechecker.start();\n\t\tawait this.locales.watch();\n\t\t// The tunnel comes up next to the build: neither waits for the other, and a failed tunnel never stops the bot.\n\t\tvoid this.tunnel.start();\n\t\tawait this.builder.watch();\n\t}\n\n\t/**\n\t * Restarts the bot immediately (used by the `r` key and by `SIGUSR2`).\n\t */\n\tpublic restart(reason: RestartReason = 'manual'): Promise<void> {\n\t\tthis.#clearRestartTimer();\n\t\treturn this.#enqueue(async () => {\n\t\t\tif (this.#stopped) return;\n\t\t\tawait this.#queueHook('dev:restart', reason, this.config);\n\t\t\tif (this.#stopped) return;\n\t\t\tif (reason === 'manual' || reason === 'crash') {\n\t\t\t\tthis.#progress = { fraction: 0, message: 'restarting the bot', startedAt: Date.now(), readyMs: null };\n\t\t\t}\n\t\t\tthis.#lastRestartReason = reason;\n\t\t\tif (this.supervisor.running) {\n\t\t\t\tthis.#restarts++;\n\t\t\t\tthis.log('stars', 'info', `Restarting (${describeReason(reason)})`);\n\t\t\t\tawait this.supervisor.stop();\n\t\t\t} else {\n\t\t\t\tthis.log('stars', 'info', `Starting (${describeReason(reason)})`);\n\t\t\t}\n\n\t\t\tif (this.#stopped) return;\n\t\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\t\tthis.#health = 'unknown';\n\t\t\tthis.supervisor.start();\n\t\t\tthis.#emitStatus();\n\t\t});\n\t}\n\n\t/** Opens or closes the public tunnel (used by the `t` key). */\n\tpublic toggleTunnel(): Promise<void> {\n\t\treturn this.tunnel.toggle();\n\t}\n\n\t/**\n\t * Stops the watcher and the bot. Safe to call more than once.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tthis.#stopped = true;\n\t\tthis.#clearRestartTimer();\n\t\tif (this.#healthTimer) clearInterval(this.#healthTimer);\n\t\tthis.#healthTimer = null;\n\t\tawait this.#enqueue(async () => {\n\t\t\tawait Promise.allSettled([\n\t\t\t\tthis.builder.close(),\n\t\t\t\tthis.supervisor.stop(),\n\t\t\t\tthis.typechecker.close(),\n\t\t\t\tthis.tunnel.close(),\n\t\t\t\tthis.locales.close()\n\t\t\t]);\n\t\t});\n\t}\n\n\t/**\n\t * Kills the bot and the helper processes without waiting for them. Only for a forced shutdown, {@link stop} is the graceful path.\n\t */\n\tpublic kill(): void {\n\t\tthis.#stopped = true;\n\t\tthis.#clearRestartTimer();\n\t\tthis.supervisor.kill();\n\t\tvoid this.typechecker.close();\n\t\tvoid this.tunnel.close();\n\t}\n\n\tpublic clearLogs(): void {\n\t\tthis.logs.clear();\n\t}\n\n\t#onBuildSuccess(outcome: BuildOutcome): void {\n\t\ttry {\n\t\t\tthis.locales.copy();\n\t\t} catch (error) {\n\t\t\tthis.#onBuildFailure({\n\t\t\t\t...outcome,\n\t\t\t\tok: false,\n\t\t\t\tmessage: `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.#lastBuild = outcome;\n\t\tthis.#progress = { ...this.#progress, fraction: 0.75, message: 'starting the bot' };\n\t\tthis.#setBuild('ok');\n\t\t// Only once locales are copied: until then the build is not done, and may still fail.\n\t\tvoid this.#queueHook('build:done', outcome, this.config);\n\t\tif (this.#stopped) return;\n\t\t// A checker without a watch mode (`tsz`) only knows about the change once the build is through.\n\t\tthis.typechecker.check();\n\t\tthis.log('stars', 'success', this.builder.tool === 'none' ? 'Sources changed' : `Build succeeded in ${outcome.durationMs}ms`);\n\t\tthis.#scheduleRestart(this.supervisor.state === 'idle' ? 'initial' : 'build');\n\t}\n\n\t#onBuildFailure(outcome: BuildOutcome): void {\n\t\tthis.#lastBuild = outcome;\n\t\tvoid this.#queueHook('build:done', outcome, this.config);\n\t\tthis.#setBuild('failed');\n\t\tthis.#clearRestartTimer();\n\t\tthis.log('stars', 'error', `Build failed${outcome.message ? `: ${outcome.message}` : ''}, waiting for changes`);\n\t}\n\n\t#onExit(exit: ProcessExit): void {\n\t\tthis.#lastExit = exit;\n\t\tthis.#health = 'unknown';\n\t\tif (!exit.requested) {\n\t\t\tconst how = exit.signal ? `signal ${exit.signal}` : `code ${exit.code}`;\n\t\t\tthis.log('stars', exit.code === 0 ? 'warn' : 'error', `The bot exited with ${how}, waiting for changes (press r to restart)`);\n\t\t}\n\t\tthis.#emitStatus();\n\t}\n\n\t#scheduleRestart(reason: RestartReason): void {\n\t\tthis.#pendingReason = reason;\n\t\tthis.#clearRestartTimer();\n\t\tthis.#restartTimer = setTimeout(() => {\n\t\t\tthis.#restartTimer = null;\n\t\t\tconst pending = this.#pendingReason ?? reason;\n\t\t\tthis.#pendingReason = null;\n\t\t\tvoid this.restart(pending);\n\t\t}, this.config.dev.debounce);\n\t}\n\n\t#clearRestartTimer(): void {\n\t\tif (this.#restartTimer) clearTimeout(this.#restartTimer);\n\t\tthis.#restartTimer = null;\n\t}\n\n\t#enqueue(task: () => Promise<void>): Promise<void> {\n\t\tthis.#queue = this.#queue.then(task, task);\n\t\treturn this.#queue;\n\t}\n\n\t#setBuild(state: BuildState): void {\n\t\tif (this.#build === state) return;\n\t\tthis.#build = state;\n\t\tthis.#emitStatus();\n\t}\n\n\tasync #checkHealth(): Promise<void> {\n\t\tif (!this.supervisor.running || !this.config.dev.url || !this.config.dev.health) return;\n\t\tconst pid = this.supervisor.pid;\n\n\t\tlet next: HealthState;\n\t\ttry {\n\t\t\tconst response = await fetch(new URL(this.config.dev.health, this.config.dev.url), { signal: AbortSignal.timeout(2000) });\n\t\t\tnext = response.status < 500 ? 'ok' : 'down';\n\t\t} catch {\n\t\t\tnext = 'down';\n\t\t}\n\n\t\tif (this.#stopped || pid !== this.supervisor.pid) return;\n\t\tif (next !== this.#health) {\n\t\t\tthis.#health = next;\n\t\t\tif (next === 'ok') this.#settleProgress();\n\t\t\tthis.#emitStatus();\n\t\t}\n\t}\n\n\t#settleProgress(): void {\n\t\tif (this.config.dev.health && this.#health !== 'ok') return;\n\t\tif (this.#build !== 'ok') return;\n\t\tthis.#progress = {\n\t\t\t...this.#progress,\n\t\t\tfraction: 1,\n\t\t\tmessage: 'watching for changes',\n\t\t\treadyMs: this.#progress.readyMs ?? Date.now() - this.#progress.startedAt\n\t\t};\n\t}\n\n\t/**\n\t * Runs a hook behind the ones already running (see {@link DevService.#hookChain}), e.g. `dev:close` so shutdown\n\t * waits for an unfinished `build:done`.\n\t */\n\tpublic runHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\treturn this.#queueHook(name, ...args);\n\t}\n\n\t/** Queues a hook behind the ones already running; see {@link DevService.#hookChain}. */\n\t#queueHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tthis.#hookChain = this.#hookChain.then(() => this.#callHook(name, ...args));\n\t\treturn this.#hookChain;\n\t}\n\n\t/**\n\t * Starts a hook right away, at the moment it describes, instead of queueing it: `build:before` belongs to the\n\t * builder's `start` boundary, and a builder such as `none` finishes in the same call stack. Its synchronous part\n\t * runs here; later hooks still wait for the rest.\n\t */\n\t#startHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tconst running = this.#callHook(name, ...args);\n\t\tthis.#hookChain = Promise.all([this.#hookChain, running]).then(() => undefined);\n\t\treturn running;\n\t}\n\n\t/**\n\t * Runs a `stars.config` hook. A failing hook is logged rather than thrown: a broken hook must never stop the\n\t * watcher or keep the bot from restarting.\n\t */\n\tasync #callHook<Name extends keyof StarsHooks>(name: Name, ...args: Parameters<StarsHooks[Name]>): Promise<void> {\n\t\tif (this.#hooks === null) return;\n\t\ttry {\n\t\t\tawait this.#hooks.callHook(name, ...args);\n\t\t} catch (error) {\n\t\t\tthis.log('stars', 'error', `Hook ${name} failed: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\t#emitStatus(): void {\n\t\tthis.emit('status', this.status);\n\t}\n}\n\nexport function createSupervisor(config: ResolvedStarsConfig): ProcessSupervisor {\n\treturn new ProcessSupervisor({\n\t\tcommand: process.execPath,\n\t\targs: [...envImportArgs(config), ...config.dev.nodeArgs, config.build.output, ...config.dev.args],\n\t\tcwd: config.root,\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...config.dev.env,\n\t\t\tSTARS_DEV: '1',\n\t\t\tNODE_ENV: 'development',\n\t\t\tFORCE_COLOR: process.env.NO_COLOR !== undefined ? undefined : (process.env.FORCE_COLOR ?? (process.stdout.isTTY ? '1' : undefined))\n\t\t},\n\t\tkillTimeout: config.dev.killTimeout\n\t});\n}\n\nexport function describeReason(reason: RestartReason): string {\n\tswitch (reason) {\n\t\tcase 'initial':\n\t\t\treturn 'first build';\n\t\tcase 'build':\n\t\t\treturn 'sources changed';\n\t\tcase 'manual':\n\t\t\treturn 'manual restart';\n\t\tcase 'crash':\n\t\t\treturn 'after crash';\n\t}\n}\n","import { lookup } from 'node:dns/promises';\n\n/**\n * Resolves `localhost` the way Vite's dev server does: Node's default DNS result order (`dns.lookup('localhost')`)\n * can disagree with the OS's own, \"verbatim\" resolution order — a well known source of a dev URL that prints fine\n * but is not the address the bot actually bound to (e.g. an IPv6-first system where the server listens on IPv4\n * only). When the two disagree this returns the OS's own address instead of the literal `localhost` hostname.\n */\nexport async function resolveLocalhost(): Promise<string> {\n\ttry {\n\t\tconst [ordered, verbatim] = await Promise.all([lookup('localhost'), lookup('localhost', { verbatim: true })]);\n\t\treturn ordered.family === verbatim.family && ordered.address === verbatim.address ? 'localhost' : verbatim.address;\n\t} catch {\n\t\treturn 'localhost';\n\t}\n}\n\n/**\n * Replaces a `localhost` hostname in `url` with {@link resolveLocalhost}'s result. Any other hostname (an explicit\n * `dev.url` override, a LAN address, …) is returned untouched.\n */\nexport async function withResolvedLocalhost(url: string): Promise<string> {\n\tconst parsed = new URL(url);\n\tif (parsed.hostname !== 'localhost') return url;\n\n\tconst host = await resolveLocalhost();\n\tif (host === 'localhost') return url;\n\n\tparsed.hostname = host.includes(':') ? `[${host}]` : host;\n\treturn parsed.href;\n}\n","import { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport { dirname } from 'node:path';\nimport type { LogBuffer, LogEntry } from '../utils/log-buffer.js';\n\n/**\n * Mirrors a dev session's logs into a file, so a run can be read back after the terminal UI is gone (the TUI takes\n * over the alternate screen and its scrollback disappears on exit). Seedcord keeps a `logs/` directory for the same\n * reason; this writes a single, truncated-per-run file instead.\n */\nexport class LogFileWriter {\n\t#stream: WriteStream | null = null;\n\n\tpublic constructor(\n\t\tpublic readonly file: string,\n\t\tprivate readonly logs: LogBuffer\n\t) {}\n\n\tpublic open(): void {\n\t\tif (this.#stream) return;\n\n\t\tmkdirSync(dirname(this.file), { recursive: true });\n\t\tthis.#stream = createWriteStream(this.file, { flags: 'w' });\n\t\t// A broken pipe or a read-only directory must never take the dev session down with it.\n\t\tthis.#stream.on('error', () => this.close());\n\n\t\tfor (const entry of this.logs.entries()) this.#write(entry);\n\t\tthis.logs.on('entry', this.#write);\n\t}\n\n\tpublic close(): void {\n\t\tconst stream = this.#stream;\n\t\tthis.#stream = null;\n\t\tif (!stream) return;\n\n\t\tthis.logs.off('entry', this.#write);\n\t\tstream.end();\n\t}\n\n\t#write = (entry: LogEntry): void => {\n\t\tthis.#stream?.write(`${format(entry)}\\n`);\n\t};\n}\n\nfunction format(entry: LogEntry): string {\n\treturn `${new Date(entry.time).toISOString()} ${entry.level.padEnd(7)} ${entry.source.padEnd(6)} ${entry.text}`;\n}\n","import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { defineCommand } from 'citty';\nimport { createBuilder } from '../builders/index.js';\nimport { DevService } from '../dev/dev-service.js';\nimport { withResolvedLocalhost } from '../dev/host.js';\nimport { LogFileWriter } from '../dev/log-file.js';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { ExitCode, renderCrashReport } from '../utils/errors.js';\nimport { applyEnvOptions, loadProject, withProjectEnv } from '../utils/hooks.js';\nimport { prefersReducedMotion, resolveOutputMode, shouldUseColor } from '../utils/output-mode.js';\nimport { THEME_SETTINGS, isThemeSetting, readSavedTheme, resolveThemeSetting, saveTheme } from '../utils/theme.js';\nimport { prepareProject, reportWarnings } from './_shared.js';\n\nexport interface DevTaskOptions extends ProjectArgs {\n\ttui?: boolean;\n\t/** `--theme`. */\n\ttheme?: string;\n}\n\nexport async function runDev(options: DevTaskOptions): Promise<void> {\n\tif (options.theme !== undefined && !isThemeSetting(options.theme)) {\n\t\tthrow cliDiagnostics.INVALID_THEME({ theme: options.theme, themes: THEME_SETTINGS.join(', ') });\n\t}\n\n\t// Dev mode applies to config evaluation, build plugins, and the supervised application — not only the child.\n\tprocess.env.NODE_ENV = 'development';\n\tconst project = await loadProject({ cwd: resolveCwd(options), configFile: options.config, env: { ...process.env, NODE_ENV: 'development' } });\n\tconst hooks = project.hooks;\n\t// `env:options` first: it may pick env files with another `HTTP_PORT`, which `dev.url` is derived from.\n\tconst config = await resolveDevConfig(withProjectEnv(await applyEnvOptions(project.config, hooks)));\n\tconst mode = resolveOutputMode({ tui: options.tui });\n\tconst color = shouldUseColor();\n\tconst theme = resolveThemeSetting({ flag: options.theme, saved: readSavedTheme() });\n\n\tconst builder = await createBuilder(config, hooks);\n\tawait hooks.callHook('builder:created', builder, config);\n\tconst service = new DevService(config, { builder, hooks });\n\tawait reportWarnings(config, (text) => service.log('stars', 'warn', text));\n\tconst logFile = config.dev.logFile ? new LogFileWriter(config.dev.logFile, service.logs) : null;\n\tlogFile?.open();\n\tconst renderer =\n\t\tmode === 'tui'\n\t\t\t? (await import('../dev/tui/tui.js')).createTuiRenderer(service, {\n\t\t\t\t\tcolor,\n\t\t\t\t\ttheme,\n\t\t\t\t\treducedMotion: prefersReducedMotion(),\n\t\t\t\t\tonThemeSave: (setting) => {\n\t\t\t\t\t\tif (!saveTheme(setting)) service.log('stars', 'warn', 'Could not save the theme preference.');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t: (await import('../dev/tui/plain.js')).createPlainRenderer(service, { color });\n\n\tlet exiting: Promise<never> | null = null;\n\tconst shutdown = (code: ExitCode): Promise<never> => {\n\t\texiting ??= (async () => {\n\t\t\trenderer.stop();\n\t\t\t// A failing hook must not keep the bot running.\n\t\t\t// Behind any hook still running (an async `build:done`), and logged rather than thrown if it fails.\n\t\t\tawait service.runHook('dev:close', config);\n\t\t\tawait service.stop();\n\t\t\tlogFile?.close();\n\t\t\tprocess.exit(code);\n\t\t})();\n\t\treturn exiting;\n\t};\n\n\t// Like Turborepo: the first signal shuts down gracefully, a second one gives up waiting and kills everything.\n\tlet signalled = false;\n\tconst onSignal = (code: ExitCode) => () => {\n\t\tif (signalled) {\n\t\t\tprocess.stderr.write('\\nForcing shutdown.\\n');\n\t\t\tservice.kill();\n\t\t\tprocess.exit(code);\n\t\t}\n\n\t\tsignalled = true;\n\t\tvoid shutdown(code);\n\t\tprocess.stderr.write('\\nShutting down gracefully, press Ctrl+C again to force quit.\\n');\n\t};\n\n\tprocess.on('SIGINT', onSignal(ExitCode.Interrupted));\n\tprocess.on('SIGTERM', onSignal(ExitCode.Terminated));\n\tprocess.on('SIGHUP', onSignal(ExitCode.Terminated));\n\tif (process.platform !== 'win32') process.on('SIGUSR2', () => void service.restart('manual'));\n\n\tconst finished = renderer.start().then(() => shutdown(ExitCode.Ok));\n\ttry {\n\t\tawait prepareProject(config, hooks);\n\t\tawait service.start();\n\t\tawait hooks.callHook('dev:start', config);\n\t} catch (error) {\n\t\tservice.log('stars', 'error', error instanceof Error ? await renderCrashReport(error, config.root) : String(error));\n\t\tawait shutdown(ExitCode.Error);\n\t}\n\tawait finished;\n}\n\n/**\n * Resolves `dev.url`'s `localhost` to the address that is actually reachable (see {@link withResolvedLocalhost}),\n * the way Vite's dev server does when it starts. Only `stars dev` pays this DNS lookup; `stars info`/`stars build`\n * show or use the unresolved config as-is, since they never talk to the bot.\n */\nasync function resolveDevConfig(config: ResolvedStarsConfig): Promise<ResolvedStarsConfig> {\n\tif (!config.dev.url) return config;\n\n\tconst url = await withResolvedLocalhost(config.dev.url);\n\treturn url === config.dev.url ? config : { ...config, dev: { ...config.dev, url } };\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'dev',\n\t\tdescription: 'Build, run and restart the bot on changes'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\ttui: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Interactive terminal UI; use --no-tui (or STARS_TUI=plain) for plain line output',\n\t\t\tdefault: true\n\t\t},\n\t\ttheme: {\n\t\t\ttype: 'string',\n\t\t\tdescription: `Colour theme of the interactive UI: ${THEME_SETTINGS.join(', ')} (or STARS_THEME; press T in the UI to pick one)`\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runDev({ config: args.config, cwd: args.cwd, tui: args.tui ? undefined : false, theme: args.theme });\n\t}\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAMA,MAAM,sCAAsB,IAAI,IAAY,CAAC,QAAQ,KAAK,CAAC;;;;;;;AAQ3D,SAAgB,cAAc,QAAuC;CACpE,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,oBAAoB,IAAI,OAAO,MAAM,IAAI,GAAG,OAAO,CAAC;CAEhF,MAAM,WAAW,mBAAmB,OAAO,MAAM,yBAAyB;CAC1E,IAAI,aAAa,MAAM,OAAO,CAAC;CAE/B,MAAM,SAAS,gBAAgB,OAAO,IAAI,SAAS,cAAc,QAAQ,CAAC,CAAC,IAAI;CAC/E,OAAO,CAAC,YAAY,wBAAwB,mBAAmB,MAAM,GAAG;AACzE;;;;ACZA,MAAM,cAAc;AACpB,MAAM,aAAa;AACnB,MAAM,gBAAgB;AACtB,MAAM,aAAa;;;;;;;;;AA0BnB,IAAa,cAAb,cAAiC,aAAgC;CAM5B;CALpC,SAA8B;CAC9B,SAAyB;CACzB,UAAU;CACV,WAAW;CAEX,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;CAEpC;CAEA,IAAW,QAAwB;EAClC,OAAO,KAAK;CACb;CAEA,IAAW,SAAiB;EAC3B,OAAO,KAAK;CACb;;CAGA,IAAW,UAAmB;EAC7B,OAAO,KAAK,OAAO,IAAI,UAAU,WAAW,CAAC,wBAAwB,KAAK,MAAM,CAAC,CAAC;CACnF;CAEA,AAAO,QAAc;EACpB,IAAI,CAAC,KAAK,OAAO,IAAI,UAAU,SAAS;EACxC,KAAK,KAAK;CACX;;;;;CAMA,AAAO,QAAc;EACpB,IAAI,CAAC,KAAK,SAAS;EACnB,IAAI,KAAK,QAAQ;GAChB,KAAK,WAAW;GAChB,KAAK,OAAO,KAAK;GACjB;EACD;EAEA,KAAK,KAAK;CACX;CAEA,AAAO,QAAuB;EAC7B,MAAM,QAAQ,KAAK;EACnB,KAAK,SAAS;EACd,KAAK,WAAW;EAChB,IAAI,CAAC,SAAS,MAAM,aAAa,MAAM,OAAO,QAAQ,QAAQ;EAE9D,OAAO,IAAI,SAAS,YAAY;GAC/B,MAAM,KAAK,cAAc,QAAQ,CAAC;GAClC,MAAM,KAAK;EACZ,CAAC;CACF;CAEA,OAAa;EACZ,MAAM,EAAE,SAAS,MAAM,MAAM,UAAU,wBAAwB,KAAK,MAAM;EAC1E,MAAM,QAAQ,MAAM,OAAO,QAAQ,WAAW,SAAS,OAAO,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,GAAG;GAC7F,KAAK,KAAK,OAAO;GACjB,KAAK,QAAQ;GACb,OAAO;IAAC;IAAU;IAAQ;GAAM;GAChC,aAAa;EACd,CAAC;EACD,KAAK,SAAS;EACd,KAAK,UAAU,YAAY,CAAC;EAE5B,IAAI,SAAS;EACb,MAAM,cAAc,SAAiB;GACpC,IAAI,WAAW,KAAK,IAAI,GAAG;GAC3B,KAAK,YAAY,IAAI;EACtB;EAEA,MAAM,SAAS,mBAAmB,UAAU;EAC5C,MAAM,SAAS,mBAAmB,UAAU;EAC5C,MAAM,QAAQ,GAAG,QAAQ,OAAO,IAAI;EACpC,MAAM,QAAQ,GAAG,QAAQ,OAAO,IAAI;EAEpC,MAAM,KAAK,SAAS,SAAS;GAC5B,OAAO,MAAM;GACb,OAAO,MAAM;GACb,KAAK,SAAS;GAEd,IAAI,CAAC,SAAS,KAAK,WAAW,YAE7B,KAAK,UAAU,SAAS,KAAK,WAAW,IAAI,OAAO,UAAU,MAAM;GAGpE,IAAI,KAAK,UAAU;IAClB,KAAK,WAAW;IAChB,KAAK,KAAK;GACX;EACD,CAAC;EACD,MAAM,KAAK,UAAU,UAAiC;GACrD,KAAK,SAAS;GACd,KAAK,KAAK,OAAO,SAAS,MAAM,SAAS,WAAW,GAAG,QAAQ,qBAAqB,MAAM,OAAO;GACjG,KAAK,UAAU,UAAU,KAAK,OAAO;EACtC,CAAC;CACF;CAEA,YAAY,MAAoB;EAC/B,MAAM,OAAO,KAAK,KAAK;EACvB,IAAI,KAAK,WAAW,GAAG;EAEvB,IAAI,YAAY,KAAK,IAAI,GAAG;GAC3B,KAAK,UAAU,YAAY,CAAC;GAC5B;EACD;EAEA,IAAI,WAAW,KAAK,IAAI,GAAG;GAC1B,KAAK,KAAK,OAAO,SAAS,IAAI;GAC9B;EACD;EAEA,MAAM,OAAO,WAAW,KAAK,IAAI,KAAK,cAAc,KAAK,IAAI;EAC7D,IAAI,MAAM;GACT,MAAM,SAAS,OAAO,KAAK,EAAE;GAC7B,KAAK,UAAU,WAAW,IAAI,OAAO,UAAU,MAAM;GACrD,KAAK,KAAK,OAAO,WAAW,IAAI,YAAY,SAAS,WAAW,IAAI,mBAAmB,GAAG,OAAO,aAAa,WAAW,IAAI,KAAK,KAAK;GACvI;EACD;EAEA,KAAK,KAAK,OAAO,QAAQ,IAAI;CAC9B;CAEA,UAAU,OAAuB,QAAsB;EACtD,KAAK,SAAS;EACd,KAAK,UAAU;EACf,KAAK,KAAK,SAAS,OAAO,MAAM;CACjC;AACD;;;;;;AAOA,SAAgB,wBAAwB,QAA+C;CACtF,MAAM,EAAE,SAAS,aAAa,OAAO,IAAI;CACzC,MAAM,UAAU;CAEhB,QAAQ,SAAR;EACC,KAAK,SAAS;GAEb,MAAM,QAAQ,cAAc,OAAO,MAAM,SAAS,OAAO;GACzD,IAAI,CAAC,OAAO,MAAM,QAAQ,QAAQ,SAAS,qCAAqC;GAEhF,OAAO;IAAE,SAAS;IAAO,MAAM;KAAC;KAAO,GAAG;KAAY;KAAM;IAAO;IAAG,MAAM;IAAM,OAAO;GAAK;EAC/F;EAEA,KAAK,OAAO;GAEX,MAAM,MAAM,cAAc,OAAO,MAAM,yBAAyB,KAAK;GACrE,IAAI,KAAK,OAAO;IAAE,SAAS;IAAK,MAAM;KAAC;KAAY;KAAM;IAAO;IAAG,MAAM;IAAM,OAAO;GAAM;GAE5F,MAAM,SAAS,cAAc,OAAO,MAAM,WAAW,SAAS;GAC9D,IAAI,QAAQ,OAAO;IAAE,SAAS;IAAQ,MAAM,CAAC,MAAM,OAAO;IAAG,MAAM;IAAM,OAAO;GAAM;GAEtF,MAAM,QAAQ,QAAQ,OAAO,oEAAoE;EAClG;EAEA,SAAS;GACR,MAAM,MAAM,iBAAiB,OAAO,IAAI;GACxC,IAAI,CAAC,KAAK,MAAM,QAAQ,QAAQ,cAAc,0CAA0C;GAExF,OAAO;IAAE,SAAS;IAAK,MAAM;KAAC,GAAG;KAAY;KAAM;IAAO;IAAG,MAAM;IAAM,OAAO;GAAK;EACtF;CACD;AACD;AAEA,MAAM,aAAa;CAAC;CAAY;CAAW;CAAyB;CAAY;AAAO;AAEvF,SAAS,QAAQ,QAA6B,MAAc,SAA6B;CACxF,OAAO,eAAe,mBAAmB;EACxC;EACA,MAAM,OAAO;EACb,MAAM,GAAG,QAAQ;CAClB,CAAC;AACF;;;;;;;;ACnKA,IAAa,aAAb,cAAgC,aAA+B;CAyB7C;CAxBjB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAgB;CAChB,AAAS;;CAET,aAA4B,QAAQ,QAAQ;CAE5C,SAAqB;CACrB,UAAuB;CACvB,YAAY;CACZ,qBAA2C;CAC3C,aAAkC;CAClC,YAAgC;CAChC,gBAAuC;CACvC,eAAsC;CACtC,iBAAuC;CACvC,WAAW;CACX,SAAwB,QAAQ,QAAQ;CACxC,YAAY;EAAE,UAAU;EAAG,SAAS;EAAsB,WAAW,KAAK,IAAI;EAAG,SAAS;CAAsB;CAEhH,AAAO,YACN,AAAgB,QAChB,SACC;EACD,MAAM;EAHU;EAIhB,KAAK,OAAO,QAAQ,QAAQ,IAAI,UAAU;EAC1C,KAAK,UAAU,QAAQ;EACvB,KAAK,aAAa,QAAQ,cAAc,iBAAiB,MAAM;EAC/D,KAAK,cAAc,QAAQ,eAAe,IAAI,YAAY,MAAM;EAChE,KAAK,SAAS,QAAQ,UAAU,IAAI,OAAO,MAAM;EACjD,KAAK,UAAU,IAAI,QAAQ,MAAM;EACjC,KAAK,SAAS,QAAQ,SAAS;EAE/B,KAAK,QAAQ,GAAG,eAAe;GAC9B,KAAK,YAAY;IAAE,UAAU;IAAG,SAAS;IAAmB,WAAW,KAAK,IAAI;IAAG,SAAS;GAAK;GACjG,KAAK,UAAU,UAAU;GACzB,AAAK,KAAK,WAAW,gBAAgB,KAAK,MAAM;EACjD,CAAC;EACD,KAAK,QAAQ,GAAG,aAAa,UAAU,YAAY;GAClD,KAAK,YAAY;IAAE,GAAG,KAAK;IAAW,UAAU,KAAK,IAAI,KAAK,UAAU,UAAU,KAAK,IAAI,KAAM,QAAQ,CAAC;IAAG;GAAQ;GACrH,KAAK,YAAY;EAClB,CAAC;EACD,KAAK,QAAQ,GAAG,YAAY,YAAY,KAAK,gBAAgB,OAAO,CAAC;EACrE,KAAK,QAAQ,GAAG,YAAY,YAAY,KAAK,gBAAgB,OAAO,CAAC;EACrE,KAAK,QAAQ,GAAG,QAAQ,OAAO,SAAS,KAAK,IAAI,SAAS,OAAO,IAAI,CAAC;EAEtE,KAAK,WAAW,GAAG,eAAe;GACjC,IAAI,KAAK,WAAW,UAAU,WAAW;IACxC,KAAK,gBAAgB;IACrB,AAAK,KAAK,aAAa;GACxB;GACA,KAAK,YAAY;EAClB,CAAC;EACD,KAAK,WAAW,GAAG,WAAW,SAAS,KAAK,IAAI,OAAO,gBAAgB,MAAM,MAAM,GAAG,IAAI,CAAC;EAC3F,KAAK,WAAW,GAAG,WAAW,SAAS,KAAK,IAAI,OAAO,gBAAgB,MAAM,OAAO,GAAG,IAAI,CAAC;EAC5F,KAAK,WAAW,GAAG,UAAU,UAAU,KAAK,IAAI,SAAS,SAAS,4BAA4B,MAAM,SAAS,CAAC;EAC9G,KAAK,WAAW,GAAG,SAAS,SAAS,KAAK,QAAQ,IAAI,CAAC;EAEvD,KAAK,YAAY,GAAG,QAAQ,OAAO,SAAS,KAAK,IAAI,OAAO,OAAO,IAAI,CAAC;EACxE,KAAK,YAAY,GAAG,eAAe,KAAK,YAAY,CAAC;EACrD,KAAK,OAAO,GAAG,QAAQ,OAAO,SAAS,KAAK,IAAI,UAAU,OAAO,IAAI,CAAC;EACtE,KAAK,OAAO,GAAG,eAAe,KAAK,YAAY,CAAC;EAChD,KAAK,QAAQ,GAAG,QAAQ,OAAO,SAAS,KAAK,IAAI,SAAS,OAAO,IAAI,CAAC;EACtE,KAAK,QAAQ,GAAG,gBAAgB;GAC/B,IAAI,KAAK,WAAW,MAAM,KAAK,iBAAiB,OAAO;EACxD,CAAC;EAED,IAAI,OAAO,IAAI,OAAO,OAAO,IAAI,QAAQ;GACxC,MAAM,WAAW,QAAQ,kBAAkB;GAC3C,KAAK,eAAe,kBAAkB,KAAK,KAAK,aAAa,GAAG,QAAQ;GACxE,KAAK,aAAa,MAAM;EACzB;CACD;CAEA,IAAW,SAAoB;EAC9B,OAAO;GACN,UAAU,KAAK;GACf,SAAS,KAAK,WAAW;GACzB,OAAO,KAAK;GACZ,QAAQ,KAAK;GACb,KAAK,KAAK,WAAW;GACrB,WAAW,KAAK,WAAW;GAC3B,UAAU,KAAK;GACf,mBAAmB,KAAK;GACxB,WAAW,KAAK;GAChB,UAAU,KAAK;GACf,KAAK,KAAK,OAAO,IAAI;GACrB,WAAW,KAAK,YAAY;GAC5B,YAAY,KAAK,YAAY;GAC7B,QAAQ,KAAK,OAAO;GACpB,WAAW,KAAK,OAAO;EACxB;CACD;CAEA,AAAO,IAAI,QAAmB,OAAiB,MAAoB;EAClE,KAAK,KAAK,KAAK;GAAE;GAAQ;GAAO;EAAK,CAAC;CACvC;;;;CAKA,MAAa,QAAuB;EACnC,KAAK,WAAW;EAChB,MAAM,QAAQ,YAAY,KAAK,OAAO,MAAM,KAAK,OAAO,KAAK;EAC7D,KAAK,IAAI,SAAS,QAAQ,KAAK,OAAO,MAAM,SAAS,SAAS,YAAY,UAAU,YAAY,MAAM,QAAQ,KAAK,OAAO,MAAM,MAAM;EACtI,IAAI,KAAK,OAAO,IAAI,UAAU,SAAS,KAAK,YAAY,MAAM;EAC9D,MAAM,KAAK,QAAQ,MAAM;EAEzB,AAAK,KAAK,OAAO,MAAM;EACvB,MAAM,KAAK,QAAQ,MAAM;CAC1B;;;;CAKA,AAAO,QAAQ,SAAwB,UAAyB;EAC/D,KAAK,mBAAmB;EACxB,OAAO,KAAK,SAAS,YAAY;GAChC,IAAI,KAAK,UAAU;GACnB,MAAM,KAAK,WAAW,eAAe,QAAQ,KAAK,MAAM;GACxD,IAAI,KAAK,UAAU;GACnB,IAAI,WAAW,YAAY,WAAW,SACrC,KAAK,YAAY;IAAE,UAAU;IAAG,SAAS;IAAsB,WAAW,KAAK,IAAI;IAAG,SAAS;GAAK;GAErG,KAAK,qBAAqB;GAC1B,IAAI,KAAK,WAAW,SAAS;IAC5B,KAAK;IACL,KAAK,IAAI,SAAS,QAAQ,eAAe,eAAe,MAAM,EAAE,EAAE;IAClE,MAAM,KAAK,WAAW,KAAK;GAC5B,OACC,KAAK,IAAI,SAAS,QAAQ,aAAa,eAAe,MAAM,EAAE,EAAE;GAGjE,IAAI,KAAK,UAAU;GACnB,KAAK,YAAY;IAAE,GAAG,KAAK;IAAW,UAAU;IAAM,SAAS;GAAmB;GAClF,KAAK,UAAU;GACf,KAAK,WAAW,MAAM;GACtB,KAAK,YAAY;EAClB,CAAC;CACF;;CAGA,AAAO,eAA8B;EACpC,OAAO,KAAK,OAAO,OAAO;CAC3B;;;;CAKA,MAAa,OAAsB;EAClC,KAAK,WAAW;EAChB,KAAK,mBAAmB;EACxB,IAAI,KAAK,cAAc,cAAc,KAAK,YAAY;EACtD,KAAK,eAAe;EACpB,MAAM,KAAK,SAAS,YAAY;GAC/B,MAAM,QAAQ,WAAW;IACxB,KAAK,QAAQ,MAAM;IACnB,KAAK,WAAW,KAAK;IACrB,KAAK,YAAY,MAAM;IACvB,KAAK,OAAO,MAAM;IAClB,KAAK,QAAQ,MAAM;GACpB,CAAC;EACF,CAAC;CACF;;;;CAKA,AAAO,OAAa;EACnB,KAAK,WAAW;EAChB,KAAK,mBAAmB;EACxB,KAAK,WAAW,KAAK;EACrB,AAAK,KAAK,YAAY,MAAM;EAC5B,AAAK,KAAK,OAAO,MAAM;CACxB;CAEA,AAAO,YAAkB;EACxB,KAAK,KAAK,MAAM;CACjB;CAEA,gBAAgB,SAA6B;EAC5C,IAAI;GACH,KAAK,QAAQ,KAAK;EACnB,SAAS,OAAO;GACf,KAAK,gBAAgB;IACpB,GAAG;IACH,IAAI;IACJ,SAAS,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAC1F,CAAC;GACD;EACD;EACA,KAAK,aAAa;EAClB,KAAK,YAAY;GAAE,GAAG,KAAK;GAAW,UAAU;GAAM,SAAS;EAAmB;EAClF,KAAK,UAAU,IAAI;EAEnB,AAAK,KAAK,WAAW,cAAc,SAAS,KAAK,MAAM;EACvD,IAAI,KAAK,UAAU;EAEnB,KAAK,YAAY,MAAM;EACvB,KAAK,IAAI,SAAS,WAAW,KAAK,QAAQ,SAAS,SAAS,oBAAoB,sBAAsB,QAAQ,WAAW,GAAG;EAC5H,KAAK,iBAAiB,KAAK,WAAW,UAAU,SAAS,YAAY,OAAO;CAC7E;CAEA,gBAAgB,SAA6B;EAC5C,KAAK,aAAa;EAClB,AAAK,KAAK,WAAW,cAAc,SAAS,KAAK,MAAM;EACvD,KAAK,UAAU,QAAQ;EACvB,KAAK,mBAAmB;EACxB,KAAK,IAAI,SAAS,SAAS,eAAe,QAAQ,UAAU,KAAK,QAAQ,YAAY,GAAG,sBAAsB;CAC/G;CAEA,QAAQ,MAAyB;EAChC,KAAK,YAAY;EACjB,KAAK,UAAU;EACf,IAAI,CAAC,KAAK,WAAW;GACpB,MAAM,MAAM,KAAK,SAAS,UAAU,KAAK,WAAW,QAAQ,KAAK;GACjE,KAAK,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,SAAS,uBAAuB,IAAI,2CAA2C;EAC7H;EACA,KAAK,YAAY;CAClB;CAEA,iBAAiB,QAA6B;EAC7C,KAAK,iBAAiB;EACtB,KAAK,mBAAmB;EACxB,KAAK,gBAAgB,iBAAiB;GACrC,KAAK,gBAAgB;GACrB,MAAM,UAAU,KAAK,kBAAkB;GACvC,KAAK,iBAAiB;GACtB,AAAK,KAAK,QAAQ,OAAO;EAC1B,GAAG,KAAK,OAAO,IAAI,QAAQ;CAC5B;CAEA,qBAA2B;EAC1B,IAAI,KAAK,eAAe,aAAa,KAAK,aAAa;EACvD,KAAK,gBAAgB;CACtB;CAEA,SAAS,MAA0C;EAClD,KAAK,SAAS,KAAK,OAAO,KAAK,MAAM,IAAI;EACzC,OAAO,KAAK;CACb;CAEA,UAAU,OAAyB;EAClC,IAAI,KAAK,WAAW,OAAO;EAC3B,KAAK,SAAS;EACd,KAAK,YAAY;CAClB;CAEA,MAAM,eAA8B;EACnC,IAAI,CAAC,KAAK,WAAW,WAAW,CAAC,KAAK,OAAO,IAAI,OAAO,CAAC,KAAK,OAAO,IAAI,QAAQ;EACjF,MAAM,MAAM,KAAK,WAAW;EAE5B,IAAI;EACJ,IAAI;GAEH,QAAO,MADgB,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,QAAQ,KAAK,OAAO,IAAI,GAAG,GAAG,EAAE,QAAQ,YAAY,QAAQ,GAAI,EAAE,CAAC,EACzG,CAAC,SAAS,MAAM,OAAO;EACvC,QAAQ;GACP,OAAO;EACR;EAEA,IAAI,KAAK,YAAY,QAAQ,KAAK,WAAW,KAAK;EAClD,IAAI,SAAS,KAAK,SAAS;GAC1B,KAAK,UAAU;GACf,IAAI,SAAS,MAAM,KAAK,gBAAgB;GACxC,KAAK,YAAY;EAClB;CACD;CAEA,kBAAwB;EACvB,IAAI,KAAK,OAAO,IAAI,UAAU,KAAK,YAAY,MAAM;EACrD,IAAI,KAAK,WAAW,MAAM;EAC1B,KAAK,YAAY;GAChB,GAAG,KAAK;GACR,UAAU;GACV,SAAS;GACT,SAAS,KAAK,UAAU,WAAW,KAAK,IAAI,IAAI,KAAK,UAAU;EAChE;CACD;;;;;CAMA,AAAO,QAAuC,MAAY,GAAG,MAAmD;EAC/G,OAAO,KAAK,WAAW,MAAM,GAAG,IAAI;CACrC;;CAGA,WAA0C,MAAY,GAAG,MAAmD;EAC3G,KAAK,aAAa,KAAK,WAAW,WAAW,KAAK,UAAU,MAAM,GAAG,IAAI,CAAC;EAC1E,OAAO,KAAK;CACb;;;;;;CAOA,WAA0C,MAAY,GAAG,MAAmD;EAC3G,MAAM,UAAU,KAAK,UAAU,MAAM,GAAG,IAAI;EAC5C,KAAK,aAAa,QAAQ,IAAI,CAAC,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,WAAW,MAAS;EAC9E,OAAO;CACR;;;;;CAMA,MAAM,UAAyC,MAAY,GAAG,MAAmD;EAChH,IAAI,KAAK,WAAW,MAAM;EAC1B,IAAI;GACH,MAAM,KAAK,OAAO,SAAS,MAAM,GAAG,IAAI;EACzC,SAAS,OAAO;GACf,KAAK,IAAI,SAAS,SAAS,QAAQ,KAAK,WAAW,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;EAC5G;CACD;CAEA,cAAoB;EACnB,KAAK,KAAK,UAAU,KAAK,MAAM;CAChC;AACD;AAEA,SAAgB,iBAAiB,QAAgD;CAChF,OAAO,IAAI,kBAAkB;EAC5B,SAAS,QAAQ;EACjB,MAAM;GAAC,GAAG,cAAc,MAAM;GAAG,GAAG,OAAO,IAAI;GAAU,OAAO,MAAM;GAAQ,GAAG,OAAO,IAAI;EAAI;EAChG,KAAK,OAAO;EACZ,KAAK;GACJ,GAAG,QAAQ;GACX,GAAG,OAAO,IAAI;GACd,WAAW;GACX,UAAU;GACV,aAAa,QAAQ,IAAI,aAAa,SAAY,SAAa,QAAQ,IAAI,gBAAgB,QAAQ,OAAO,QAAQ,MAAM;EACzH;EACA,aAAa,OAAO,IAAI;CACzB,CAAC;AACF;AAEA,SAAgB,eAAe,QAA+B;CAC7D,QAAQ,QAAR;EACC,KAAK,WACJ,OAAO;EACR,KAAK,SACJ,OAAO;EACR,KAAK,UACJ,OAAO;EACR,KAAK,SACJ,OAAO;CACT;AACD;;;;;;;;;;AC9YA,eAAsB,mBAAoC;CACzD,IAAI;EACH,MAAM,CAAC,SAAS,YAAY,MAAM,QAAQ,IAAI,CAAC,OAAO,WAAW,GAAG,OAAO,aAAa,EAAE,UAAU,KAAK,CAAC,CAAC,CAAC;EAC5G,OAAO,QAAQ,WAAW,SAAS,UAAU,QAAQ,YAAY,SAAS,UAAU,cAAc,SAAS;CAC5G,QAAQ;EACP,OAAO;CACR;AACD;;;;;AAMA,eAAsB,sBAAsB,KAA8B;CACzE,MAAM,SAAS,IAAI,IAAI,GAAG;CAC1B,IAAI,OAAO,aAAa,aAAa,OAAO;CAE5C,MAAM,OAAO,MAAM,iBAAiB;CACpC,IAAI,SAAS,aAAa,OAAO;CAEjC,OAAO,WAAW,KAAK,SAAS,GAAG,IAAI,IAAI,KAAK,KAAK;CACrD,OAAO,OAAO;AACf;;;;;;;;;ACrBA,IAAa,gBAAb,MAA2B;CAIT;CACC;CAJlB,UAA8B;CAE9B,AAAO,YACN,AAAgB,MAChB,AAAiB,MAChB;EAFe;EACC;CACf;CAEH,AAAO,OAAa;EACnB,IAAI,KAAK,SAAS;EAElB,UAAU,QAAQ,KAAK,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;EACjD,KAAK,UAAU,kBAAkB,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;EAE1D,KAAK,QAAQ,GAAG,eAAe,KAAK,MAAM,CAAC;EAE3C,KAAK,MAAM,SAAS,KAAK,KAAK,QAAQ,GAAG,KAAK,OAAO,KAAK;EAC1D,KAAK,KAAK,GAAG,SAAS,KAAK,MAAM;CAClC;CAEA,AAAO,QAAc;EACpB,MAAM,SAAS,KAAK;EACpB,KAAK,UAAU;EACf,IAAI,CAAC,QAAQ;EAEb,KAAK,KAAK,IAAI,SAAS,KAAK,MAAM;EAClC,OAAO,IAAI;CACZ;CAEA,UAAU,UAA0B;EACnC,KAAK,SAAS,MAAM,GAAG,OAAO,KAAK,EAAE,GAAG;CACzC;AACD;AAEA,SAAS,OAAO,OAAyB;CACxC,OAAO,GAAG,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,YAAY,EAAE,GAAG,MAAM,MAAM,OAAO,CAAC,EAAE,GAAG,MAAM,OAAO,OAAO,CAAC,EAAE,GAAG,MAAM;AAC1G;;;;ACzBA,eAAsB,OAAO,SAAwC;CACpE,IAAI,QAAQ,UAAU,UAAa,CAAC,eAAe,QAAQ,KAAK,GAC/D,MAAM,eAAe,cAAc;EAAE,OAAO,QAAQ;EAAO,QAAQ,eAAe,KAAK,IAAI;CAAE,CAAC;CAI/F,QAAQ,IAAI,WAAW;CACvB,MAAM,UAAU,MAAM,YAAY;EAAE,KAAK,WAAW,OAAO;EAAG,YAAY,QAAQ;EAAQ,KAAK;GAAE,GAAG,QAAQ;GAAK,UAAU;EAAc;CAAE,CAAC;CAC5I,MAAM,QAAQ,QAAQ;CAEtB,MAAM,SAAS,MAAM,iBAAiB,eAAe,MAAM,gBAAgB,QAAQ,QAAQ,KAAK,CAAC,CAAC;CAClG,MAAM,OAAO,kBAAkB,EAAE,KAAK,QAAQ,IAAI,CAAC;CACnD,MAAM,QAAQ,eAAe;CAC7B,MAAM,QAAQ,oBAAoB;EAAE,MAAM,QAAQ;EAAO,OAAO,eAAe;CAAE,CAAC;CAElF,MAAM,UAAU,MAAM,cAAc,QAAQ,KAAK;CACjD,MAAM,MAAM,SAAS,mBAAmB,SAAS,MAAM;CACvD,MAAM,UAAU,IAAI,WAAW,QAAQ;EAAE;EAAS;CAAM,CAAC;CACzD,MAAM,eAAe,SAAS,SAAS,QAAQ,IAAI,SAAS,QAAQ,IAAI,CAAC;CACzE,MAAM,UAAU,OAAO,IAAI,UAAU,IAAI,cAAc,OAAO,IAAI,SAAS,QAAQ,IAAI,IAAI;CAC3F,SAAS,KAAK;CACd,MAAM,WACL,SAAS,SACL,MAAM,OAAO,qBAAoB,CAAE,kBAAkB,SAAS;EAC/D;EACA;EACA,eAAe,qBAAqB;EACpC,cAAc,YAAY;GACzB,IAAI,CAAC,UAAU,OAAO,GAAG,QAAQ,IAAI,SAAS,QAAQ,sCAAsC;EAC7F;CACD,CAAC,KACC,MAAM,OAAO,uBAAsB,CAAE,oBAAoB,SAAS,EAAE,MAAM,CAAC;CAEhF,IAAI,UAAiC;CACrC,MAAM,YAAY,SAAmC;EACpD,aAAa,YAAY;GACxB,SAAS,KAAK;GAGd,MAAM,QAAQ,QAAQ,aAAa,MAAM;GACzC,MAAM,QAAQ,KAAK;GACnB,SAAS,MAAM;GACf,QAAQ,KAAK,IAAI;EAClB,EAAC,CAAE;EACH,OAAO;CACR;CAGA,IAAI,YAAY;CAChB,MAAM,YAAY,eAAyB;EAC1C,IAAI,WAAW;GACd,QAAQ,OAAO,MAAM,uBAAuB;GAC5C,QAAQ,KAAK;GACb,QAAQ,KAAK,IAAI;EAClB;EAEA,YAAY;EACZ,AAAK,SAAS,IAAI;EAClB,QAAQ,OAAO,MAAM,iEAAiE;CACvF;CAEA,QAAQ,GAAG,UAAU,SAAS,SAAS,WAAW,CAAC;CACnD,QAAQ,GAAG,WAAW,SAAS,SAAS,UAAU,CAAC;CACnD,QAAQ,GAAG,UAAU,SAAS,SAAS,UAAU,CAAC;CAClD,IAAI,QAAQ,aAAa,SAAS,QAAQ,GAAG,iBAAiB,KAAK,QAAQ,QAAQ,QAAQ,CAAC;CAE5F,MAAM,WAAW,SAAS,MAAM,CAAC,CAAC,WAAW,SAAS,SAAS,EAAE,CAAC;CAClE,IAAI;EACH,MAAM,eAAe,QAAQ,KAAK;EAClC,MAAM,QAAQ,MAAM;EACpB,MAAM,MAAM,SAAS,aAAa,MAAM;CACzC,SAAS,OAAO;EACf,QAAQ,IAAI,SAAS,SAAS,iBAAiB,QAAQ,MAAM,kBAAkB,OAAO,OAAO,IAAI,IAAI,OAAO,KAAK,CAAC;EAClH,MAAM,SAAS,SAAS,KAAK;CAC9B;CACA,MAAM;AACP;;;;;;AAOA,eAAe,iBAAiB,QAA2D;CAC1F,IAAI,CAAC,OAAO,IAAI,KAAK,OAAO;CAE5B,MAAM,MAAM,MAAM,sBAAsB,OAAO,IAAI,GAAG;CACtD,OAAO,QAAQ,OAAO,IAAI,MAAM,SAAS;EAAE,GAAG;EAAQ,KAAK;GAAE,GAAG,OAAO;GAAK;EAAI;CAAE;AACnF;AAEA,kBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,KAAK;GACJ,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,OAAO;GACN,MAAM;GACN,aAAa,uCAAuC,eAAe,KAAK,IAAI,EAAE;EAC/E;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,OAAO;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,KAAK,KAAK,MAAM,SAAY;GAAO,OAAO,KAAK;EAAM,CAAC;CAC1G;AACD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics-CZBVxlpj.js","names":[],"sources":["../src/utils/diagnostics.ts"],"sourcesContent":["import { defineDiagnostics } from 'nostics';\n\n/**\n * Structured, stable diagnostic codes for everything `@wolfstar/cli` itself rejects (as opposed to `stars.config.*`\n * validation, which is `@wolfstar/http-framework`'s own {@link import('@wolfstar/schema').configDiagnostics}).\n *\n * `reporters` stays empty: `runMain` (`src/run.ts`) is the single place that renders a caught `Diagnostic` to the\n * terminal (`formatError`) and picks its exit code (`exitCodeOf`), so nothing here should print on its own — a\n * command that calls e.g. `runBuild` directly (as the test suite does) gets a plain thrown value instead of stray\n * console output.\n *\n * `why` and `fix` are always given the same, fully-typed params object, even when one of them ignores part of it or\n * neither takes any: a bare `() => value` next to a typed sibling loses nostics' param-type inference (a zero-arg\n * function widens to `unknown` params, erasing the sibling's fields from the merged type).\n */\nexport const cliDiagnostics = defineDiagnostics({\n\tdocsBase: (code) => `https://stars-components.js.org/docs/cli/errors#${code.toLowerCase()}`,\n\treporters: [],\n\tcodes: {\n\t\tPREPARE_OUTDATED: {\n\t\t\twhy: (_p: {}) => 'The generated project files are out of date, run `stars prepare` to update it.'\n\t\t},\n\t\tDISCORD_TOKEN_MISSING: {\n\t\t\twhy: (_p: {}) => 'DISCORD_TOKEN is not set',\n\t\t\tfix: (_p: {}) => 'Set DISCORD_TOKEN in the environment or in the project .env file.'\n\t\t},\n\t\tDISCORD_APPLICATION_ID_MISSING: {\n\t\t\twhy: (_p: {}) => 'The Discord application id is not set',\n\t\t\tfix: (_p: {}) => 'Set DISCORD_APPLICATION_ID (or APPLICATION_ID) in the environment or in the project .env file.'\n\t\t},\n\t\tDISCORD_REQUEST_FAILED: {\n\t\t\twhy: (p: { status: number; detail: string }) => `Discord answered ${p.status}${p.detail ? `: ${p.detail}` : ''}`,\n\t\t\tfix: (p: { status: number; detail: string }) =>\n\t\t\t\tp.status === 401 ? 'Check DISCORD_TOKEN.' : 'Check the application id and the bot permissions.'\n\t\t},\n\t\tBUILD_FAILED: {\n\t\t\twhy: (p: { message: string }) => `Build failed${p.message ? `: ${p.message}` : ''}`\n\t\t},\n\t\tCOMMAND_NOT_FOUND: {\n\t\t\twhy: (p: { names: string }) => `No deployed command is named ${p.names}`,\n\t\t\tfix: (_p: { names: string }) => 'Run `stars commands list` to see what is deployed.'\n\t\t},\n\t\tABORTED: {\n\t\t\twhy: (_p: {}) => 'Aborted'\n\t\t},\n\t\tCONFIRMATION_REQUIRED: {\n\t\t\twhy: (_p: {}) => 'Refusing to delete commands without a confirmation',\n\t\t\tfix: (_p: {}) => 'Pass --yes to delete them, or --name to pick one, from a script.'\n\t\t},\n\t\tINVALID_THEME: {\n\t\t\twhy: (p: { theme: string; themes: string }) => `Unknown theme \\`${p.theme}\\`.`,\n\t\t\tfix: (p: { theme: string; themes: string }) => `Use one of: ${p.themes}.`\n\t\t},\n\t\tCODEGEN_OUTDATED: {\n\t\t\twhy: (_p: {}) => 'Generated files are out of date, run `stars codegen` to update them.'\n\t\t},\n\t\tDEPENDENCY_MISSING: {\n\t\t\twhy: (p: { name: string; root: string; hint: string }) => `\"${p.name}\" is not installed in ${p.root}`,\n\t\t\tfix: (p: { name: string; root: string; hint: string }) => p.hint\n\t\t},\n\t\tCODEGEN_FAILED: {\n\t\t\twhy: (p: { code: number | null; stderr: string }) => `i18next-type-generator exited with code ${p.code}${p.stderr ? `: ${p.stderr}` : ''}`\n\t\t}\n\t}\n});\n\nexport type CliDiagnosticCode = keyof typeof cliDiagnostics;\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAa,iBAAiB,kBAAkB;CAC/C,WAAW,SAAS,mDAAmD,KAAK,YAAY;CACxF,WAAW,CAAC;CACZ,OAAO;EACN,kBAAkB,EACjB,MAAM,OAAW,iFAClB;EACA,uBAAuB;GACtB,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,gCAAgC;GAC/B,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,wBAAwB;GACvB,MAAM,MAA0C,oBAAoB,EAAE,SAAS,EAAE,SAAS,KAAK,EAAE,WAAW;GAC5G,MAAM,MACL,EAAE,WAAW,MAAM,yBAAyB;EAC9C;EACA,cAAc,EACb,MAAM,MAA2B,eAAe,EAAE,UAAU,KAAK,EAAE,YAAY,KAChF;EACA,mBAAmB;GAClB,MAAM,MAAyB,gCAAgC,EAAE;GACjE,MAAM,OAA0B;EACjC;EACA,SAAS,EACR,MAAM,OAAW,UAClB;EACA,uBAAuB;GACtB,MAAM,OAAW;GACjB,MAAM,OAAW;EAClB;EACA,eAAe;GACd,MAAM,MAAyC,mBAAmB,EAAE,MAAM;GAC1E,MAAM,MAAyC,eAAe,EAAE,OAAO;EACxE;EACA,kBAAkB,EACjB,MAAM,OAAW,uEAClB;EACA,oBAAoB;GACnB,MAAM,MAAoD,IAAI,EAAE,KAAK,wBAAwB,EAAE;GAC/F,MAAM,MAAoD,EAAE;EAC7D;EACA,gBAAgB,EACf,MAAM,MAA+C,2CAA2C,EAAE,OAAO,EAAE,SAAS,KAAK,EAAE,WAAW,KACvI;CACD;AACD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors-Crt4hu0b.js","names":[],"sources":["../src/utils/errors.ts"],"sourcesContent":["import { configDiagnostics } from '@wolfstar/schema';\nimport { createColors } from 'colorette';\nimport { Diagnostic } from 'nostics';\nimport { ansiFormatter } from 'nostics/formatters/ansi';\nimport { shouldUseColor } from './output-mode.js';\n\nexport const ExitCode = {\n\tOk: 0,\n\tError: 1,\n\tInvalidConfig: 2,\n\tBuildFailed: 3,\n\tInterrupted: 130,\n\tTerminated: 143\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** Every `stars.config.*` diagnostic code maps to {@link ExitCode.InvalidConfig}; everything else defaults to `Error`. */\nconst CONFIG_DIAGNOSTIC_CODES = new Set<string>(Object.keys(configDiagnostics));\n\n/** CLI-local diagnostic codes whose exit code isn't the default {@link ExitCode.Error}. */\nconst CLI_EXIT_CODES: Partial<Record<string, ExitCode>> = {\n\tBUILD_FAILED: ExitCode.BuildFailed\n};\n\n/**\n * Formats an error for the terminal: a `Diagnostic` (from `stars.config.*` validation, via\n * `@wolfstar/schema`'s `configDiagnostics`, or from the CLI's own `cliDiagnostics`) renders through\n * nostics' own ANSI formatter — message, `fix`, `sources` and `docs` — everything else falls back to a crash report.\n */\nexport async function formatError(error: unknown): Promise<string> {\n\tif (error instanceof Diagnostic) {\n\t\tconst colors = createColors({ useColor: shouldUseColor() });\n\t\treturn ansiFormatter(colors)(error);\n\t}\n\n\t// citty's CLIError (unknown command, missing argument): the message is enough.\n\tif (error instanceof Error && error.name === 'CLIError') return error.message;\n\tif (error instanceof Error) return renderCrashReport(error);\n\treturn String(error);\n}\n\n/**\n * Renders an unexpected error (a bug, not something the CLI already explains through a `Diagnostic`) as a\n * sourcemapped, syntax-highlighted report — frames and a snippet of the original source instead of a stack trace\n * pointing into the bundled `dist/cli.js`.\n */\nexport async function renderCrashReport(error: unknown, cwd: string = process.cwd()): Promise<string> {\n\tconst { createReport, fsLoader, renderAnsi } = await import('my-bad');\n\tconst report = await createReport(error, { cwd, loaders: [fsLoader()] });\n\treturn renderAnsi(report, { cwd });\n}\n\nexport function exitCodeOf(error: unknown): ExitCode {\n\tif (error instanceof Diagnostic) {\n\t\tif (CONFIG_DIAGNOSTIC_CODES.has(error.code)) return ExitCode.InvalidConfig;\n\t\treturn CLI_EXIT_CODES[error.code] ?? ExitCode.Error;\n\t}\n\n\treturn ExitCode.Error;\n}\n"],"mappings":";;;;;;;AAMA,MAAa,WAAW;CACvB,IAAI;CACJ,OAAO;CACP,eAAe;CACf,aAAa;CACb,aAAa;CACb,YAAY;AACb;;AAKA,MAAM,0BAA0B,IAAI,IAAY,OAAO,KAAK,iBAAiB,CAAC;;AAG9E,MAAM,iBAAoD,EACzD,cAAc,SAAS,YACxB;;;;;;AAOA,eAAsB,YAAY,OAAiC;CAClE,IAAI,iBAAiB,YAAY;EAChC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,EAAE,CAAC;EAC1D,OAAO,cAAc,MAAM,CAAC,CAAC,KAAK;CACnC;CAGA,IAAI,iBAAiB,SAAS,MAAM,SAAS,YAAY,OAAO,MAAM;CACtE,IAAI,iBAAiB,OAAO,OAAO,kBAAkB,KAAK;CAC1D,OAAO,OAAO,KAAK;AACpB;;;;;;AAOA,eAAsB,kBAAkB,OAAgB,MAAc,QAAQ,IAAI,GAAoB;CACrG,MAAM,EAAE,cAAc,UAAU,eAAe,MAAM,OAAO;CAE5D,OAAO,WAAW,MADG,aAAa,OAAO;EAAE;EAAK,SAAS,CAAC,SAAS,CAAC;CAAE,CAAC,GAC7C,EAAE,IAAI,CAAC;AAClC;AAEA,SAAgB,WAAW,OAA0B;CACpD,IAAI,iBAAiB,YAAY;EAChC,IAAI,wBAAwB,IAAI,MAAM,IAAI,GAAG,OAAO,SAAS;EAC7D,OAAO,eAAe,MAAM,SAAS,SAAS;CAC/C;CAEA,OAAO,SAAS;AACjB"}
|