@wolfstar/cli 2.6.1 → 2.7.0-next-20261009120452

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +6 -2
  2. package/dist/{_shared-CyzTojMA.js → _shared-BLXTNq89.js} +3 -3
  3. package/dist/{_shared-CyzTojMA.js.map → _shared-BLXTNq89.js.map} +1 -1
  4. package/dist/{bridge-Cbm0jX9h.js → bridge-DQ3dZ9pm.js} +2 -2
  5. package/dist/{bridge-Cbm0jX9h.js.map → bridge-DQ3dZ9pm.js.map} +1 -1
  6. package/dist/{build-BbIEbOu3.js → build-DVF5vcSS.js} +5 -5
  7. package/dist/{build-BbIEbOu3.js.map → build-DVF5vcSS.js.map} +1 -1
  8. package/dist/cli.js +1 -1
  9. package/dist/{codegen-C2PY7RXA.js → codegen-DI263aSx.js} +5 -5
  10. package/dist/{codegen-C2PY7RXA.js.map → codegen-DI263aSx.js.map} +1 -1
  11. package/dist/commands-Bd6Dp5Y0.js +3 -0
  12. package/dist/{commands-C-i3qYOz.js → commands-CtucWY2d.js} +5 -5
  13. package/dist/{commands-C-i3qYOz.js.map → commands-CtucWY2d.js.map} +1 -1
  14. package/dist/commands-D7SFy2_3.js +16 -0
  15. package/dist/{commands-D9i-ZgpA.js.map → commands-D7SFy2_3.js.map} +1 -1
  16. package/dist/{completions-DA-NZAcY.js → completions-D_scEKH1.js} +3 -3
  17. package/dist/{completions-DA-NZAcY.js.map → completions-D_scEKH1.js.map} +1 -1
  18. package/dist/{dev-BLlgQwl6.js → dev-CnXgPQ8F.js} +10 -10
  19. package/dist/{dev-BLlgQwl6.js.map → dev-CnXgPQ8F.js.map} +1 -1
  20. package/dist/{diagnostics-Dn3CXa8J.js → diagnostics-BKc--u_3.js} +5 -1
  21. package/dist/diagnostics-BKc--u_3.js.map +1 -0
  22. package/dist/{doctor-CMGfbXS5.js → doctor-BYRkkc5l.js} +28 -10
  23. package/dist/doctor-BYRkkc5l.js.map +1 -0
  24. package/dist/{hooks-D_RVS0ba.js → hooks-CzV2YRoJ.js} +32 -6
  25. package/dist/hooks-CzV2YRoJ.js.map +1 -0
  26. package/dist/index.d.ts +4 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -2
  29. package/dist/{info-C_YDcVul.js → info-DLo6tZT5.js} +5 -4
  30. package/dist/info-DLo6tZT5.js.map +1 -0
  31. package/dist/{local-commands-CGBjc8KJ.js → local-commands-DKnabUnX.js} +4 -4
  32. package/dist/{local-commands-CGBjc8KJ.js.map → local-commands-DKnabUnX.js.map} +1 -1
  33. package/dist/{locales-BzyEMQnX.js → locales-CnVIXIip.js} +5 -5
  34. package/dist/{locales-BzyEMQnX.js.map → locales-CnVIXIip.js.map} +1 -1
  35. package/dist/{nitro-DufOgx8s.js → nitro-BWRIMUd8.js} +2 -2
  36. package/dist/{nitro-DufOgx8s.js.map → nitro-BWRIMUd8.js.map} +1 -1
  37. package/dist/{prepare-DKH0UIYA.js → prepare-DnNsv3TU.js} +4 -4
  38. package/dist/{prepare-DKH0UIYA.js.map → prepare-DnNsv3TU.js.map} +1 -1
  39. package/dist/{project-DBqQMFCk.js → project-EJyKro-M.js} +2 -2
  40. package/dist/{project-DBqQMFCk.js.map → project-EJyKro-M.js.map} +1 -1
  41. package/dist/{run-Bs6e9_6S.js → run-BVBqR6hV.js} +2 -2
  42. package/dist/{run-Bs6e9_6S.js.map → run-BVBqR6hV.js.map} +1 -1
  43. package/dist/{tsc-BArammxe.js → tsc-6su4cT6K.js} +3 -3
  44. package/dist/{tsc-BArammxe.js.map → tsc-6su4cT6K.js.map} +1 -1
  45. package/dist/tsc-DK53_ZWE.js +3 -0
  46. package/dist/{tsdown-2i5h88vT.js → tsdown-DP5VrWx4.js} +2 -2
  47. package/dist/{tsdown-2i5h88vT.js.map → tsdown-DP5VrWx4.js.map} +1 -1
  48. package/dist/{tui-BOkOx13K.js → tui-C8MjzsKS.js} +2 -2
  49. package/dist/{tui-BOkOx13K.js.map → tui-C8MjzsKS.js.map} +1 -1
  50. package/dist/{tunnel-BNV5cuJz.js → tunnel-DlFjqUE7.js} +193 -93
  51. package/dist/tunnel-DlFjqUE7.js.map +1 -0
  52. package/dist/{typecheck-p_2rj9lL.js → typecheck-B2aRagKp.js} +5 -5
  53. package/dist/{typecheck-p_2rj9lL.js.map → typecheck-B2aRagKp.js.map} +1 -1
  54. package/dist/{typechecker-C3UOI2LF.js → typechecker-zjnzC2L_.js} +4 -4
  55. package/dist/{typechecker-C3UOI2LF.js.map → typechecker-zjnzC2L_.js.map} +1 -1
  56. package/dist/{vite-C5CN3xUu.js → vite-9yEVMHY_.js} +2 -2
  57. package/dist/{vite-C5CN3xUu.js.map → vite-9yEVMHY_.js.map} +1 -1
  58. package/package.json +9 -5
  59. package/dist/commands-BfNA1-eZ.js +0 -3
  60. package/dist/commands-D9i-ZgpA.js +0 -16
  61. package/dist/diagnostics-Dn3CXa8J.js.map +0 -1
  62. package/dist/doctor-CMGfbXS5.js.map +0 -1
  63. package/dist/hooks-D_RVS0ba.js.map +0 -1
  64. package/dist/info-C_YDcVul.js.map +0 -1
  65. package/dist/tsc-9yHyx0L6.js +0 -3
  66. package/dist/tunnel-BNV5cuJz.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tui-BOkOx13K.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/mouse.ts","../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 { useEffect, 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\n/**\n * What a click on the sidebar lands on. Rows and columns are counted from 0 at the top-left corner of the sidebar;\n * `end` is exclusive.\n */\nexport type SidebarRegion =\n\t| { kind: 'header'; group: SidebarGroup; row: number }\n\t| { kind: 'item'; group: SidebarGroup; index: number; row: number; start: number; end: number }\n\t| { kind: 'key'; key: string; row: number };\n\n/** A region before its row is known: the rows are numbered once the sidebar knows which of them fit. */\ntype SidebarHit =\n\t| { kind: 'header'; group: SidebarGroup }\n\t| { kind: 'items'; group: SidebarGroup; items: readonly { index: number; start: number; end: number }[] }\n\t| { kind: 'key'; key: string };\n\ninterface SidebarRow {\n\tnode: ReactNode;\n\thit?: SidebarHit;\n}\n\n/** The region of the sidebar at a cell, if a click there does something. */\nexport function findSidebarRegion(regions: readonly SidebarRegion[], row: number, column: number): SidebarRegion | null {\n\treturn regions.find((region) => region.row === row && (region.kind !== 'item' || (column >= region.start && column < region.end))) ?? null;\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\t/** Told where the clickable entries are after every paint, for the mouse. */\n\tonRegions?: (regions: readonly SidebarRegion[]) => void;\n}\n\n/** The padding of the sidebar, then the indentation of the lines of a group. */\nconst PADDING = 1;\nconst INDENT = 2;\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, onRegions } =\n\t\tprops;\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 = (\n\t\tgroup: SidebarGroup,\n\t\tlabels: readonly string[],\n\t\tnodes: readonly ReactNode[],\n\t\trange: [number, number] = [0, Infinity]\n\t): SidebarRow[] =>\n\t\twrapLabels(labels, labelWidth)\n\t\t\t.slice(...range)\n\t\t\t.map((line, index) => {\n\t\t\t\t// Where each label of the line starts: the labels are separated by one space.\n\t\t\t\tlet column = PADDING + INDENT;\n\t\t\t\tconst items = line.map((label) => {\n\t\t\t\t\tconst start = column;\n\t\t\t\t\tcolumn += labels[label]!.length + 1;\n\t\t\t\t\treturn { index: label, start, end: column - 1 };\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\thit: { kind: 'items', group, items },\n\t\t\t\t\tnode: (\n\t\t\t\t\t\t<Text key={`${group}-${index}`} wrap=\"truncate-end\">\n\t\t\t\t\t\t\t{' '.repeat(INDENT)}\n\t\t\t\t\t\t\t{line.flatMap((label, position) => (position > 0 ? [' ', nodes[label]] : [nodes[label]]))}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)\n\t\t\t\t};\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: SidebarRow[] = 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: SidebarRow[] = [\n\t\t{ node: <Text key=\"gap-filters\"> </Text> },\n\t\t{\n\t\t\thit: { kind: 'header', group: 'channels' },\n\t\t\tnode: groupHeader('channels', !collapsed.channels && hiddenChannels > 0 ? ` · ${range[0] + 1}-${range[1]}/${channelLayout.length}` : '')\n\t\t},\n\t\t...(collapsed.channels ? [] : lines('channels', channels, channelNodes, range)),\n\t\t{ hit: { kind: 'header', group: 'levels' }, node: groupHeader('levels') },\n\t\t...levelLines\n\t];\n\n\tconst keys: SidebarRow[][] = KEYS.map((section, sectionIndex) => [\n\t\t{ node: <Text key={`gap-keys-${sectionIndex}`}> </Text> },\n\t\t...section.map(([key, label]) => ({\n\t\t\thit: { kind: 'key', key } satisfies SidebarHit,\n\t\t\tnode: (\n\t\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t\t<Text bold color={paint('url')}>\n\t\t\t\t\t\t{key}\n\t\t\t\t\t</Text>{' '}\n\t\t\t\t\t<Text dimColor>{label}</Text>\n\t\t\t\t</Text>\n\t\t\t)\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\tconst statusRows = head.map((node): SidebarRow => ({ node }));\n\tlet body = [...statusRows, ...filters, ...keys.flat()];\n\tif (body.length > budget) body = [...statusRows, ...filters, ...keys[1]!];\n\tif (body.length > budget) body = [...statusRows, ...filters];\n\tbody = body.slice(0, budget);\n\n\tconst regions = body.flatMap(({ hit }, row): SidebarRegion[] => {\n\t\tif (hit === undefined) return [];\n\t\tif (hit.kind === 'items') return hit.items.map((item) => ({ kind: 'item', group: hit.group, row, ...item }));\n\t\treturn [{ ...hit, row }];\n\t});\n\t// Compared by value: the regions only move when the layout does, and the dashboard repaints on every log entry.\n\tconst regionsKey = JSON.stringify(regions);\n\tuseEffect(() => onRegions?.(regions), [regionsKey, onRegions]);\n\n\treturn (\n\t\t<Box flexDirection=\"column\" width={width} height={height} paddingX={PADDING}>\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, type Key } from 'ink';\nimport { useCallback, useEffect, useMemo, useRef, 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 { MouseEvent, MouseInput } from '../../mouse.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 { findSidebarRegion, Sidebar, type SidebarFocus, type SidebarGroup, type SidebarRegion } 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\t/** The mouse of the terminal, when `dev.mouse` is on. */\n\tmouse?: Pick<MouseInput, 'subscribe'>;\n\t/** Runs a key of the app (`q`, `r`, `?`…), for a click on its hint in the sidebar. */\n\tonKey: (input: string) => void;\n}\n\n/** How many rows a notch of the wheel scrolls. */\nconst WHEEL_ROWS = 3;\n/** Two clicks on the same entry within this many milliseconds are a double click. */\nconst DOUBLE_CLICK_MS = 400;\nconst NO_KEY = {} as Key;\n/** The keys of the sidebar a click can press, by how the sidebar writes them: the others stand for several keys. */\nconst HINT_KEYS: Readonly<Record<string, readonly [input: string, key: Partial<Key>]>> = {\n\ttab: ['', { tab: true }],\n\tspace: [' ', {}],\n\ts: ['s', {}]\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, mouse, onKey } = 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\tconst regions = useRef<readonly SidebarRegion[]>([]);\n\tconst lastClick = useRef<{ group: SidebarGroup; index: number; at: number; filter: LogViewFilter } | null>(null);\n\tconst onRegions = useCallback((next: readonly SidebarRegion[]) => {\n\t\tregions.current = next;\n\t}, []);\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\tconst handleKey = (input: string, key: Key) => {\n\t\tif (key.ctrl || confirmQuit) return;\n\t\tif (searching) {\n\t\t\tif (key.escape) {\n\t\t\t\tsetSearching(false);\n\t\t\t\tchange({ ...filter, query: '' });\n\t\t\t} else if (key.return) setSearching(false);\n\t\t\telse if (key.backspace || key.delete) change({ ...filter, query: [...filter.query].slice(0, -1).join('') });\n\t\t\telse if (input && !key.upArrow && !key.downArrow && !key.leftArrow && !key.rightArrow && !key.tab) {\n\t\t\t\tchange({ ...filter, query: filter.query + input });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (key.escape) {\n\t\t\tif (filter.query) change({ ...filter, query: '' });\n\t\t\telse setPinned(null);\n\t\t\treturn setMarked(null);\n\t\t}\n\t\tif (input === '/') return setSearching(true);\n\t\tif (key.tab) return setFocus((current) => ({ group: current.group === 'channels' ? 'levels' : 'channels', index: 0 }));\n\t\tif (key.leftArrow || key.rightArrow) {\n\t\t\tif (items.length === 0) return;\n\t\t\tconst delta = key.leftArrow ? -1 : 1;\n\t\t\treturn setFocus((current) => ({ ...current, index: (current.index + delta + items.length) % items.length }));\n\t\t}\n\t\tif (key.return) return setCollapsed((current) => ({ ...current, [focus.group]: !current[focus.group] }));\n\t\tif (input === ' ' || input === 's') {\n\t\t\tconst target = items[Math.min(focus.index, items.length - 1)];\n\t\t\tif (target === undefined) return;\n\t\t\tif (focus.group === 'channels') return change(input === ' ' ? toggleChannel(filter, target) : soloChannel(filter, target));\n\t\t\tconst level = target as (typeof VIEW_LEVELS)[number];\n\t\t\treturn change(input === ' ' ? toggleLevel(filter, level) : soloLevel(filter, level));\n\t\t}\n\t\tif (input === 'a') return change({ ...filter, allow: null, hidden: new Set(), levels: new Set(VIEW_LEVELS), query: '' });\n\t\tif (input === 'b') {\n\t\t\tsetGrouped((current) => !current);\n\t\t\treturn setPinned(null);\n\t\t}\n\t\tif (key.upArrow || input === 'k') return scroll(-1);\n\t\tif (key.downArrow || input === 'j') return scroll(1);\n\t\tif (key.pageUp) return scroll(-Math.max(1, paneHeight - 1));\n\t\tif (key.pageDown) return scroll(Math.max(1, paneHeight - 1));\n\t\tif (key.home || input === 'g') return setPinned(pinAt(rows, Math.min(paneHeight, rows.length)));\n\t\tif (key.end || input === 'G') return setPinned(null);\n\t\tif (input === 'e') {\n\t\t\t// The most recent error of what is shown: grouped by channel, that is not the last row.\n\t\t\tconst index = newestErrorRow(rows);\n\t\t\tif (index < 0) return;\n\t\t\tconst row = rows[index]!;\n\t\t\tsetMarked(row.kind === 'entry' ? row.entry.id : null);\n\t\t\tsetPinned(pinAt(rows, Math.max(paneHeight, index + Math.ceil(paneHeight / 2))));\n\t\t}\n\t};\n\tuseInput(handleKey, { isActive: active });\n\n\tconst select = (from: LogViewFilter, group: SidebarGroup, index: number, solo: boolean) => {\n\t\tconst target = (group === 'channels' ? channels : VIEW_LEVELS)[index];\n\t\tif (target === undefined) return;\n\t\tsetFocus({ group, index });\n\t\tif (group === 'channels') return change(solo ? soloChannel(from, target) : toggleChannel(from, target));\n\t\tconst level = target as (typeof VIEW_LEVELS)[number];\n\t\treturn change(solo ? soloLevel(from, level) : toggleLevel(from, level));\n\t};\n\n\tconst handleMouse = (event: MouseEvent) => {\n\t\tif (confirmQuit) return;\n\t\tif (event.kind === 'wheel') {\n\t\t\t// Over the sidebar the wheel does nothing: its groups scroll with the selection.\n\t\t\tif (event.column >= side) scroll(event.wheel * WHEEL_ROWS);\n\t\t\treturn;\n\t\t}\n\t\tif (event.kind !== 'press' || event.button !== 'left' || event.column >= side) return;\n\n\t\tconst region = findSidebarRegion(regions.current, event.row, event.column);\n\t\tif (region === null) return;\n\t\tif (region.kind === 'header') {\n\t\t\tsetFocus((current) => (current.group === region.group ? current : { group: region.group, index: 0 }));\n\t\t\treturn setCollapsed((current) => ({ ...current, [region.group]: !current[region.group] }));\n\t\t}\n\t\tif (region.kind === 'key') {\n\t\t\t// While searching the keys are text: a click must not type one into the query, nor quit behind the search box.\n\t\t\tif (searching) return;\n\t\t\tconst own = HINT_KEYS[region.key];\n\t\t\treturn own ? handleKey(own[0], { ...NO_KEY, ...own[1] }) : onKey(region.key);\n\t\t}\n\n\t\t// A click toggles, like space. A second click on the same entry solos it like `s`, from the filter as it was\n\t\t// before the first one, so that a double click on an entry that is already alone shows everything again.\n\t\tconst now = Date.now();\n\t\tconst previous = lastClick.current;\n\t\tconst double =\n\t\t\tprevious !== null && previous.group === region.group && previous.index === region.index && now - previous.at <= DOUBLE_CLICK_MS;\n\t\tlastClick.current = double ? null : { group: region.group, index: region.index, at: now, filter };\n\t\tif (double) return select(previous.filter, region.group, region.index, true);\n\t\t// alt or ctrl + click solos at once.\n\t\treturn select(filter, region.group, region.index, event.alt || event.ctrl);\n\t};\n\t// The subscription outlives a paint, the handler does not: it reads the state of the paint it was made in.\n\tconst mouseHandler = useRef(handleMouse);\n\tmouseHandler.current = handleMouse;\n\tuseEffect(() => {\n\t\tif (!mouse || !active) return undefined;\n\t\treturn mouse.subscribe((event) => mouseHandler.current(event));\n\t}, [mouse, active]);\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\tonRegions={onRegions}\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 type { MouseInput } from '../mouse.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\t/** The mouse of the terminal, when `dev.mouse` is on: the dashboard listens to it. */\n\tmouse?: Pick<MouseInput, 'subscribe'>;\n\t/** Called with whether the dashboard, the only view that takes the mouse, is the one on screen. */\n\tonMouseChange?: (wanted: boolean) => 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(props: DevAppProps) {\n\tconst { service, color, theme, reducedMotion, layout = 'auto', filter, onQuit, onViewChange, onCopy, onThemeSave, mouse, onMouseChange } = props;\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\t// The overlays and the panel keep the terminal's own wheel and text selection.\n\tconst takesMouse = base === 'dashboard' && overlay === null;\n\tuseEffect(() => {\n\t\tonMouseChange?.(takesMouse);\n\t}, [takesMouse, onMouseChange]);\n\n\tconst onCapture = useCallback((capturing: boolean) => setCaptured(capturing), []);\n\n\t/** The keys that act on the session or change the view; also what a click on their hint in the sidebar runs. */\n\tconst runKey = (input: string) => {\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\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\trunKey(input);\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\tmouse={mouse}\n\t\t\t\t\t\t\tonKey={runKey}\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 { PassThrough } from 'node:stream';\nimport { StringDecoder } from 'node:string_decoder';\n\n/**\n * Asks the terminal to report button presses and the wheel (`1000`), with coordinates in the SGR form (`1006`),\n * which is not limited to 223 columns. Motion is left off: nothing here reacts to a hover, and it is one sequence\n * per cell the pointer crosses. A terminal that knows neither ignores both.\n */\nexport const ENABLE_MOUSE = '\\u001B[?1000h\\u001B[?1006h';\nexport const DISABLE_MOUSE = '\\u001B[?1006l\\u001B[?1000l';\n\nexport type MouseButton = 'left' | 'middle' | 'right' | 'none';\n\nexport interface MouseEvent {\n\tkind: 'press' | 'release' | 'wheel';\n\t/** The button of a press or a release; `none` for the wheel. */\n\tbutton: MouseButton;\n\t/** Where the wheel turned: `-1` up, `1` down, `0` for a button. */\n\twheel: -1 | 0 | 1;\n\t/** The cell under the pointer, counted from 0 at the top-left corner. */\n\tcolumn: number;\n\trow: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n}\n\nexport type MouseListener = (event: MouseEvent) => void;\n\n// ESC [ < button ; column ; row, then `M` for a press and `m` for a release.\n// oxlint-disable-next-line no-control-regex\nconst SGR_MOUSE = /\\u001B\\[<(\\d+);(\\d+);(\\d+)([Mm])/g;\n/** The start of a report whose end has not arrived yet, at the end of a chunk. */\n// oxlint-disable-next-line no-control-regex\nconst PARTIAL_SGR_MOUSE = /\\u001B(?:\\[(?:<[\\d;]*)?)?$/;\nconst BUTTONS: readonly MouseButton[] = ['left', 'middle', 'right', 'none'];\n\n/**\n * Splits what the terminal sent into the mouse reports and everything else.\n *\n * @param chunk - A chunk read from the terminal.\n * @returns The mouse events of the chunk, and the chunk without their sequences: the keys the user typed.\n */\nexport function parseMouse(chunk: string): { events: MouseEvent[]; rest: string } {\n\tconst events: MouseEvent[] = [];\n\tconst rest = chunk.replace(SGR_MOUSE, (_match, code: string, column: string, row: string, final: string) => {\n\t\tconst bits = Number(code);\n\t\t// Bit 5 is motion, which is not asked for, and bit 7 the extra buttons (back, forward): neither is a click.\n\t\tif ((bits & 32) !== 0 || (bits & 128) !== 0) return '';\n\n\t\tconst wheel = (bits & 64) !== 0;\n\t\t// The wheel also turns sideways (66, 67), which scrolls nothing here.\n\t\tif (wheel && (bits & 2) !== 0) return '';\n\t\tconst event = {\n\t\t\tcolumn: Number(column) - 1,\n\t\t\trow: Number(row) - 1,\n\t\t\tshift: (bits & 4) !== 0,\n\t\t\talt: (bits & 8) !== 0,\n\t\t\tctrl: (bits & 16) !== 0\n\t\t};\n\t\tif (wheel) events.push({ ...event, kind: 'wheel', button: 'none', wheel: (bits & 1) === 0 ? -1 : 1 });\n\t\telse events.push({ ...event, kind: final === 'M' ? 'press' : 'release', button: BUTTONS[bits & 3]!, wheel: 0 });\n\t\treturn '';\n\t});\n\n\treturn { events, rest };\n}\n\nexport interface MouseInput {\n\t/** What the UI reads its keys from: the terminal's input without the mouse reports. */\n\treadonly stdin: NodeJS.ReadStream;\n\t/** Listens to the mouse; the returned function stops listening. */\n\tsubscribe(listener: MouseListener): () => void;\n\t/** Stops reading the terminal's input. */\n\tdispose(): void;\n}\n\n/**\n * Reads the terminal's input ahead of the UI, so that a mouse report is never taken for typed text: Ink would\n * otherwise hand `ESC[<0;12;5M` to its key handlers, and a click while searching would type it into the query.\n *\n * @param source - The terminal's input.\n */\nexport function createMouseInput(source: NodeJS.ReadStream): MouseInput {\n\tconst filtered = new PassThrough();\n\tconst listeners = new Set<MouseListener>();\n\t// A character cut in two by a read (a paste) is put back together, as Ink's `setEncoding` did on the terminal.\n\tconst decoder = new StringDecoder('utf8');\n\tlet pending = '';\n\n\tconst onData = (data: Buffer | string) => {\n\t\tconst { events, rest } = parseMouse(pending + (typeof data === 'string' ? data : decoder.write(data)));\n\t\t// A lone ESC is the Escape key: only what looks like the start of a report waits for the next chunk.\n\t\tconst partial = rest.length > 1 ? PARTIAL_SGR_MOUSE.exec(rest) : null;\n\t\tconst held = partial && partial[0].length > 1 ? partial[0] : '';\n\t\tpending = held;\n\t\tconst keys = held ? rest.slice(0, -held.length) : rest;\n\t\tif (keys) filtered.write(keys);\n\t\tfor (const event of events) for (const listener of listeners) listener(event);\n\t};\n\tsource.on('data', onData);\n\n\tconst stdin = Object.assign(filtered, {\n\t\tisTTY: source.isTTY,\n\t\tsetRawMode(mode: boolean) {\n\t\t\tsource.setRawMode?.(mode);\n\t\t\treturn stdin;\n\t\t},\n\t\tref() {\n\t\t\tsource.ref?.();\n\t\t\treturn stdin;\n\t\t},\n\t\tunref() {\n\t\t\tsource.unref?.();\n\t\t\treturn stdin;\n\t\t}\n\t}) as unknown as NodeJS.ReadStream;\n\n\treturn {\n\t\tstdin,\n\t\tsubscribe(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => listeners.delete(listener);\n\t\t},\n\t\tdispose() {\n\t\t\tsource.off('data', onData);\n\t\t\tsource.pause?.();\n\t\t\tlisteners.clear();\n\t\t\tfiltered.end();\n\t\t}\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 { createMouseInput, DISABLE_MOUSE, ENABLE_MOUSE } from './mouse.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\t/** `--no-mouse`; defaults to `dev.mouse`. */\n\tmouse?: boolean;\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\tconst mouse = (options.mouse ?? service.config.dev.mouse) ? createMouseInput(stdin) : null;\n\t// The mouse is only reported while the dashboard is on screen: the panel and the overlays leave the terminal its\n\t// own wheel and text selection.\n\tlet reporting = false;\n\tconst reportMouse = (wanted: boolean) => {\n\t\tif (!mouse || wanted === reporting) return;\n\t\treporting = wanted;\n\t\twrite(wanted ? ENABLE_MOUSE : DISABLE_MOUSE);\n\t};\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\tmouse={mouse ?? undefined}\n\t\t\tonMouseChange={(wanted) => {\n\t\t\t\tif (!stopped) reportMouse(wanted);\n\t\t\t}}\n\t\t/>,\n\t\t{\n\t\t\tstdout: sink,\n\t\t\tstdin: mouse?.stdin ?? stdin,\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\treportMouse(false);\n\t\t\tif (alternate) write('\\u001B[?1049l');\n\t\t\tmouse?.dispose();\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
+ {"version":3,"file":"tui-C8MjzsKS.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/mouse.ts","../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 { useEffect, 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\n/**\n * What a click on the sidebar lands on. Rows and columns are counted from 0 at the top-left corner of the sidebar;\n * `end` is exclusive.\n */\nexport type SidebarRegion =\n\t| { kind: 'header'; group: SidebarGroup; row: number }\n\t| { kind: 'item'; group: SidebarGroup; index: number; row: number; start: number; end: number }\n\t| { kind: 'key'; key: string; row: number };\n\n/** A region before its row is known: the rows are numbered once the sidebar knows which of them fit. */\ntype SidebarHit =\n\t| { kind: 'header'; group: SidebarGroup }\n\t| { kind: 'items'; group: SidebarGroup; items: readonly { index: number; start: number; end: number }[] }\n\t| { kind: 'key'; key: string };\n\ninterface SidebarRow {\n\tnode: ReactNode;\n\thit?: SidebarHit;\n}\n\n/** The region of the sidebar at a cell, if a click there does something. */\nexport function findSidebarRegion(regions: readonly SidebarRegion[], row: number, column: number): SidebarRegion | null {\n\treturn regions.find((region) => region.row === row && (region.kind !== 'item' || (column >= region.start && column < region.end))) ?? null;\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\t/** Told where the clickable entries are after every paint, for the mouse. */\n\tonRegions?: (regions: readonly SidebarRegion[]) => void;\n}\n\n/** The padding of the sidebar, then the indentation of the lines of a group. */\nconst PADDING = 1;\nconst INDENT = 2;\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, onRegions } =\n\t\tprops;\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 = (\n\t\tgroup: SidebarGroup,\n\t\tlabels: readonly string[],\n\t\tnodes: readonly ReactNode[],\n\t\trange: [number, number] = [0, Infinity]\n\t): SidebarRow[] =>\n\t\twrapLabels(labels, labelWidth)\n\t\t\t.slice(...range)\n\t\t\t.map((line, index) => {\n\t\t\t\t// Where each label of the line starts: the labels are separated by one space.\n\t\t\t\tlet column = PADDING + INDENT;\n\t\t\t\tconst items = line.map((label) => {\n\t\t\t\t\tconst start = column;\n\t\t\t\t\tcolumn += labels[label]!.length + 1;\n\t\t\t\t\treturn { index: label, start, end: column - 1 };\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\thit: { kind: 'items', group, items },\n\t\t\t\t\tnode: (\n\t\t\t\t\t\t<Text key={`${group}-${index}`} wrap=\"truncate-end\">\n\t\t\t\t\t\t\t{' '.repeat(INDENT)}\n\t\t\t\t\t\t\t{line.flatMap((label, position) => (position > 0 ? [' ', nodes[label]] : [nodes[label]]))}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)\n\t\t\t\t};\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: SidebarRow[] = 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: SidebarRow[] = [\n\t\t{ node: <Text key=\"gap-filters\"> </Text> },\n\t\t{\n\t\t\thit: { kind: 'header', group: 'channels' },\n\t\t\tnode: groupHeader('channels', !collapsed.channels && hiddenChannels > 0 ? ` · ${range[0] + 1}-${range[1]}/${channelLayout.length}` : '')\n\t\t},\n\t\t...(collapsed.channels ? [] : lines('channels', channels, channelNodes, range)),\n\t\t{ hit: { kind: 'header', group: 'levels' }, node: groupHeader('levels') },\n\t\t...levelLines\n\t];\n\n\tconst keys: SidebarRow[][] = KEYS.map((section, sectionIndex) => [\n\t\t{ node: <Text key={`gap-keys-${sectionIndex}`}> </Text> },\n\t\t...section.map(([key, label]) => ({\n\t\t\thit: { kind: 'key', key } satisfies SidebarHit,\n\t\t\tnode: (\n\t\t\t\t<Text key={key} wrap=\"truncate-end\">\n\t\t\t\t\t<Text bold color={paint('url')}>\n\t\t\t\t\t\t{key}\n\t\t\t\t\t</Text>{' '}\n\t\t\t\t\t<Text dimColor>{label}</Text>\n\t\t\t\t</Text>\n\t\t\t)\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\tconst statusRows = head.map((node): SidebarRow => ({ node }));\n\tlet body = [...statusRows, ...filters, ...keys.flat()];\n\tif (body.length > budget) body = [...statusRows, ...filters, ...keys[1]!];\n\tif (body.length > budget) body = [...statusRows, ...filters];\n\tbody = body.slice(0, budget);\n\n\tconst regions = body.flatMap(({ hit }, row): SidebarRegion[] => {\n\t\tif (hit === undefined) return [];\n\t\tif (hit.kind === 'items') return hit.items.map((item) => ({ kind: 'item', group: hit.group, row, ...item }));\n\t\treturn [{ ...hit, row }];\n\t});\n\t// Compared by value: the regions only move when the layout does, and the dashboard repaints on every log entry.\n\tconst regionsKey = JSON.stringify(regions);\n\tuseEffect(() => onRegions?.(regions), [regionsKey, onRegions]);\n\n\treturn (\n\t\t<Box flexDirection=\"column\" width={width} height={height} paddingX={PADDING}>\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, type Key } from 'ink';\nimport { useCallback, useEffect, useMemo, useRef, 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 { MouseEvent, MouseInput } from '../../mouse.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 { findSidebarRegion, Sidebar, type SidebarFocus, type SidebarGroup, type SidebarRegion } 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\t/** The mouse of the terminal, when `dev.mouse` is on. */\n\tmouse?: Pick<MouseInput, 'subscribe'>;\n\t/** Runs a key of the app (`q`, `r`, `?`…), for a click on its hint in the sidebar. */\n\tonKey: (input: string) => void;\n}\n\n/** How many rows a notch of the wheel scrolls. */\nconst WHEEL_ROWS = 3;\n/** Two clicks on the same entry within this many milliseconds are a double click. */\nconst DOUBLE_CLICK_MS = 400;\nconst NO_KEY = {} as Key;\n/** The keys of the sidebar a click can press, by how the sidebar writes them: the others stand for several keys. */\nconst HINT_KEYS: Readonly<Record<string, readonly [input: string, key: Partial<Key>]>> = {\n\ttab: ['', { tab: true }],\n\tspace: [' ', {}],\n\ts: ['s', {}]\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, mouse, onKey } = 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\tconst regions = useRef<readonly SidebarRegion[]>([]);\n\tconst lastClick = useRef<{ group: SidebarGroup; index: number; at: number; filter: LogViewFilter } | null>(null);\n\tconst onRegions = useCallback((next: readonly SidebarRegion[]) => {\n\t\tregions.current = next;\n\t}, []);\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\tconst handleKey = (input: string, key: Key) => {\n\t\tif (key.ctrl || confirmQuit) return;\n\t\tif (searching) {\n\t\t\tif (key.escape) {\n\t\t\t\tsetSearching(false);\n\t\t\t\tchange({ ...filter, query: '' });\n\t\t\t} else if (key.return) setSearching(false);\n\t\t\telse if (key.backspace || key.delete) change({ ...filter, query: [...filter.query].slice(0, -1).join('') });\n\t\t\telse if (input && !key.upArrow && !key.downArrow && !key.leftArrow && !key.rightArrow && !key.tab) {\n\t\t\t\tchange({ ...filter, query: filter.query + input });\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (key.escape) {\n\t\t\tif (filter.query) change({ ...filter, query: '' });\n\t\t\telse setPinned(null);\n\t\t\treturn setMarked(null);\n\t\t}\n\t\tif (input === '/') return setSearching(true);\n\t\tif (key.tab) return setFocus((current) => ({ group: current.group === 'channels' ? 'levels' : 'channels', index: 0 }));\n\t\tif (key.leftArrow || key.rightArrow) {\n\t\t\tif (items.length === 0) return;\n\t\t\tconst delta = key.leftArrow ? -1 : 1;\n\t\t\treturn setFocus((current) => ({ ...current, index: (current.index + delta + items.length) % items.length }));\n\t\t}\n\t\tif (key.return) return setCollapsed((current) => ({ ...current, [focus.group]: !current[focus.group] }));\n\t\tif (input === ' ' || input === 's') {\n\t\t\tconst target = items[Math.min(focus.index, items.length - 1)];\n\t\t\tif (target === undefined) return;\n\t\t\tif (focus.group === 'channels') return change(input === ' ' ? toggleChannel(filter, target) : soloChannel(filter, target));\n\t\t\tconst level = target as (typeof VIEW_LEVELS)[number];\n\t\t\treturn change(input === ' ' ? toggleLevel(filter, level) : soloLevel(filter, level));\n\t\t}\n\t\tif (input === 'a') return change({ ...filter, allow: null, hidden: new Set(), levels: new Set(VIEW_LEVELS), query: '' });\n\t\tif (input === 'b') {\n\t\t\tsetGrouped((current) => !current);\n\t\t\treturn setPinned(null);\n\t\t}\n\t\tif (key.upArrow || input === 'k') return scroll(-1);\n\t\tif (key.downArrow || input === 'j') return scroll(1);\n\t\tif (key.pageUp) return scroll(-Math.max(1, paneHeight - 1));\n\t\tif (key.pageDown) return scroll(Math.max(1, paneHeight - 1));\n\t\tif (key.home || input === 'g') return setPinned(pinAt(rows, Math.min(paneHeight, rows.length)));\n\t\tif (key.end || input === 'G') return setPinned(null);\n\t\tif (input === 'e') {\n\t\t\t// The most recent error of what is shown: grouped by channel, that is not the last row.\n\t\t\tconst index = newestErrorRow(rows);\n\t\t\tif (index < 0) return;\n\t\t\tconst row = rows[index]!;\n\t\t\tsetMarked(row.kind === 'entry' ? row.entry.id : null);\n\t\t\tsetPinned(pinAt(rows, Math.max(paneHeight, index + Math.ceil(paneHeight / 2))));\n\t\t}\n\t};\n\tuseInput(handleKey, { isActive: active });\n\n\tconst select = (from: LogViewFilter, group: SidebarGroup, index: number, solo: boolean) => {\n\t\tconst target = (group === 'channels' ? channels : VIEW_LEVELS)[index];\n\t\tif (target === undefined) return;\n\t\tsetFocus({ group, index });\n\t\tif (group === 'channels') return change(solo ? soloChannel(from, target) : toggleChannel(from, target));\n\t\tconst level = target as (typeof VIEW_LEVELS)[number];\n\t\treturn change(solo ? soloLevel(from, level) : toggleLevel(from, level));\n\t};\n\n\tconst handleMouse = (event: MouseEvent) => {\n\t\tif (confirmQuit) return;\n\t\tif (event.kind === 'wheel') {\n\t\t\t// Over the sidebar the wheel does nothing: its groups scroll with the selection.\n\t\t\tif (event.column >= side) scroll(event.wheel * WHEEL_ROWS);\n\t\t\treturn;\n\t\t}\n\t\tif (event.kind !== 'press' || event.button !== 'left' || event.column >= side) return;\n\n\t\tconst region = findSidebarRegion(regions.current, event.row, event.column);\n\t\tif (region === null) return;\n\t\tif (region.kind === 'header') {\n\t\t\tsetFocus((current) => (current.group === region.group ? current : { group: region.group, index: 0 }));\n\t\t\treturn setCollapsed((current) => ({ ...current, [region.group]: !current[region.group] }));\n\t\t}\n\t\tif (region.kind === 'key') {\n\t\t\t// While searching the keys are text: a click must not type one into the query, nor quit behind the search box.\n\t\t\tif (searching) return;\n\t\t\tconst own = HINT_KEYS[region.key];\n\t\t\treturn own ? handleKey(own[0], { ...NO_KEY, ...own[1] }) : onKey(region.key);\n\t\t}\n\n\t\t// A click toggles, like space. A second click on the same entry solos it like `s`, from the filter as it was\n\t\t// before the first one, so that a double click on an entry that is already alone shows everything again.\n\t\tconst now = Date.now();\n\t\tconst previous = lastClick.current;\n\t\tconst double =\n\t\t\tprevious !== null && previous.group === region.group && previous.index === region.index && now - previous.at <= DOUBLE_CLICK_MS;\n\t\tlastClick.current = double ? null : { group: region.group, index: region.index, at: now, filter };\n\t\tif (double) return select(previous.filter, region.group, region.index, true);\n\t\t// alt or ctrl + click solos at once.\n\t\treturn select(filter, region.group, region.index, event.alt || event.ctrl);\n\t};\n\t// The subscription outlives a paint, the handler does not: it reads the state of the paint it was made in.\n\tconst mouseHandler = useRef(handleMouse);\n\tmouseHandler.current = handleMouse;\n\tuseEffect(() => {\n\t\tif (!mouse || !active) return undefined;\n\t\treturn mouse.subscribe((event) => mouseHandler.current(event));\n\t}, [mouse, active]);\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\tonRegions={onRegions}\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 type { MouseInput } from '../mouse.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\t/** The mouse of the terminal, when `dev.mouse` is on: the dashboard listens to it. */\n\tmouse?: Pick<MouseInput, 'subscribe'>;\n\t/** Called with whether the dashboard, the only view that takes the mouse, is the one on screen. */\n\tonMouseChange?: (wanted: boolean) => 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(props: DevAppProps) {\n\tconst { service, color, theme, reducedMotion, layout = 'auto', filter, onQuit, onViewChange, onCopy, onThemeSave, mouse, onMouseChange } = props;\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\t// The overlays and the panel keep the terminal's own wheel and text selection.\n\tconst takesMouse = base === 'dashboard' && overlay === null;\n\tuseEffect(() => {\n\t\tonMouseChange?.(takesMouse);\n\t}, [takesMouse, onMouseChange]);\n\n\tconst onCapture = useCallback((capturing: boolean) => setCaptured(capturing), []);\n\n\t/** The keys that act on the session or change the view; also what a click on their hint in the sidebar runs. */\n\tconst runKey = (input: string) => {\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\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\trunKey(input);\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\tmouse={mouse}\n\t\t\t\t\t\t\tonKey={runKey}\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 { PassThrough } from 'node:stream';\nimport { StringDecoder } from 'node:string_decoder';\n\n/**\n * Asks the terminal to report button presses and the wheel (`1000`), with coordinates in the SGR form (`1006`),\n * which is not limited to 223 columns. Motion is left off: nothing here reacts to a hover, and it is one sequence\n * per cell the pointer crosses. A terminal that knows neither ignores both.\n */\nexport const ENABLE_MOUSE = '\\u001B[?1000h\\u001B[?1006h';\nexport const DISABLE_MOUSE = '\\u001B[?1006l\\u001B[?1000l';\n\nexport type MouseButton = 'left' | 'middle' | 'right' | 'none';\n\nexport interface MouseEvent {\n\tkind: 'press' | 'release' | 'wheel';\n\t/** The button of a press or a release; `none` for the wheel. */\n\tbutton: MouseButton;\n\t/** Where the wheel turned: `-1` up, `1` down, `0` for a button. */\n\twheel: -1 | 0 | 1;\n\t/** The cell under the pointer, counted from 0 at the top-left corner. */\n\tcolumn: number;\n\trow: number;\n\tshift: boolean;\n\talt: boolean;\n\tctrl: boolean;\n}\n\nexport type MouseListener = (event: MouseEvent) => void;\n\n// ESC [ < button ; column ; row, then `M` for a press and `m` for a release.\n// oxlint-disable-next-line no-control-regex\nconst SGR_MOUSE = /\\u001B\\[<(\\d+);(\\d+);(\\d+)([Mm])/g;\n/** The start of a report whose end has not arrived yet, at the end of a chunk. */\n// oxlint-disable-next-line no-control-regex\nconst PARTIAL_SGR_MOUSE = /\\u001B(?:\\[(?:<[\\d;]*)?)?$/;\nconst BUTTONS: readonly MouseButton[] = ['left', 'middle', 'right', 'none'];\n\n/**\n * Splits what the terminal sent into the mouse reports and everything else.\n *\n * @param chunk - A chunk read from the terminal.\n * @returns The mouse events of the chunk, and the chunk without their sequences: the keys the user typed.\n */\nexport function parseMouse(chunk: string): { events: MouseEvent[]; rest: string } {\n\tconst events: MouseEvent[] = [];\n\tconst rest = chunk.replace(SGR_MOUSE, (_match, code: string, column: string, row: string, final: string) => {\n\t\tconst bits = Number(code);\n\t\t// Bit 5 is motion, which is not asked for, and bit 7 the extra buttons (back, forward): neither is a click.\n\t\tif ((bits & 32) !== 0 || (bits & 128) !== 0) return '';\n\n\t\tconst wheel = (bits & 64) !== 0;\n\t\t// The wheel also turns sideways (66, 67), which scrolls nothing here.\n\t\tif (wheel && (bits & 2) !== 0) return '';\n\t\tconst event = {\n\t\t\tcolumn: Number(column) - 1,\n\t\t\trow: Number(row) - 1,\n\t\t\tshift: (bits & 4) !== 0,\n\t\t\talt: (bits & 8) !== 0,\n\t\t\tctrl: (bits & 16) !== 0\n\t\t};\n\t\tif (wheel) events.push({ ...event, kind: 'wheel', button: 'none', wheel: (bits & 1) === 0 ? -1 : 1 });\n\t\telse events.push({ ...event, kind: final === 'M' ? 'press' : 'release', button: BUTTONS[bits & 3]!, wheel: 0 });\n\t\treturn '';\n\t});\n\n\treturn { events, rest };\n}\n\nexport interface MouseInput {\n\t/** What the UI reads its keys from: the terminal's input without the mouse reports. */\n\treadonly stdin: NodeJS.ReadStream;\n\t/** Listens to the mouse; the returned function stops listening. */\n\tsubscribe(listener: MouseListener): () => void;\n\t/** Stops reading the terminal's input. */\n\tdispose(): void;\n}\n\n/**\n * Reads the terminal's input ahead of the UI, so that a mouse report is never taken for typed text: Ink would\n * otherwise hand `ESC[<0;12;5M` to its key handlers, and a click while searching would type it into the query.\n *\n * @param source - The terminal's input.\n */\nexport function createMouseInput(source: NodeJS.ReadStream): MouseInput {\n\tconst filtered = new PassThrough();\n\tconst listeners = new Set<MouseListener>();\n\t// A character cut in two by a read (a paste) is put back together, as Ink's `setEncoding` did on the terminal.\n\tconst decoder = new StringDecoder('utf8');\n\tlet pending = '';\n\n\tconst onData = (data: Buffer | string) => {\n\t\tconst { events, rest } = parseMouse(pending + (typeof data === 'string' ? data : decoder.write(data)));\n\t\t// A lone ESC is the Escape key: only what looks like the start of a report waits for the next chunk.\n\t\tconst partial = rest.length > 1 ? PARTIAL_SGR_MOUSE.exec(rest) : null;\n\t\tconst held = partial && partial[0].length > 1 ? partial[0] : '';\n\t\tpending = held;\n\t\tconst keys = held ? rest.slice(0, -held.length) : rest;\n\t\tif (keys) filtered.write(keys);\n\t\tfor (const event of events) for (const listener of listeners) listener(event);\n\t};\n\tsource.on('data', onData);\n\n\tconst stdin = Object.assign(filtered, {\n\t\tisTTY: source.isTTY,\n\t\tsetRawMode(mode: boolean) {\n\t\t\tsource.setRawMode?.(mode);\n\t\t\treturn stdin;\n\t\t},\n\t\tref() {\n\t\t\tsource.ref?.();\n\t\t\treturn stdin;\n\t\t},\n\t\tunref() {\n\t\t\tsource.unref?.();\n\t\t\treturn stdin;\n\t\t}\n\t}) as unknown as NodeJS.ReadStream;\n\n\treturn {\n\t\tstdin,\n\t\tsubscribe(listener) {\n\t\t\tlisteners.add(listener);\n\t\t\treturn () => listeners.delete(listener);\n\t\t},\n\t\tdispose() {\n\t\t\tsource.off('data', onData);\n\t\t\tsource.pause?.();\n\t\t\tlisteners.clear();\n\t\t\tfiltered.end();\n\t\t}\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 { createMouseInput, DISABLE_MOUSE, ENABLE_MOUSE } from './mouse.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\t/** `--no-mouse`; defaults to `dev.mouse`. */\n\tmouse?: boolean;\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\tconst mouse = (options.mouse ?? service.config.dev.mouse) ? createMouseInput(stdin) : null;\n\t// The mouse is only reported while the dashboard is on screen: the panel and the overlays leave the terminal its\n\t// own wheel and text selection.\n\tlet reporting = false;\n\tconst reportMouse = (wanted: boolean) => {\n\t\tif (!mouse || wanted === reporting) return;\n\t\treporting = wanted;\n\t\twrite(wanted ? ENABLE_MOUSE : DISABLE_MOUSE);\n\t};\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\tmouse={mouse ?? undefined}\n\t\t\tonMouseChange={(wanted) => {\n\t\t\t\tif (!stopped) reportMouse(wanted);\n\t\t\t}}\n\t\t/>,\n\t\t{\n\t\t\tstdout: sink,\n\t\t\tstdin: mouse?.stdin ?? stdin,\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\treportMouse(false);\n\t\t\tif (alternate) write('\\u001B[?1049l');\n\t\t\tmouse?.dispose();\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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"}