@seedcord/cli 0.1.0-next.0 → 0.2.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":["createNodeRequire","viteConfig"],"sources":["../src/core/BaseCommand.ts","../src/utils/resolveDefaultExport.ts","../src/core/config/ConfigLoader.ts","../src/core/config/ConfigLocator.ts","../src/core/modules/RuntimeModuleLoader.ts","../src/commands/build/builder/BootstrapWriter.ts","../src/commands/build/builder/TypeScriptProjectBuilder.ts","../src/commands/build/BuildRunner.ts","../src/commands/build/BuildCommand.ts","../src/ui/hooks/useDevState.ts","../src/ui/stores/LogStore.ts","../src/ui/hooks/useLogs.ts","../src/ui/hooks/useScroll.ts","../src/ui/stores/devPhase.ts","../src/ui/hooks/useUptime.ts","../src/ui/hotkeys.ts","../src/ui/components/primitives/LogHeader.tsx","../src/ui/components/CommandRefreshPrompt.tsx","../src/ui/components/ErrorDisplay.tsx","../src/ui/components/RestartRequiredCard.tsx","../src/ui/components/primitives/NotificationStack.tsx","../src/ui/channelColor.ts","../src/ui/components/primitives/ScrollableLogView.tsx","../src/ui/format.ts","../src/ui/components/Banner.tsx","../src/ui/components/primitives/RunningAnimation.tsx","../src/ui/components/StatusBadge.tsx","../src/ui/components/primitives/ChannelToggles.tsx","../src/ui/components/primitives/HotkeyBar.tsx","../src/ui/components/primitives/Sidebar.tsx","../src/ui/layout/DevLayout.tsx","../src/ui/DevApp.tsx","../src/ui/stores/DevStore.ts","../src/utils/SilentLogger.ts","../src/commands/dev/runtime/HmrPlugin.ts","../src/commands/dev/runtime/vite.config.ts","../src/commands/dev/runtime/ViteDevRuntime.ts","../src/commands/dev/TscRunner.ts","../src/commands/dev/DevRunner.ts","../src/commands/dev/DevCommand.ts","../src/cli.ts"],"sourcesContent":["import { Logger } from '@seedcord/services';\n\nimport type { Command } from '@commander-js/extra-typings';\nimport type { ILogger } from '@seedcord/types';\n\nexport abstract class BaseCommand {\n protected readonly logger: ILogger;\n\n constructor(\n public readonly name: string,\n public readonly description: string,\n loggerChannel: string\n ) {\n this.logger = new Logger(loggerChannel);\n }\n\n public abstract register(program: Command): void;\n}\n","export function resolveDefaultExport<TValue>(moduleExport: TValue): unknown {\n let current: unknown = moduleExport;\n const visited = new Set<unknown>();\n\n while (isObjectWithDefault(current) && !visited.has(current)) {\n visited.add(current);\n current = current.default;\n }\n\n return current;\n}\n\nfunction isObjectWithDefault(value: unknown): value is { default: unknown } {\n return Boolean(value && typeof value === 'object' && 'default' in value);\n}\n","import { dirname, isAbsolute, relative, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { resolveDefaultExport } from '@utils/resolveDefaultExport';\n\nimport type {\n ResolvedSeedcordBuildConfig,\n ResolvedSeedcordDevConfig,\n SeedcordBuildConfig,\n SeedcordDevConfig\n} from './schema';\nimport type { ModuleLoader } from '@core/modules/ModuleLoader';\nimport type { ILogger } from '@seedcord/types';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return typeof value === 'undefined' || typeof value === 'string';\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction validateBuild(value: unknown): void {\n if (typeof value === 'undefined') return;\n if (!isPlainObject(value)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuild);\n if (!isOptionalString(value.outDir)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildOutDir);\n if (!isOptionalString(value.tsconfig)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildTsconfig);\n if (!isOptionalString(value.bootstrap)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildBootstrap);\n}\n\nfunction validateHmr(value: unknown): void {\n if (typeof value === 'undefined') return;\n if (!isPlainObject(value)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidHmr);\n if (!isOptionalString(value.tsconfig)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidTsconfig);\n if (typeof value.restart !== 'undefined' && !isStringArray(value.restart)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidHmrRestart);\n }\n}\n\nfunction validateConfig(raw: unknown): asserts raw is SeedcordDevConfig {\n if (!isPlainObject(raw)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidExport);\n if (typeof raw.instance !== 'string' || raw.instance.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingInstance);\n }\n if (typeof raw.entry !== 'string' || raw.entry.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingEntry);\n }\n if (!isOptionalString(raw.root)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidRoot);\n validateBuild(raw.build);\n validateHmr(raw.hmr);\n}\n\nexport class ConfigLoader {\n constructor(\n private readonly modules: ModuleLoader,\n private readonly logger: ILogger\n ) {}\n\n public async load(configPath: string): Promise<ResolvedSeedcordDevConfig> {\n const loadedModule = await this.modules.importModule(configPath);\n const config: unknown = await Promise.resolve(resolveDefaultExport(loadedModule));\n validateConfig(config);\n\n const configDir = dirname(configPath);\n const root = resolve(configDir, config.root ?? '.');\n const instance = this.resolveWithinRoot(root, config.instance);\n const entry = this.resolveWithinRoot(root, config.entry);\n this.assertEntryWithinRoot(root, entry);\n const build = this.resolveBuildOptions(configDir, config.build);\n const tsconfig = config.hmr?.tsconfig ? resolve(root, config.hmr.tsconfig) : undefined;\n\n this.logger.info(`Loaded configuration from ${configPath}`);\n this.logger.debug(`Resolved root: ${root}`);\n this.logger.debug(`Resolved instance: ${instance}`);\n this.logger.debug(`Resolved entry: ${entry}`);\n this.logger.debug(`Resolved build outDir: ${build.outDir}`);\n if (build.tsconfig) this.logger.debug(`Resolved build tsconfig: ${build.tsconfig}`);\n if (tsconfig) this.logger.debug(`Resolved dev tsconfig: ${tsconfig}`);\n this.logger.debug(`Resolved bootstrap: ${build.bootstrap}`);\n\n return {\n instance,\n root,\n configFile: configPath,\n entry,\n build,\n tsconfig,\n hmr: config.hmr\n } satisfies ResolvedSeedcordDevConfig;\n }\n\n private resolveWithinRoot(root: string, target: string): string {\n if (isAbsolute(target)) return target;\n return resolve(root, target);\n }\n\n private assertEntryWithinRoot(root: string, entry: string): void {\n const relativePath = relative(root, entry);\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigEntryOutsideRoot, [entry, root]);\n }\n }\n\n private resolveBuildOptions(\n configDir: string,\n build: SeedcordBuildConfig | undefined\n ): ResolvedSeedcordBuildConfig {\n const outDir = resolve(configDir, build?.outDir ?? 'dist');\n const bootstrapValue = build?.bootstrap;\n const bootstrap = bootstrapValue ? this.resolveBootstrap(outDir, bootstrapValue) : resolve(outDir, 'index.mjs');\n const tsconfig = build?.tsconfig ? resolve(configDir, build.tsconfig) : undefined;\n\n const resolvedBuild: ResolvedSeedcordBuildConfig = tsconfig\n ? { outDir, bootstrap, tsconfig }\n : { outDir, bootstrap };\n\n return resolvedBuild;\n }\n\n private resolveBootstrap(outDir: string, bootstrap: string): string {\n if (isAbsolute(bootstrap)) return bootstrap;\n return resolve(outDir, bootstrap);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { SEEDCORD_CONFIG_FILENAMES } from './schema';\n\nimport type { ILogger } from '@seedcord/types';\n\nexport class ConfigLocator {\n constructor(private readonly logger: ILogger) {}\n\n public locate(baseDir = process.cwd()): string {\n const normalizedBase = resolve(baseDir);\n for (const candidate of SEEDCORD_CONFIG_FILENAMES) {\n const fullPath = join(normalizedBase, candidate);\n if (existsSync(fullPath)) {\n this.logger.debug(`Found config at ${fullPath}`);\n return fullPath;\n }\n }\n\n throw new SeedcordError(SeedcordErrorCode.CliConfigNotFound, [normalizedBase, SEEDCORD_CONFIG_FILENAMES]);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { createJiti } from 'jiti';\nimport { tsImport } from 'tsx/esm/api';\n\nimport type { ModuleLoader } from './ModuleLoader';\n\ntype TsconfigOption = string | false;\n\ninterface RuntimeModuleLoaderOptions {\n tsconfig?: TsconfigOption;\n forceTsx?: boolean;\n}\n\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nexport class RuntimeModuleLoader implements ModuleLoader {\n private readonly jiti = createJiti(import.meta.url, {\n cache: false,\n interopDefault: true,\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs']\n });\n\n constructor(private readonly options: RuntimeModuleLoaderOptions = {}) {}\n\n public async importModule<TModule = unknown>(entryPath: string): Promise<TModule> {\n const normalized = resolve(entryPath);\n if (!existsSync(normalized)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [normalized]);\n }\n\n if (this.shouldUseTsx(normalized)) {\n return this.importWithTsx<TModule>(normalized);\n }\n\n return this.importWithNode<TModule>(normalized);\n }\n\n private shouldUseTsx(filePath: string): boolean {\n if (this.options.forceTsx) return true;\n return TS_EXTENSIONS.has(extname(filePath).toLowerCase());\n }\n\n private async importWithTsx<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n const tsconfig = this.resolveTsconfig(entryPath);\n\n try {\n return (await tsImport(specifier, { parentURL: import.meta.url, tsconfig })) as TModule;\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown tsx error';\n throw new SeedcordError(SeedcordErrorCode.CliTsxImportFailed, [entryPath, reason]);\n }\n }\n\n private async importWithNode<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n\n try {\n return (await import(specifier)) as TModule;\n } catch (nativeError: unknown) {\n try {\n return await this.jiti.import(entryPath);\n } catch (fallbackError: unknown) {\n const nativeReason = nativeError instanceof Error ? nativeError.message : 'Unknown ESM import error';\n const fallbackReason = fallbackError instanceof Error ? fallbackError.message : 'Unknown jiti error';\n throw new SeedcordError(SeedcordErrorCode.CliImportFailed, [entryPath, nativeReason, fallbackReason]);\n }\n }\n }\n\n private resolveTsconfig(entryPath: string): TsconfigOption {\n if (typeof this.options.tsconfig !== 'undefined') {\n return this.options.tsconfig;\n }\n\n return this.findNearestTsconfig(dirname(entryPath)) ?? false;\n }\n\n private findNearestTsconfig(startDir: string): string | undefined {\n const candidate = resolve(startDir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(startDir);\n if (parent === startDir) return undefined;\n\n return this.findNearestTsconfig(parent);\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BootstrapWriter {\n constructor(private readonly logger: ILogger) {}\n\n public async write(config: ResolvedSeedcordDevConfig, emittedEntry: string): Promise<void> {\n const target = config.build.bootstrap;\n const relativeImport = this.formatImportPath(relative(dirname(target), emittedEntry));\n const contents = `import '${relativeImport}';\\n`;\n\n try {\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, contents, 'utf8');\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliBootstrapWriteFailed, [target, reason]);\n }\n\n this.logger.info(`Bootstrap file created at ${target}`);\n }\n\n private formatImportPath(fragment: string): string {\n const normalized = fragment.replaceAll('\\\\', '/');\n return normalized.startsWith('.') ? normalized : `./${normalized}`;\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createRequire as createNodeRequire } from 'node:module';\nimport { dirname, extname, relative, resolve } from 'node:path';\n\nimport { isSeedcordError, SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface BuildResult {\n emittedEntry: string;\n}\n\ninterface ProcessResult {\n exitCode: number;\n output: string;\n}\n\nexport class TypeScriptProjectBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public async build(config: ResolvedSeedcordDevConfig): Promise<BuildResult> {\n const tsconfigPath = this.resolveTsconfig(config);\n const projectDir = dirname(config.configFile);\n\n await mkdir(config.build.outDir, { recursive: true });\n\n this.logger.info(`Building Seedcord project via tsc using ${tsconfigPath}`);\n\n try {\n await this.runTsc(projectDir, tsconfigPath);\n await this.fixRelativeSpecifiers(config.build.outDir);\n } catch (error: unknown) {\n if (isSeedcordError(error)) throw error;\n\n const reason = error instanceof Error ? error.message : 'Unknown build error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [reason]);\n }\n\n const emittedEntry = this.resolveEmittedEntry(config);\n if (!existsSync(emittedEntry)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Expected output file ${emittedEntry} missing after build`\n ]);\n }\n\n this.logger.info(`Emitted entry: ${emittedEntry}`);\n return { emittedEntry } satisfies BuildResult;\n }\n\n private async runTsc(projectDir: string, tsconfigPath: string): Promise<void> {\n const tscPath = this.resolveProjectTsc(projectDir);\n\n const args = ['-p', tsconfigPath, '--pretty', 'false', '--inlineSources'];\n // tsc rejects --sourceMap alongside a project's inlineSourceMap; only force it otherwise.\n if (!(await this.usesInlineSourceMap(projectDir, tsconfigPath))) args.push('--sourceMap');\n\n const result = await this.runNodeScript(projectDir, tscPath, args);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `TypeScript compilation failed:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private async usesInlineSourceMap(projectDir: string, tsconfigPath: string): Promise<boolean> {\n const tscPath = this.resolveProjectTsc(projectDir);\n const result = await this.runNodeScript(projectDir, tscPath, ['--showConfig', '-p', tsconfigPath]);\n if (result.exitCode !== 0) return false;\n\n try {\n const config = JSON.parse(result.output) as { compilerOptions?: { inlineSourceMap?: boolean } };\n return config.compilerOptions?.inlineSourceMap === true;\n } catch {\n return false;\n }\n }\n\n private async fixRelativeSpecifiers(outDir: string): Promise<void> {\n const fixPath = this.resolveFixEsmImportPath();\n\n const result = await this.runNodeScript(process.cwd(), fixPath, [outDir]);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Failed to fix relative import specifiers:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private resolveProjectTsc(projectDir: string): string {\n const projectRequire = this.createProjectRequire(projectDir);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown resolution error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Unable to resolve typescript. Ensure it is installed in this project.\\n${reason}`\n ]);\n }\n }\n\n private resolveFixEsmImportPath(): string {\n const selfRequire = createNodeRequire(import.meta.url);\n\n try {\n return selfRequire.resolve('fix-esm-import-path/fix-esm-import-path.js');\n } catch {\n return selfRequire.resolve('fix-esm-import-path');\n }\n }\n\n private createProjectRequire(projectDir: string): NodeRequire {\n const candidate = resolve(projectDir, 'package.json');\n if (existsSync(candidate)) return createNodeRequire(candidate);\n\n return createNodeRequire(import.meta.url);\n }\n\n private async runNodeScript(cwd: string, scriptPath: string, args: string[]): Promise<ProcessResult> {\n return await this.runProcess(process.execPath, [scriptPath, ...args], cwd);\n }\n\n private runProcess(cmd: string, args: string[], cwd: string): Promise<ProcessResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });\n\n let output = '';\n\n child.stdout.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.stderr.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.on('error', rejectPromise);\n\n child.on('close', (code) => {\n resolvePromise({ exitCode: code ?? 1, output });\n });\n });\n }\n\n private truncateOutput(text: string, maxChars = 24_000): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}\\n...output truncated...`;\n }\n\n private resolveTsconfig(config: ResolvedSeedcordDevConfig): string {\n if (config.build.tsconfig) {\n if (!existsSync(config.build.tsconfig)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [config.build.tsconfig]);\n }\n\n return config.build.tsconfig;\n }\n\n const configDir = dirname(config.configFile);\n const candidates = ['tsconfig.build.json', 'tsconfig.json']\n .map((file) => resolve(configDir, file))\n .filter((candidate) => existsSync(candidate));\n\n const [firstCandidate] = candidates;\n if (firstCandidate) return firstCandidate;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [configDir]);\n }\n\n private resolveEmittedEntry(config: ResolvedSeedcordDevConfig): string {\n const relFromRoot = relative(config.root, config.entry);\n const relNoExt = relFromRoot.slice(0, relFromRoot.length - extname(relFromRoot).length);\n\n const basePath = resolve(config.build.outDir, relNoExt);\n const candidateExts = ['.js', '.mjs', '.cjs'];\n\n for (const ext of candidateExts) {\n const candidate = `${basePath}${ext}`;\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback if no emitted file was found\n return `${basePath}.js`;\n }\n}\n","import { existsSync } from 'node:fs';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { ConfigLoader } from '@core/config/ConfigLoader';\nimport { ConfigLocator } from '@core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '@core/modules/RuntimeModuleLoader';\n\nimport { BootstrapWriter } from './builder/BootstrapWriter';\nimport { TypeScriptProjectBuilder } from './builder/TypeScriptProjectBuilder';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BuildRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly builder: TypeScriptProjectBuilder,\n private readonly bootstrapWriter: BootstrapWriter,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): BuildRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const builder = new TypeScriptProjectBuilder(logger);\n const bootstrapWriter = new BootstrapWriter(logger);\n\n return new BuildRunner(locator, configLoader, builder, bootstrapWriter, logger);\n }\n\n public async run(): Promise<void> {\n const config = await this.loadConfig();\n this.assertEntryExists(config.entry);\n const { emittedEntry } = await this.builder.build(config);\n await this.bootstrapWriter.write(config, emittedEntry);\n this.logger.info('Seedcord build finished successfully.');\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n\n private assertEntryExists(entryPath: string): void {\n if (!existsSync(entryPath)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [entryPath]);\n }\n }\n}\n","import { isSeedcordError } from '@seedcord/services';\n\nimport { BaseCommand } from '@core/BaseCommand';\n\nimport { BuildRunner } from './BuildRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class BuildCommand extends BaseCommand {\n private readonly runner: BuildRunner;\n\n constructor() {\n super('build', 'Compile a Seedcord project from the config file', 'CLI:Build');\n this.runner = BuildRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n try {\n await this.runner.run();\n } catch (error: unknown) {\n this.logger.error('Seedcord build failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","import { useCallback, useSyncExternalStore } from 'react';\n\nimport type { DevState, DevStore } from '@ui/stores/DevStore';\n\nexport function useDevState(store: DevStore): DevState {\n const subscribe = useCallback(\n (onChange: () => void) => {\n store.on('change', onChange);\n return () => {\n store.off('change', onChange);\n };\n },\n [store]\n );\n const getSnapshot = useCallback(() => store.getState(), [store]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { LoggerChannelRegistry, StrictEventEmitter } from '@seedcord/services';\n\nimport type { ILoggerSink, ILoggerSinkHandle, LoggerSinkLogEntry } from '@seedcord/services';\n\nexport interface LogEntry {\n id: number;\n channel: string;\n text: string;\n timestamp: number;\n}\n\ninterface LogStoreEvents {\n change: [];\n}\n\n// Buffered log batches flush on this debounce so a noisy bot doesn't re-render the log view per line.\nconst UPDATE_DEBOUNCE_MS = 30;\n\n// eslint-disable-next-line no-magic-numbers -- 27 is the ESC control code\nconst ESC = String.fromCharCode(27);\n\nexport class LogStore extends StrictEventEmitter<LogStoreEvents> implements ILoggerSink {\n private static _instance: LogStore | null = null;\n\n private entries: LogEntry[] = [];\n private buffer: LogEntry[] = [];\n private nextId = 1;\n private sinkHandle: ILoggerSinkHandle | null = null;\n private pendingUpdate = false;\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly MAX_LOGS = 1000;\n\n private constructor() {\n super();\n }\n\n public static get instance(): LogStore {\n LogStore._instance ??= new LogStore();\n return LogStore._instance;\n }\n\n public mount(): void {\n if (this.sinkHandle) return;\n this.sinkHandle = LoggerChannelRegistry.instance.installSink(this, {\n muteConsole: true\n });\n }\n\n public unmount(): void {\n if (!this.sinkHandle) return;\n this.sinkHandle.dispose();\n this.sinkHandle = null;\n }\n\n public onLog(entry: LoggerSinkLogEntry): void {\n // Split on a lone \\r too: a bare carriage return left in a row resets the terminal cursor to column 0\n // on print and overwrites the start of the line. Then drop any other control char (keeping ESC so SGR\n // color sequences still render) for the same corruption reason.\n const lines = entry.rendered.split(/\\r\\n|\\r|\\n/);\n const now = Date.now();\n\n for (const line of lines) {\n this.buffer.push({\n id: this.nextId++,\n channel: entry.channel,\n text: line.replace(/\\p{Cc}/gu, (char) => (char === ESC ? char : '')),\n timestamp: now\n });\n }\n\n this.scheduleUpdate();\n }\n\n // Stays a stable reference for useSyncExternalStore; channel filtering happens in useLogs.\n public getLogs(): readonly LogEntry[] {\n return this.entries;\n }\n\n // Source channels from real log entries, not the registry, so the toggle list never shows an empty\n // \"default\" placeholder.\n public getChannels(): readonly string[] {\n const seen = new Set<string>();\n for (const entry of this.entries) seen.add(entry.channel);\n return [...seen].sort();\n }\n\n public clear(): void {\n this.entries = [];\n this.buffer = [];\n this.emit('change');\n }\n\n // Drain buffered logs immediately and yield once so Ink paints the final lines before a quit unmounts the UI.\n public async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.applyBuffer();\n await new Promise<void>((resolve) => setImmediate(resolve));\n }\n\n private scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.flushTimer = setTimeout(() => this.applyBuffer(), UPDATE_DEBOUNCE_MS);\n }\n\n private applyBuffer(): void {\n this.flushTimer = null;\n this.pendingUpdate = false;\n if (this.buffer.length === 0) return;\n\n const newEntries = [...this.entries, ...this.buffer];\n this.buffer = [];\n this.entries = newEntries.length > this.MAX_LOGS ? newEntries.slice(-this.MAX_LOGS) : newEntries;\n\n this.emit('change');\n }\n}\n","import { useCallback, useMemo, useSyncExternalStore } from 'react';\n\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { LogEntry } from '@ui/stores/LogStore';\n\n// `enabled` must be a stable reference between unchanged renders (the shell holds it in state), or the memo\n// recomputes every render. An empty/absent set means all channels.\nexport function useLogs(enabled?: ReadonlySet<string>): readonly LogEntry[] {\n const store = LogStore.instance;\n\n const subscribe = useCallback(\n (cb: () => void) => {\n store.on('change', cb);\n return () => {\n store.off('change', cb);\n };\n },\n [store]\n );\n\n const getSnapshot = useCallback(() => store.getLogs(), [store]);\n\n const allLogs = useSyncExternalStore(subscribe, getSnapshot);\n\n return useMemo(() => {\n if (!enabled || enabled.size === 0) return allLogs;\n return allLogs.filter((l) => enabled.has(l.channel));\n }, [allLogs, enabled]);\n}\n","import { useState } from 'react';\n\nexport interface ScrollApi<Item> {\n // Oldest-first; consumers render in array order.\n readonly visible: readonly Item[];\n readonly following: boolean;\n readonly atTop: boolean;\n // Count of hidden entries above (older) and below (newer) the current window.\n readonly above: number;\n readonly below: number;\n readonly up: (lines?: number) => void;\n readonly down: (lines?: number) => void;\n readonly pageUp: () => void;\n readonly pageDown: () => void;\n readonly toTop: () => void;\n readonly toBottom: () => void;\n}\n\ntype ScrollKey = number | string;\n\ninterface ScrollView<Item> {\n readonly visible: readonly Item[];\n readonly topIndex: number;\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n}\n\n// Pure, side-effect free (exported for unit tests). A null anchor follows the tail (newest). A non-null\n// anchor pins the window's top to that entry's CURRENT index, so the visible lines stay put when the buffer\n// trims its head or new lines append while scrolled up; if the anchored entry was trimmed away, it falls\n// back to the oldest line.\nexport function computeScrollView<Item>(\n items: readonly Item[],\n viewportHeight: number,\n anchor: ScrollKey | null,\n getKey: (item: Item) => ScrollKey\n): ScrollView<Item> {\n const height = Math.max(1, viewportHeight);\n const len = items.length;\n const maxTop = Math.max(0, len - height);\n\n let topIndex: number;\n if (anchor === null) {\n topIndex = maxTop;\n } else {\n const found = items.findIndex((item) => getKey(item) === anchor);\n topIndex = found === -1 ? 0 : found;\n }\n topIndex = Math.min(Math.max(0, topIndex), maxTop);\n\n const visible = items.slice(topIndex, topIndex + height);\n return {\n visible,\n topIndex,\n following: anchor === null || topIndex >= maxTop,\n atTop: topIndex === 0,\n above: topIndex,\n below: len - (topIndex + visible.length)\n };\n}\n\n// A virtualized scroll window over an append-mostly list, anchored to an entry KEY (see computeScrollView).\nexport function useScroll<Item>(\n items: readonly Item[],\n viewportHeight: number,\n getKey: (item: Item) => ScrollKey\n): ScrollApi<Item> {\n const [anchor, setAnchor] = useState<ScrollKey | null>(null);\n\n const height = Math.max(1, viewportHeight);\n const maxTop = Math.max(0, items.length - height);\n const view = computeScrollView(items, viewportHeight, anchor, getKey);\n\n // Reaching the tail clears the anchor (back to follow mode) so new lines auto-show again.\n const anchorAt = (nextTop: number): void => {\n const clamped = Math.min(Math.max(0, nextTop), maxTop);\n if (clamped >= maxTop) {\n setAnchor(null);\n return;\n }\n const entry = items[clamped];\n setAnchor(entry === undefined ? null : getKey(entry));\n };\n\n const up = (lines = 1): void => anchorAt(view.topIndex - lines);\n const down = (lines = 1): void => anchorAt(view.topIndex + lines);\n\n return {\n visible: view.visible,\n following: view.following,\n atTop: view.atTop,\n above: view.above,\n below: view.below,\n up,\n down,\n pageUp: () => up(height - 1),\n pageDown: () => down(height - 1),\n toTop: () => {\n const oldest = items[0];\n setAnchor(oldest === undefined ? null : getKey(oldest));\n },\n toBottom: () => setAnchor(null)\n };\n}\n","import type { TextProps } from 'ink';\n\nexport type DevPhase = 'starting' | 'running' | 'restart-required' | 'disconnected' | 'error' | 'quitting';\n\n// Disconnect only applies while a bot session is actually running; the other phases have nothing to stop.\nexport function isSessionLive(phase: DevPhase): boolean {\n return phase === 'running' || phase === 'restart-required';\n}\n\n// Phases where the process is up and emitting logs (in restart-required it is up but stale), so the live\n// dot blinks. disconnected, error, and quitting produce no logs and read as idle.\nexport function isStreaming(phase: DevPhase): boolean {\n return phase === 'starting' || phase === 'running' || phase === 'restart-required';\n}\n\n// How the status glyph animates: a one-shot spinner for transient phases, a steady looping arc while the\n// session is live, or a static icon for resting states.\ntype PhaseGlyph = 'spinner' | 'arc' | 'static';\n\nexport interface PhaseMeta {\n readonly label: string;\n readonly icon: string;\n readonly color: TextProps['color'];\n readonly kind: PhaseGlyph;\n}\n\n// Single source for the status-badge presentation. `satisfies` keeps each entry's literal types while\n// enforcing one entry per DevPhase, so adding a phase is a compile error until its meta is filled in.\nexport const PHASE_META = {\n starting: { label: 'starting', icon: '◐', color: 'cyan', kind: 'spinner' },\n running: { label: 'running', icon: '●', color: 'green', kind: 'arc' },\n 'restart-required': { label: 'restart required', icon: '◆', color: 'yellow', kind: 'static' },\n disconnected: { label: 'offline', icon: '○', color: 'gray', kind: 'static' },\n error: { label: 'error', icon: '✖', color: 'red', kind: 'static' },\n quitting: { label: 'quitting', icon: '◐', color: 'magenta', kind: 'spinner' }\n} as const satisfies Record<DevPhase, PhaseMeta>;\n","import { useAnimation } from 'ink';\n\nimport { isSessionLive } from '@ui/stores/devPhase';\n\nimport type { DevState } from '@ui/stores/DevStore';\n\nconst TICK_MS = 1000;\n\n// Elapsed ms while a session is live (running or restart-required), else null. useAnimation's `time` counts\n// real elapsed ms and resets to 0 when reactivated, so it restarts on each fresh run and keeps counting\n// across restart-required. No stored timestamp, manual timer, or Date.now()-in-render needed.\nexport function useUptime(state: DevState): number | null {\n const active = isSessionLive(state.phase);\n const { time } = useAnimation({ interval: TICK_MS, isActive: active });\n return active ? time : null;\n}\n","import { isSessionLive } from '@ui/stores/devPhase';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { ScrollApi } from '@ui/hooks/useScroll';\nimport type { DevState, DevStore } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { Key } from 'ink';\n\n// Toggling a channel materializes the full list on first use, then flips one entry. When the result is \"all\n// on\" again it collapses back to an empty set so channels that appear later stay visible by default.\nfunction toggleChannel(prev: ReadonlySet<string>, channel: string, all: readonly string[]): ReadonlySet<string> {\n const base = prev.size === 0 ? new Set(all) : new Set(prev);\n if (base.has(channel)) base.delete(channel);\n else base.add(channel);\n return base.size === all.length ? new Set<string>() : base;\n}\n\ninterface HotkeyContext {\n readonly input: string;\n readonly key: Key;\n readonly state: DevState;\n readonly interactive: boolean;\n readonly scroll: ScrollApi<LogEntry>;\n readonly store: DevStore;\n readonly enabled: ReadonlySet<string>;\n readonly setEnabled: (next: ReadonlySet<string>) => void;\n readonly showToggles: boolean;\n readonly setShowToggles: (next: boolean) => void;\n readonly cursor: number;\n readonly setCursor: (next: number) => void;\n readonly onQuit?: (() => Promise<void> | void) | undefined;\n readonly onDisconnect?: (() => Promise<void> | void) | undefined;\n readonly onRestart?: (() => Promise<void> | void) | undefined;\n readonly onRefreshCommands?: ((shouldRefresh: boolean) => Promise<void> | void) | undefined;\n}\n\nfunction quit(ctx: HotkeyContext): void {\n ctx.store.beginQuit();\n void ctx.onQuit?.();\n}\n\n// Ink puts stdin in raw mode, so Ctrl-C arrives as a keypress, not a SIGINT; handle it first so it always quits.\nfunction handleQuitSignal(ctx: HotkeyContext): boolean {\n if (ctx.key.ctrl && ctx.input === 'c') {\n quit(ctx);\n return true;\n }\n return false;\n}\n\nfunction handlePrompt(ctx: HotkeyContext): boolean {\n if (!ctx.state.commandUpdatePrompt) return false;\n if (ctx.input === 'y') {\n void ctx.onRefreshCommands?.(true);\n ctx.store.clearPrompt();\n } else if (ctx.input === 'n') {\n void ctx.onRefreshCommands?.(false);\n ctx.store.clearPrompt();\n }\n return true;\n}\n\nfunction handleToggleMode(ctx: HotkeyContext): boolean {\n if (!ctx.showToggles) return false;\n const channels = LogStore.instance.getChannels();\n\n if (ctx.key.escape || ctx.input === 'c') {\n ctx.setShowToggles(false);\n } else if (ctx.key.upArrow && channels.length > 0) {\n ctx.setCursor((ctx.cursor + channels.length - 1) % channels.length);\n } else if (ctx.key.downArrow && channels.length > 0) {\n ctx.setCursor((ctx.cursor + 1) % channels.length);\n } else if (ctx.input === ' ' || ctx.key.return) {\n const channel = channels[ctx.cursor];\n if (channel !== undefined) ctx.setEnabled(toggleChannel(ctx.enabled, channel, channels));\n }\n return true;\n}\n\nfunction handleScroll(ctx: HotkeyContext): boolean {\n // Runs before session actions, so scroll capture is unconditional (works even when non-interactive). t/b\n // mirror Home/End for keyboards lacking them, and like the arrows are reserved here, a future single-letter\n // action must avoid t and b.\n const { key, input, scroll } = ctx;\n if (key.upArrow) scroll.up();\n else if (key.downArrow) scroll.down();\n else if (key.pageUp) scroll.pageUp();\n else if (key.pageDown) scroll.pageDown();\n else if (key.home || input === 't') scroll.toTop();\n else if (key.end || input === 'b') scroll.toBottom();\n else return false;\n return true;\n}\n\n// Session controls. `q` quits in any state; the rest only apply once the UI is interactive.\nfunction handleActions(ctx: HotkeyContext): void {\n const { input, state, store } = ctx;\n\n if (input === 'q') {\n quit(ctx);\n return;\n }\n if (!ctx.interactive) return;\n\n if (input === 'd') {\n if (!isSessionLive(state.phase)) return;\n store.beginDisconnect();\n void ctx.onDisconnect?.();\n } else if (input === 'r') {\n store.beginRestart();\n void ctx.onRestart?.();\n } else if (input === 'c') {\n ctx.setCursor(0);\n ctx.setShowToggles(true);\n } else if (input === 'l') {\n LogStore.instance.clear();\n ctx.scroll.toBottom();\n }\n}\n\n// Single keyboard dispatcher for the dev UI: a keypress runs through these in order and stops at the first\n// that handles it, the quit signal, then the prompt and toggle modes (which capture all input while open),\n// then scroll, then session controls.\nexport function dispatchHotkey(ctx: HotkeyContext): void {\n if (handleQuitSignal(ctx)) return;\n if (handlePrompt(ctx)) return;\n if (handleToggleMode(ctx)) return;\n if (handleScroll(ctx)) return;\n handleActions(ctx);\n}\n","import { Box, Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nconst BLINK_MS = 530;\n\nfunction LiveDot(): ReactElement {\n // Blink the dot via the animation frame; a steady width (dot or space) keeps \"live\" from shifting.\n const { frame } = useAnimation({ interval: BLINK_MS });\n return (\n <Text>\n <Text color=\"red\">{frame % 2 === 0 ? '●' : ' '}</Text>\n <Text dimColor> live</Text>\n </Text>\n );\n}\n\ninterface LogHeaderProps {\n readonly following: boolean;\n readonly below: number;\n // True only while the session streams; the dot stops blinking once the session stops or crashes.\n readonly live: boolean;\n}\n\n// Sits above the logs: a blinking live dot while tailing a streaming session, a static idle marker once the\n// session stops or crashes, or the scroll status once scrolled away.\nexport function LogHeader({ following, below, live }: LogHeaderProps): ReactElement {\n if (!following) {\n return (\n <Box flexShrink={0}>\n <Text color=\"yellow\" wrap=\"truncate\">{`▲ scrolled · ${below} newer below · b to follow`}</Text>\n </Box>\n );\n }\n\n return <Box flexShrink={0}>{live ? <LiveDot /> : <Text dimColor>○ idle</Text>}</Box>;\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\ninterface CommandRefreshPromptProps {\n files: string[];\n}\n\nexport function CommandRefreshPrompt({ files }: CommandRefreshPromptProps): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor=\"yellow\" flexDirection=\"column\" paddingX={1}>\n <Text>\n <Text color=\"yellow\" bold>\n Commands updated:\n </Text>\n </Text>\n {files.map((file) => (\n <Text key={file} color=\"cyan\">\n - {file}\n </Text>\n ))}\n <Text>Refresh commands? (y/n)</Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nconst STACK_PREVIEW_LINES = 6;\n\ninterface ErrorDisplayProps {\n readonly error: Error;\n}\n\nexport function ErrorDisplay({ error }: ErrorDisplayProps): ReactElement {\n // stack[0] repeats \"Error: message\" which we already render, so preview the frames below it.\n const frames = (error.stack?.split('\\n') ?? []).slice(1);\n const preview = frames.slice(0, STACK_PREVIEW_LINES);\n const hidden = frames.length - preview.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"red\" padding={1}>\n <Box marginTop={-1}>\n <Text color=\"red\" bold>\n Error: {error.name}\n </Text>\n </Box>\n <Text>{error.message}</Text>\n {preview.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {preview.map((line) => (\n <Text key={line} dimColor wrap=\"truncate\">\n {line}\n </Text>\n ))}\n {hidden > 0 && <Text dimColor>{`… ${hidden} more line${hidden === 1 ? '' : 's'}`}</Text>}\n </Box>\n )}\n <Box marginTop={1}>\n <Text>\n press{' '}\n <Text color=\"yellow\" bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nexport function RestartRequiredCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor=\"yellow\" flexDirection=\"column\" paddingX={1}>\n <Text color=\"yellow\" bold>\n Restart required\n </Text>\n <Text>\n A change needs a full restart. press{' '}\n <Text color=\"yellow\" bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { CommandRefreshPrompt } from '../CommandRefreshPrompt';\nimport { ErrorDisplay } from '../ErrorDisplay';\nimport { RestartRequiredCard } from '../RestartRequiredCard';\n\nimport type { ReactElement } from 'react';\n\ninterface NotificationStackProps {\n readonly error: Error | null;\n readonly restartRequired: boolean;\n readonly prompt: readonly string[] | null;\n}\n\n// Notification cards docked below the logs. Renders nothing when idle, so it adds no rows.\nexport function NotificationStack({ error, restartRequired, prompt }: NotificationStackProps): ReactElement | null {\n if (!error && !restartRequired && !prompt) return null;\n\n return (\n <Box flexShrink={0} flexDirection=\"column\">\n {error ? <ErrorDisplay error={error} /> : null}\n {restartRequired ? <RestartRequiredCard /> : null}\n {prompt ? <CommandRefreshPrompt files={[...prompt]} /> : null}\n </Box>\n );\n}\n","// Stable, distinct color per channel so a line's channel tag and its toggle entry always match. Red is\n// reserved for errors and the live dot, so it is left out of the palette.\nconst PALETTE = ['cyan', 'green', 'yellow', 'magenta', 'blue', 'cyanBright'] as const;\n\ntype ChannelColor = (typeof PALETTE)[number];\n\nexport function channelColor(channel: string): ChannelColor {\n // Cheap order-insensitive sum; collisions are purely cosmetic across the handful of dev channels.\n let hash = 0;\n for (const char of channel) hash = (hash + char.charCodeAt(0)) % PALETTE.length;\n return PALETTE[hash] ?? PALETTE[0];\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '@ui/channelColor';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { ReactElement } from 'react';\n\nconst MIN_LOG_LINES = 3;\nconst MAX_TAG = 10;\n\ninterface ScrollableLogViewProps {\n readonly visible: readonly LogEntry[];\n readonly viewportHeight: number;\n // False until the parent box has been measured; avoids a one-frame \"too small\" flash on mount.\n readonly measured: boolean;\n}\n\nexport function ScrollableLogView({ visible, viewportHeight, measured }: ScrollableLogViewProps): ReactElement | null {\n if (!measured) return null;\n\n if (viewportHeight < MIN_LOG_LINES) {\n return (\n <Text color=\"yellow\" wrap=\"truncate\">\n Terminal too small to show logs.\n </Text>\n );\n }\n\n // Pad channel tags to a common width so messages line up; cap the width so a long channel name is\n // truncated rather than the message.\n const channels = LogStore.instance.getChannels();\n const tagWidth = Math.min(\n MAX_TAG,\n channels.reduce((max, channel) => Math.max(max, channel.length), 0)\n );\n\n return (\n // flex-end pins the newest line to the bottom edge (tail -f): the window grows upward, and when the\n // buffer is sparse the lines sit at the bottom instead of the middle.\n <Box flexDirection=\"column\" flexGrow={1} justifyContent=\"flex-end\" overflow=\"hidden\">\n {visible.length === 0 ? (\n <Text dimColor>Waiting for logs…</Text>\n ) : (\n visible.map((log) => (\n <Text key={log.id} wrap=\"truncate\">\n <Text color={channelColor(log.channel)}>{log.channel.slice(0, tagWidth).padEnd(tagWidth)}</Text>{' '}\n {log.text}\n </Text>\n ))\n )}\n </Box>\n );\n}\n","const MS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\n\nfunction pad(value: number): string {\n return value.toString().padStart(2, '0');\n}\n\n// Drops empty leading units: 12s, 3m 12s, 1h 02m 03s.\nexport function formatUptime(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / MS_PER_SECOND));\n const seconds = totalSeconds % SECONDS_PER_MINUTE;\n const totalMinutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);\n const minutes = totalMinutes % MINUTES_PER_HOUR;\n const hours = Math.floor(totalMinutes / MINUTES_PER_HOUR);\n\n if (hours > 0) return `${hours}h ${pad(minutes)}m ${pad(seconds)}s`;\n if (minutes > 0) return `${minutes}m ${pad(seconds)}s`;\n return `${seconds}s`;\n}\n","import { formatFilePath } from '@seedcord/utils';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { Config } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nconst SEED_COLOR = '#f04e36';\nconst CORD_COLOR = '#6fab49';\n\ninterface BannerProps {\n readonly config: Config | null;\n // Drops the config paths; Sidebar sets this when the rail is too short for them.\n readonly compact?: boolean;\n}\n\nfunction ConfigPath({ path }: { path: string | null | undefined }): ReactElement {\n if (!path) return <Text color=\"gray\">Disabled</Text>;\n return <Text dimColor>{formatFilePath(path)}</Text>;\n}\n\nfunction Wordmark(): ReactElement {\n return (\n <Text bold>\n <Text color={SEED_COLOR}>seed</Text>\n <Text color={CORD_COLOR}>cord</Text>\n </Text>\n );\n}\n\nexport function Banner({ config, compact = false }: BannerProps): ReactElement {\n if (compact || !config) return <Wordmark />;\n\n return (\n <Box flexDirection=\"column\">\n <Wordmark />\n <Box flexDirection=\"column\" paddingTop={1}>\n <Text wrap=\"truncate\">\n <Text color=\"blue\">➜</Text> Interactions: <ConfigPath path={config.bot.interactions.path} />\n </Text>\n <Text wrap=\"truncate\">\n <Text color=\"blue\">➜</Text> Events: <ConfigPath path={config.bot.events.path} />\n </Text>\n <Text wrap=\"truncate\">\n <Text color=\"blue\">➜</Text> Pub/Sub: <ConfigPath path={config.subscribers.path} />\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport type { TextProps } from 'ink';\nimport type { ReactElement } from 'react';\n\n// A slow rotating arc, distinct from ink-spinner's startup `balloon2`, so the running state looks different\n// from the startup spinner.\nconst FRAMES = ['◜', '◠', '◝', '◞', '◡', '◟'] as const;\nconst FRAME_MS = 120;\nconst STATIC_GLYPH = '●';\n\ninterface RunningAnimationProps {\n readonly active: boolean;\n readonly color?: TextProps['color'];\n}\n\nexport function RunningAnimation({ active, color }: RunningAnimationProps): ReactElement {\n const { frame } = useAnimation({ interval: FRAME_MS, isActive: active });\n const glyph = active ? FRAMES[frame % FRAMES.length] : STATIC_GLYPH;\n return color === undefined ? <Text>{glyph}</Text> : <Text color={color}>{glyph}</Text>;\n}\n","import { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { PHASE_META } from '@ui/stores/devPhase';\n\nimport { RunningAnimation } from './primitives/RunningAnimation';\n\nimport type { DevPhase } from '@ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface StatusBadgeProps {\n readonly phase: DevPhase;\n}\n\nfunction Glyph({ phase }: { phase: DevPhase }): ReactElement {\n const meta = PHASE_META[phase];\n if (meta.kind === 'spinner') return <Spinner type=\"balloon2\" />;\n if (meta.kind === 'arc') return <RunningAnimation active color={meta.color} />;\n return <Text>{meta.icon}</Text>;\n}\n\nexport function StatusBadge({ phase }: StatusBadgeProps): ReactElement {\n const meta = PHASE_META[phase];\n return (\n <Text color={meta.color} bold>\n <Glyph phase={phase} /> {meta.label}\n </Text>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '@ui/channelColor';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { ReactElement } from 'react';\n\ninterface ChannelTogglesProps {\n // Empty set means every channel is on, so channels that appear later default to visible.\n readonly enabled: ReadonlySet<string>;\n // Index of the focused row while in toggle mode, or null when the list is read-only.\n readonly cursor: number | null;\n}\n\nexport function ChannelToggles({ enabled, cursor }: ChannelTogglesProps): ReactElement {\n // Re-read each render; the tree re-renders on every log batch, so no memo is needed.\n const channels = LogStore.instance.getChannels();\n\n if (channels.length === 0) {\n return <Text dimColor>no logs yet</Text>;\n }\n\n return (\n <Box flexDirection=\"column\">\n {channels.map((channel, index) => {\n const on = enabled.size === 0 || enabled.has(channel);\n const focused = cursor === index;\n // Match the per-line log tag color when on, so the toggle and its log lines visually pair up.\n const color = focused ? 'cyan' : on ? channelColor(channel) : 'gray';\n return (\n <Text key={channel} color={color} wrap=\"truncate\">\n {focused ? '❯ ' : ' '}\n {on ? '●' : '○'} {channel}\n </Text>\n );\n })}\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { isSessionLive } from '@ui/stores/devPhase';\n\nimport type { DevPhase } from '@ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ntype HotkeyBarMode = 'default' | 'toggles';\n\ninterface HotkeyBarProps {\n readonly phase: DevPhase;\n readonly interactive: boolean;\n readonly mode: HotkeyBarMode;\n readonly following: boolean;\n}\n\ninterface HotkeyProps {\n readonly keyLabel: string;\n readonly action: string;\n readonly enabled?: boolean;\n readonly highlight?: boolean;\n}\n\nfunction Hotkey({ keyLabel, action, enabled = true, highlight = false }: HotkeyProps): ReactElement {\n const keyColor = !enabled ? 'gray' : highlight ? 'yellow' : 'cyan';\n return (\n <Box marginRight={2}>\n <Text color={keyColor} bold>\n {keyLabel}\n </Text>\n <Text dimColor> {action}</Text>\n </Box>\n );\n}\n\n// Highlight r in the phases the user recovers from with a restart.\nconst RESTART_HINT_PHASES = new Set<DevPhase>(['restart-required', 'disconnected', 'error']);\n\nfunction DefaultKeys({\n phase,\n interactive,\n following\n}: {\n phase: DevPhase;\n interactive: boolean;\n following: boolean;\n}): ReactElement {\n return (\n <>\n <Hotkey keyLabel=\"q\" action=\"quit\" />\n <Hotkey keyLabel=\"r\" action=\"restart\" enabled={interactive} highlight={RESTART_HINT_PHASES.has(phase)} />\n <Hotkey keyLabel=\"d\" action=\"disconnect\" enabled={interactive && isSessionLive(phase)} />\n <Hotkey keyLabel=\"c\" action=\"channels\" enabled={interactive} />\n <Hotkey keyLabel=\"l\" action=\"clear\" enabled={interactive} />\n <Hotkey keyLabel=\"↑↓\" action=\"scroll\" />\n <Hotkey keyLabel=\"t/b\" action=\"top/bottom\" highlight={!following} />\n </>\n );\n}\n\nexport function HotkeyBar({ phase, interactive, mode, following }: HotkeyBarProps): ReactElement {\n return (\n <Box flexDirection=\"column\" flexWrap=\"wrap\">\n {mode === 'toggles' && (\n <>\n <Hotkey keyLabel=\"↑↓\" action=\"move\" />\n <Hotkey keyLabel=\"space\" action=\"toggle\" />\n <Hotkey keyLabel=\"esc\" action=\"done\" />\n </>\n )}\n {mode === 'default' && <DefaultKeys phase={phase} interactive={interactive} following={following} />}\n </Box>\n );\n}\n","import { LoggerChannelRegistry } from '@seedcord/services';\nimport { formatFilePath } from '@seedcord/utils';\nimport { Box, Text, useWindowSize } from 'ink';\nimport React from 'react';\n\nimport { formatUptime } from '@ui/format';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\nimport { ChannelToggles } from './ChannelToggles';\nimport { HotkeyBar } from './HotkeyBar';\n\nimport type { DevState } from '@ui/stores/DevStore';\nimport type { ReactElement } from 'react';\n\n// Below this many terminal rows the rail drops the config paths so the rest still fits.\nconst COMPACT_ROWS = 26;\n\n// Pads the metadata labels so their values line up into a column.\nconst META_LABEL_WIDTH = 5;\n\n// Every channel writes its own per-run file into this directory, so show the directory, not one file.\nfunction logDir(): string | null {\n const registry = LoggerChannelRegistry.instance;\n const path = registry.getLogFilePath(registry.getDefaultChannel());\n return path ? formatFilePath(path, { onlyDir: true }) : null;\n}\n\ninterface SidebarProps {\n readonly state: DevState;\n readonly enabled: ReadonlySet<string>;\n readonly uptimeMs: number | null;\n readonly following: boolean;\n readonly interactive: boolean;\n readonly showToggles: boolean;\n readonly cursor: number;\n readonly width: number;\n}\n\nfunction Meta({ label, value }: { label: string; value: string }): ReactElement {\n return (\n <Text wrap=\"truncate\">\n <Text dimColor>{label.padEnd(META_LABEL_WIDTH)}</Text>\n {value}\n </Text>\n );\n}\n\nfunction StatusBlock({ state, uptimeMs }: { state: DevState; uptimeMs: number | null }): ReactElement {\n const dir = logDir();\n return (\n <Box flexDirection=\"column\">\n <StatusBadge phase={state.phase} />\n {state.status ? <Text wrap=\"truncate\">{state.status}</Text> : null}\n {uptimeMs === null ? null : <Meta label=\"up\" value={formatUptime(uptimeMs)} />}\n {dir === null ? null : <Meta label=\"logs\" value={dir} />}\n </Box>\n );\n}\n\n// The left rail: banner, status, channel filter, and hotkeys, stacked from the top alongside the logs.\n// flexShrink={0} on every section keeps each at its natural height, so a short terminal clips from the\n// bottom instead of overlapping rows.\nexport function Sidebar({\n state,\n enabled,\n uptimeMs,\n following,\n interactive,\n showToggles,\n cursor,\n width\n}: SidebarProps): ReactElement {\n const { rows } = useWindowSize();\n const compact = rows < COMPACT_ROWS;\n\n return (\n <Box flexDirection=\"column\" width={width} paddingX={1} overflow=\"hidden\">\n <Box flexShrink={0}>\n <Banner config={state.config} compact={compact} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <StatusBlock state={state} uptimeMs={uptimeMs} />\n </Box>\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <Text bold color=\"blueBright\">\n channels\n </Text>\n <ChannelToggles enabled={enabled} cursor={showToggles ? cursor : null} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <HotkeyBar\n phase={state.phase}\n interactive={interactive}\n mode={showToggles ? 'toggles' : 'default'}\n following={following}\n />\n </Box>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { LogHeader } from '@ui/components/primitives/LogHeader';\nimport { NotificationStack } from '@ui/components/primitives/NotificationStack';\nimport { ScrollableLogView } from '@ui/components/primitives/ScrollableLogView';\nimport { Sidebar } from '@ui/components/primitives/Sidebar';\nimport { isStreaming } from '@ui/stores/devPhase';\n\nimport type { ScrollApi } from '@ui/hooks/useScroll';\nimport type { DevState } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nconst MAX_RAIL = 40;\nconst MIN_RAIL = 26;\nconst RAIL_FRACTION = 0.32;\n\nexport interface DevLayoutProps {\n readonly state: DevState;\n readonly columns: number;\n // The shell measures this box to size the scroll window; it must be attached or the viewport is empty.\n readonly logBoxRef: Ref<DOMElement>;\n readonly scroll: ScrollApi<LogEntry>;\n readonly viewportHeight: number;\n readonly measured: boolean;\n readonly enabled: ReadonlySet<string>;\n readonly showToggles: boolean;\n readonly cursor: number;\n readonly interactive: boolean;\n readonly uptimeMs: number | null;\n}\n\n// Left rail (banner, status, channel filter, hotkeys) and a wide right column for logs, separated by a\n// vertical divider. The log column shows its live/scroll status on top, then the scrolling logs, then\n// notification cards docked beneath where there's room for stack traces.\nexport function DevLayout(props: DevLayoutProps): ReactElement {\n const { state, columns, logBoxRef, scroll, viewportHeight, measured } = props;\n const { enabled, showToggles, cursor, interactive, uptimeMs } = props;\n const railWidth = Math.min(MAX_RAIL, Math.max(MIN_RAIL, Math.floor(columns * RAIL_FRACTION)));\n\n return (\n <Box flexGrow={1}>\n <Sidebar\n state={state}\n enabled={enabled}\n uptimeMs={uptimeMs}\n following={scroll.following}\n interactive={interactive}\n showToggles={showToggles}\n cursor={cursor}\n width={railWidth}\n />\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n borderStyle=\"single\"\n borderColor=\"gray\"\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n paddingLeft={1}\n overflow=\"hidden\"\n >\n <LogHeader following={scroll.following} below={scroll.below} live={isStreaming(state.phase)} />\n <Box ref={logBoxRef} flexGrow={1} overflow=\"hidden\">\n <ScrollableLogView visible={scroll.visible} viewportHeight={viewportHeight} measured={measured} />\n </Box>\n <NotificationStack\n error={state.error}\n restartRequired={state.restartRequired}\n prompt={state.commandUpdatePrompt}\n />\n </Box>\n </Box>\n );\n}\n","import { Box, measureElement, useInput, useWindowSize } from 'ink';\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport { useDevState } from '@ui/hooks/useDevState';\nimport { useLogs } from '@ui/hooks/useLogs';\nimport { useScroll } from '@ui/hooks/useScroll';\nimport { useUptime } from '@ui/hooks/useUptime';\nimport { dispatchHotkey } from '@ui/hotkeys';\nimport { DevLayout } from '@ui/layout/DevLayout';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { DevStore } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement } from 'react';\n\ninterface DevAppProps {\n readonly store: DevStore;\n readonly onReady: () => void;\n readonly onQuit?: () => Promise<void> | void;\n readonly onDisconnect?: () => Promise<void> | void;\n readonly onRestart?: () => Promise<void> | void;\n readonly onRefreshCommands?: (shouldRefresh: boolean) => Promise<void> | void;\n}\n\nfunction logKey(entry: LogEntry): number {\n return entry.id;\n}\n\nexport function DevApp(props: DevAppProps): ReactElement {\n const { store, onReady } = props;\n const state = useDevState(store);\n const { rows, columns } = useWindowSize();\n\n const [enabled, setEnabled] = useState<ReadonlySet<string>>(() => new Set());\n const [showToggles, setShowToggles] = useState(false);\n const [cursor, setCursor] = useState(0);\n\n const logBoxRef = useRef<DOMElement | null>(null);\n const [logBoxHeight, setLogBoxHeight] = useState(0);\n\n const logs = useLogs(enabled);\n const viewportHeight = Math.max(1, logBoxHeight);\n const scroll = useScroll(logs, viewportHeight, logKey);\n const uptimeMs = useUptime(state);\n\n const interactive = !state.isBusy || state.restartRequired;\n\n // Re-measure only when something can change the box height: a terminal resize, or a notification card\n // appearing/clearing. The measured height is the exact log-line budget for the scroll window.\n useEffect(() => {\n if (!logBoxRef.current) return;\n const measured = measureElement(logBoxRef.current).height;\n setLogBoxHeight((prev) => (prev === measured ? prev : measured));\n }, [rows, columns, state.error, state.restartRequired, state.commandUpdatePrompt]);\n\n useInput((input, key) => {\n dispatchHotkey({\n input,\n key,\n state,\n interactive,\n scroll,\n store,\n enabled,\n setEnabled,\n showToggles,\n setShowToggles,\n cursor,\n setCursor,\n onQuit: props.onQuit,\n onDisconnect: props.onDisconnect,\n onRestart: props.onRestart,\n onRefreshCommands: props.onRefreshCommands\n });\n });\n\n const isInitialized = useRef(false);\n useEffect(() => {\n if (isInitialized.current) return;\n isInitialized.current = true;\n\n LogStore.instance.clear();\n LogStore.instance.mount();\n onReady();\n\n return () => {\n LogStore.instance.unmount();\n };\n }, [onReady]);\n\n return (\n <Box flexDirection=\"column\" width={columns} height={rows} overflow=\"hidden\">\n <DevLayout\n state={state}\n columns={columns}\n logBoxRef={logBoxRef}\n scroll={scroll}\n viewportHeight={viewportHeight}\n measured={logBoxHeight > 0}\n enabled={enabled}\n showToggles={showToggles}\n cursor={cursor}\n interactive={interactive}\n uptimeMs={uptimeMs}\n />\n </Box>\n );\n}\n","import { StrictEventEmitter } from '@seedcord/services';\nimport { assertNever } from '@seedcord/utils';\n\nimport type { DevPhase } from './devPhase';\nimport type { DevEvent } from '@commands/dev/runtime/events';\nimport type { Config } from '@seedcord/types';\n\nexport interface DevState {\n readonly phase: DevPhase;\n readonly status: string;\n readonly error: Error | null;\n readonly isBusy: boolean;\n readonly config: Config | null;\n readonly restartRequired: boolean;\n readonly commandUpdatePrompt: string[] | null;\n}\n\nconst INITIAL: DevState = {\n phase: 'starting',\n status: 'Initializing...',\n error: null,\n isBusy: true,\n config: null,\n restartRequired: false,\n commandUpdatePrompt: null\n};\n\n// Single source of truth for the dev UI. The runner pushes scalar updates through the setters; runtime\n// events reduce through `apply`. `getState` returns a stable reference between mutations, which\n// `useSyncExternalStore` requires to avoid render loops.\nexport class DevStore extends StrictEventEmitter<{ change: [] }> {\n private state: DevState = INITIAL;\n\n public getState(): DevState {\n return this.state;\n }\n\n public setStatus(status: string): void {\n this.patch({ status });\n }\n\n public setBusy(isBusy: boolean): void {\n this.patch({ isBusy });\n }\n\n public setPhase(phase: DevPhase): void {\n this.patch({ phase });\n }\n\n public setError(error: Error | null): void {\n this.patch({ error });\n }\n\n public setConfig(config: Config): void {\n this.patch({ config });\n }\n\n public clearPrompt(): void {\n this.patch({ commandUpdatePrompt: null });\n }\n\n // Optimistic UI transitions: the user pressed r/d, so reset to a busy \"reconnecting\" state in one atomic\n // patch (one render) before the runner stops the session and starts the next one.\n public beginRestart(): void {\n this.patch({ phase: 'starting', isBusy: true, restartRequired: false, error: null, status: 'Restarting...' });\n }\n\n public beginDisconnect(): void {\n this.patch({\n phase: 'disconnected',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Disconnecting...'\n });\n }\n\n public beginQuit(): void {\n this.patch({ phase: 'quitting', isBusy: true, status: 'Shutting down...' });\n }\n\n public apply(event: DevEvent): void {\n switch (event.type) {\n case 'restart-required':\n this.patch({\n phase: 'restart-required',\n status: 'Restart required. Press r to restart.',\n restartRequired: true\n });\n break;\n case 'command-update-prompt':\n this.patch({ commandUpdatePrompt: event.files });\n break;\n case 'module-loading':\n case 'module-loaded':\n case 'module-error':\n case 'file-change':\n case 'ready':\n break;\n default:\n assertNever(event);\n }\n }\n\n private patch(next: Partial<DevState>): void {\n this.state = { ...this.state, ...next };\n this.emit('change');\n }\n}\n","import type { ILogger } from '@seedcord/types';\n\nexport class SilentLogger implements ILogger {\n public error(): void {}\n public warn(): void {}\n public info(): void {}\n public http(): void {}\n public verbose(): void {}\n public debug(): void {}\n public silly(): void {}\n}\n","import { relative, resolve } from 'node:path';\n\nimport { Logger, StrictEventEmitter } from '@seedcord/services';\nimport chalk from 'chalk';\nimport { minimatch } from 'minimatch';\n\nimport type { DevEvent } from './events';\nimport type { HmrEventType, HmrUpdateEvent } from '@api/Hmr';\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type {\n EnvironmentModuleNode,\n HotUpdateOptions,\n ModuleNode,\n NormalizedHotChannel,\n Plugin,\n ViteDevServer\n} from 'vite';\n\nconst DEBOUNCE_MS = 250;\n\nexport class HmrPlugin extends StrictEventEmitter<{ event: [DevEvent] }> {\n private readonly logger: Logger;\n private readonly lastUpdate = new Map<string, number>();\n private server: ViteDevServer | null = null;\n private readonly dynamicRestartPatterns = new Set<string>();\n\n private get hot(): NormalizedHotChannel | undefined {\n return this.server?.environments.ssr.hot;\n }\n\n constructor(private readonly config: ResolvedSeedcordDevConfig) {\n super();\n this.logger = new Logger('HMR', { channel: 'hmr' });\n }\n\n public get plugin(): Plugin {\n return {\n name: 'seedcord:hmr',\n configureServer: this.configureServer.bind(this),\n hotUpdate: this.hotUpdate.bind(this)\n };\n }\n\n public sendRefreshCommands(shouldRefresh: boolean): void {\n if (this.server) {\n if (this.hot) {\n this.hot.send('seedcord:refresh-commands', { shouldRefresh });\n }\n }\n }\n\n private configureServer(server: ViteDevServer): void {\n this.server = server;\n server.watcher.on('add', (file) => this.handleFileEvent(file, 'create'));\n server.watcher.on('unlink', (file) => this.handleFileEvent(file, 'delete'));\n server.watcher.on('addDir', (file) => this.handleFileEvent(file, 'createDir'));\n server.watcher.on('unlinkDir', (file) => this.handleFileEvent(file, 'deleteDir'));\n\n if (this.hot) {\n this.hot.on('seedcord:commands-update-prompt', (data) => {\n this.emit('event', { type: 'command-update-prompt', files: data.files });\n });\n\n this.hot.on('seedcord:register-critical-files', (data) => {\n for (const pattern of data.patterns) {\n this.dynamicRestartPatterns.add(pattern);\n }\n\n this.logger.utils.list(data.patterns, 'Registered critical file patterns:');\n });\n }\n }\n\n // Debounce per (file, type): a rapid create-then-update of the same file is two distinct events, so a\n // single shared timestamp would drop the second. Returns true when the event should be suppressed.\n private isDebounced(file: string, type: HmrEventType): boolean {\n const key = `${file}::${type}`;\n const now = Date.now();\n const last = this.lastUpdate.get(key);\n if (last !== undefined && now - last < DEBOUNCE_MS) return true;\n this.lastUpdate.set(key, now);\n return false;\n }\n\n private handleFileEvent(file: string, type: HmrEventType): void {\n if (this.isDebounced(file, type)) return;\n\n const relPath = relative(process.cwd(), file);\n const typeColor =\n type === 'create' || type === 'createDir'\n ? chalk.green\n : type === 'delete' || type === 'deleteDir'\n ? chalk.red\n : chalk.blue;\n\n this.logger.info(`${typeColor(type.toUpperCase())} ${chalk.gray(relPath)}`);\n\n const payload: HmrUpdateEvent = { file, type };\n\n if (this.hot) {\n this.hot.send('seedcord:hmr', payload);\n }\n }\n\n private hotUpdate(ctx: HotUpdateOptions): EnvironmentModuleNode[] {\n const { file, modules, server } = ctx;\n const type = 'update';\n\n if (this.isDebounced(file, type)) return [];\n\n const relPath = relative(process.cwd(), file);\n\n this.logger.info(`${chalk.blue(type.toUpperCase())} ${chalk.gray(relPath)}`);\n\n if (this.isCriticalFile(file)) {\n this.logger.warn(`${chalk.red('Critical file changed:')} ${chalk.bold(relPath)}. Restart required.`);\n this.emit('event', { type: 'restart-required' });\n return [];\n }\n\n const moduleGraph = server.moduleGraph;\n const fileModules = moduleGraph.getModulesByFile(file);\n const allModules = fileModules ? Array.from(fileModules) : [];\n\n const combinedModules = new Set([...modules, ...allModules]);\n const affectedModules = this.getAffectedModules(Array.from(combinedModules));\n\n const filesToInvalidate = new Set([file, ...affectedModules]);\n\n for (const fileToInvalidate of filesToInvalidate) {\n const mods = moduleGraph.getModulesByFile(fileToInvalidate);\n if (mods) {\n for (const mod of mods) {\n moduleGraph.invalidateModule(mod);\n }\n }\n }\n\n // file-change tells the runtime to invalidate this module in its evaluated-modules graph.\n this.emit('event', { type: 'file-change', path: file });\n\n const payload: HmrUpdateEvent = { file, type, affectedModules };\n\n if (this.hot) {\n this.hot.send('seedcord:hmr', payload);\n }\n\n // Returning [] suppresses Vite's default client HMR; invalidation runs through the runtime instead.\n return [];\n }\n\n private isCriticalFile(file: string): boolean {\n const root = this.config.root;\n const relPath = relative(root, file);\n\n if (this.config.hmr?.restart) {\n for (const pattern of this.config.hmr.restart) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n }\n\n for (const pattern of this.dynamicRestartPatterns) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n\n if (\n file === this.config.configFile ||\n file.endsWith('package.json') ||\n file.endsWith('tsconfig.json') ||\n file.endsWith('.env')\n ) {\n return true;\n }\n\n const entryPath = resolve(root, this.config.entry);\n const instancePath = resolve(root, this.config.instance);\n\n if (file === entryPath || file === instancePath) {\n return true;\n }\n\n return false;\n }\n\n private getAffectedModules(modules: (EnvironmentModuleNode | ModuleNode)[]): string[] {\n const affected = new Set<string>();\n const seen = new Set<string>();\n\n const traverse = (mod: EnvironmentModuleNode | ModuleNode): void => {\n if (mod.file && !seen.has(mod.file)) {\n seen.add(mod.file);\n affected.add(mod.file);\n mod.importers.forEach(traverse);\n }\n };\n\n modules.forEach(traverse);\n return Array.from(affected);\n }\n}\n","import { defineConfig } from 'vite';\n\nexport default defineConfig({\n server: {\n middlewareMode: true,\n hmr: true,\n watch: {\n usePolling: false,\n ignored: ['**/node_modules/**', '**/dist/**']\n }\n },\n build: {\n ssr: true,\n outDir: 'dist',\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: 'esm',\n preserveModules: true\n }\n }\n },\n ssr: {\n target: 'node',\n external: ['@seedcord/services'],\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n },\n environments: {\n ssr: {\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n }\n },\n future: {\n removeSsrLoadModule: 'warn',\n removePluginHookHandleHotUpdate: 'warn',\n removePluginHookSsrArgument: 'warn',\n removeServerModuleGraph: 'warn',\n removeServerReloadModule: 'warn',\n removeServerPluginContainer: 'warn',\n removeServerHot: 'warn',\n removeServerTransformRequest: 'warn',\n removeServerWarmupRequest: 'warn'\n },\n clearScreen: false,\n logLevel: 'error',\n appType: 'custom'\n});\n","import { relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { createServer, createServerModuleRunner, mergeConfig } from 'vite';\nimport { EvaluatedModules } from 'vite/module-runner';\n\nimport { HmrPlugin } from './HmrPlugin';\nimport viteConfig from './vite.config';\n\nimport type { DevRuntime, DevRuntimeContext, DevRuntimeLoadResult } from './DevRuntime';\nimport type { DevEvent, DevEventHandler } from './events';\nimport type { ViteDevServer } from 'vite';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nexport class ViteDevRuntime implements DevRuntime {\n private context: DevRuntimeContext | null = null;\n private viteServer: ViteDevServer | null = null;\n private moduleRunner: ModuleRunner | null = null;\n private eventHandler: DevEventHandler | null = null;\n private evaluatedModules: EvaluatedModules | null = null;\n private hmrPlugin: HmrPlugin | null = null;\n\n public async start(context: DevRuntimeContext): Promise<void> {\n this.context = context;\n this.eventHandler = context.onEvent ?? null;\n\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: projectRoot });\n\n const hmrPlugin = new HmrPlugin(this.context.config);\n this.hmrPlugin = hmrPlugin;\n\n const config = mergeConfig(viteConfig, {\n root: projectRoot,\n plugins: [hmrPlugin.plugin]\n });\n\n this.viteServer = await createServer(config);\n\n this.evaluatedModules = new EvaluatedModules();\n this.moduleRunner = createServerModuleRunner(this.viteServer.environments.ssr, {\n evaluatedModules: this.evaluatedModules\n });\n\n hmrPlugin.on('event', this.handleHmrEvent.bind(this));\n\n this.emit({ type: 'module-loaded', path: projectRoot });\n this.emit({ type: 'ready' });\n }\n\n private handleHmrEvent(event: DevEvent): void {\n if (event.type === 'file-change') {\n this.invalidateModule(event.path);\n }\n this.emit(event);\n }\n\n private invalidateModule(file: string): void {\n const projectRoot = this.context?.config.root;\n if (!projectRoot || !this.evaluatedModules) return;\n\n const moduleId = toModuleId(projectRoot, file);\n const moduleNode = this.evaluatedModules.getModuleById(moduleId);\n if (moduleNode) {\n this.evaluatedModules.invalidateModule(moduleNode);\n }\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.hmrPlugin?.sendRefreshCommands(shouldRefresh);\n }\n\n public async loadEntry(): Promise<DevRuntimeLoadResult> {\n if (!this.context || !this.viteServer || !this.moduleRunner) {\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [\n this.context?.config.instance ?? 'runtime',\n 'ViteDevRuntime.start() must complete before loadEntry()'\n ]);\n }\n\n const { instance: entryPath } = this.context.config;\n const projectRoot = this.context.config.root;\n const startTime = performance.now();\n\n this.emit({ type: 'module-loading', path: entryPath });\n\n try {\n const moduleId = toModuleId(projectRoot, entryPath);\n\n const module = await this.moduleRunner.import<unknown>(moduleId);\n const loadTime = performance.now() - startTime;\n\n this.emit({ type: 'module-loaded', path: entryPath });\n\n return {\n module,\n metadata: {\n loadTime\n }\n };\n } catch (error: unknown) {\n this.emit({ type: 'module-error', path: entryPath, error });\n throw error;\n }\n }\n\n public async dispose(): Promise<void> {\n // Restart/disconnect dispose the runtime without exiting the process, so drop the runtime<->plugin\n // 'event' wiring and references or each new session would leak the prior one's listeners.\n this.hmrPlugin?.removeAllListeners('event');\n\n if (this.viteServer) {\n await this.viteServer.close();\n this.viteServer = null;\n }\n\n this.moduleRunner = null;\n this.evaluatedModules = null;\n this.hmrPlugin = null;\n this.context = null;\n this.eventHandler = null;\n }\n\n private emit(event: DevEvent): void {\n this.eventHandler?.(event);\n }\n}\n\n// Vite normalizes module ids to forward slashes; relative() yields backslashes on Windows, so normalize.\nfunction toModuleId(projectRoot: string, file: string): string {\n return `/${relative(projectRoot, file).replaceAll('\\\\', '/')}`;\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\n\nimport { Logger } from '@seedcord/services';\n\nconst TSC_GRACEFUL_EXIT_MS = 2000;\n\nexport class TscRunner {\n private process: ChildProcess | null = null;\n private readonly logger: Logger;\n\n constructor(\n private readonly tsconfigPath?: string,\n private readonly cwd?: string\n ) {\n this.logger = new Logger('Typecheck', { channel: 'tsc' });\n }\n\n public start(): void {\n if (this.process) return;\n\n const tscPath = this.resolveProjectTsc();\n if (!tscPath) {\n this.logger.error('Unable to resolve \"typescript\". Install it in the project to enable tsc --watch.');\n return;\n }\n\n const args = [tscPath, '--noEmit', '--watch', '--preserveWatchOutput', '--pretty'];\n if (this.tsconfigPath) {\n args.push('--project', this.tsconfigPath);\n }\n\n this.logger.info('Starting tsc --watch...');\n\n this.process = spawn(process.execPath, args, {\n cwd: this.cwd ?? process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.info(line.trimEnd());\n }\n }\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.error(line.trimEnd());\n }\n }\n });\n\n this.process.on('error', (err) => {\n this.logger.error(`Failed to start tsc: ${err.message}`);\n });\n\n this.process.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n this.logger.error(`tsc exited with code ${code}`);\n } else {\n this.logger.info('tsc exited.');\n }\n this.process = null;\n });\n }\n\n public stop(): void {\n const child = this.process;\n if (!child) return;\n\n this.logger.info('Stopping tsc...');\n child.kill('SIGTERM');\n\n // justified: tsc --watch can ignore SIGTERM when stdin is detached (Windows/some Node builds); escalate to SIGKILL after a grace window. unref so the timer never holds the event loop open.\n const killTimer = setTimeout(() => child.kill('SIGKILL'), TSC_GRACEFUL_EXIT_MS);\n killTimer.unref();\n child.once('exit', () => {\n clearTimeout(killTimer);\n });\n // The handle is nulled by the 'exit' listener in start(); leaving it set until exit prevents start() from spawning a second tsc over a still-dying one.\n }\n\n private resolveProjectTsc(): string | null {\n const projectDir = this.cwd ?? process.cwd();\n const manifest = resolve(projectDir, 'package.json');\n const projectRequire = existsSync(manifest) ? createRequire(manifest) : createRequire(import.meta.url);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch {\n return null;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { SeedcordBrand, type Brandable } from '@seedcord/types/internal';\n\nimport { ConfigLoader } from '@core/config/ConfigLoader';\nimport { ConfigLocator } from '@core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '@core/modules/RuntimeModuleLoader';\nimport { resolveDefaultExport } from '@utils/resolveDefaultExport';\n\nimport { ViteDevRuntime } from './runtime/ViteDevRuntime';\nimport { TscRunner } from './TscRunner';\n\nimport type { DevRuntime } from './runtime/DevRuntime';\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger, SeedcordInstance } from '@seedcord/types';\nimport type { DevStore } from '@ui/stores/DevStore';\n\nexport function isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n}\n\nclass SeedcordDevSession {\n private stopResolve?: () => void;\n private instance?: SeedcordInstance;\n private isStopped = false;\n private startupPromise?: Promise<unknown>;\n private tscRunner?: TscRunner;\n private stopPromise?: Promise<void>;\n\n constructor(\n private readonly config: ResolvedSeedcordDevConfig,\n private readonly runtime: DevRuntime,\n private readonly store: DevStore\n ) {}\n\n private async loadInstanceModule(): Promise<unknown> {\n await this.runtime.start({\n config: this.config,\n onEvent: (event) => {\n this.store.apply(event);\n }\n });\n\n // Detect a missing entry structurally; the resolved instance path is absolute. Relying on vite's\n // \"Does the file exist\" wording broke the moment that phrasing changed across a minor.\n if (!existsSync(this.config.instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [this.config.instance]);\n }\n\n try {\n const { module } = await this.runtime.loadEntry();\n return module;\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, message]);\n }\n }\n\n public async start(onReady?: () => void): Promise<void> {\n const cwd = dirname(this.config.configFile);\n this.tscRunner = new TscRunner(this.config.tsconfig, cwd);\n this.tscRunner.start();\n\n const module = await this.loadInstanceModule();\n const exported = resolveDefaultExport(module);\n const instance = await Promise.resolve(exported);\n\n if (!isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n this.instance = instance;\n this.store.setConfig(instance.config);\n\n try {\n this.store.setPhase('starting');\n this.store.setStatus('Starting Seedcord instance...');\n this.startupPromise = Promise.resolve(instance.start());\n await this.startupPromise;\n\n if (this.isStopped) {\n return;\n }\n\n this.store.setPhase('running');\n this.store.setStatus('Seedcord is running.');\n onReady?.();\n\n // Block until stop() is called (by a UI action or the single signal handler in DevCommand). The session\n // registers no process-signal handlers itself, so restarts never accumulate listeners.\n await new Promise<void>((resolve) => {\n this.stopResolve = resolve;\n });\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, reason]);\n }\n }\n\n // quit()/restart()/disconnect() call stop(), and the run loop's finally calls dispose() -> stop() again;\n // memoize so the abort + shutdown sequence runs exactly once instead of double-shutting-down.\n public async stop(): Promise<void> {\n this.stopPromise ??= this.runStop();\n return this.stopPromise;\n }\n\n private async runStop(): Promise<void> {\n this.isStopped = true;\n this.tscRunner?.stop();\n this.instance?.startup.abort();\n\n if (this.startupPromise) {\n // stop() already triggered startup.abort(), so a rejection here is that abort, not a fresh failure (real\n // startup failures surface through start()'s own catch). Awaiting drains it so teardown stays ordered.\n try {\n await this.startupPromise;\n } catch {\n /* drained: see above */\n }\n }\n\n await this.instance?.shutdown.run(0, false);\n this.stopResolve?.();\n }\n\n public async dispose(): Promise<void> {\n await this.stop();\n await this.runtime.dispose();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.runtime.refreshCommands?.(shouldRefresh);\n }\n}\n\n/**\n * Coordinates config discovery, loading, and starting a Seedcord instance.\n */\nexport class DevRunner {\n private currentSession: SeedcordDevSession | null = null;\n private signalResolve?: () => void;\n private shouldQuit = false;\n private isDisconnected = false;\n private isRunning = false;\n\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly store: DevStore\n ) {}\n\n public static create(logger: ILogger, store: DevStore): DevRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n\n return new DevRunner(locator, configLoader, store);\n }\n\n public async run(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n try {\n while (!this.shouldQuit) {\n try {\n if (this.isDisconnected) {\n await this.handleDisconnected();\n continue;\n }\n\n await this.runSession();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- quit() flips shouldQuit during the awaited session; TS narrows it to false from the loop guard and can't see the async cross-method mutation\n if (this.shouldQuit) break;\n await this.handleError(error);\n }\n }\n } finally {\n this.isRunning = false;\n }\n }\n\n private async handleDisconnected(): Promise<void> {\n this.store.setPhase('disconnected');\n this.store.setStatus('Disconnected. Press r to restart.');\n this.store.setBusy(false);\n await this.waitForSignal();\n this.store.setBusy(true);\n if (!this.shouldQuit) {\n this.isDisconnected = false;\n }\n }\n\n private async runSession(): Promise<void> {\n this.store.setPhase('starting');\n this.store.setBusy(true);\n const config = await this.loadConfig();\n const runtime = new ViteDevRuntime();\n this.currentSession = new SeedcordDevSession(config, runtime, this.store);\n\n try {\n await this.currentSession.start(() => {\n this.store.setBusy(false);\n });\n } finally {\n this.store.setBusy(true);\n await this.currentSession.dispose();\n this.currentSession = null;\n }\n }\n\n private async handleError(error: unknown): Promise<void> {\n this.store.setPhase('error');\n this.store.setError(error instanceof Error ? error : new Error(String(error)));\n this.store.setStatus('Error occurred. Press r to restart.');\n this.store.setBusy(false);\n await this.waitForSignal();\n this.store.setBusy(true);\n }\n\n public async quit(): Promise<void> {\n this.shouldQuit = true;\n this.store.setPhase('quitting');\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public async restart(): Promise<void> {\n this.isDisconnected = false;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public async disconnect(): Promise<void> {\n // Already parked in the disconnected wait, waking the signal here would fall through and start a\n // fresh session (i.e. behave like restart). No live session means nothing to disconnect.\n if (this.isDisconnected) return;\n this.isDisconnected = true;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.currentSession?.refreshCommands(shouldRefresh);\n }\n\n private async waitForSignal(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.signalResolve = resolve;\n });\n }\n\n public async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n}\n","import { LoggerChannelRegistry } from '@seedcord/services';\nimport { formatFilePath } from '@seedcord/utils';\nimport { render } from 'ink';\nimport React from 'react';\n\nimport { BaseCommand } from '@core/BaseCommand';\nimport { DevApp } from '@ui/DevApp';\nimport { DevStore } from '@ui/stores/DevStore';\nimport { LogStore } from '@ui/stores/LogStore';\nimport { SilentLogger } from '@utils/SilentLogger';\n\nimport { DevRunner } from './DevRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class DevCommand extends BaseCommand {\n private readonly runner: DevRunner;\n private readonly store: DevStore;\n\n constructor() {\n super('dev', 'Run a Seedcord instance from the config file', 'CLI:Dev');\n this.store = new DevStore();\n this.runner = DevRunner.create(new SilentLogger(), this.store);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n // SIGTERM (and SIGINT when stdin is not raw) trigger a graceful quit; Ink handles the raw-mode\n // Ctrl-C keypress itself. once() self-removes; the finally removes them on a normal exit.\n const onSignal = (): void => {\n void this.runner.quit();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n\n try {\n await this.runDevApp();\n } catch (error: unknown) {\n this.logger.error('Seedcord dev failed', error);\n process.exitCode = 1;\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n\n // The alternate screen has been restored by now, so this lands in the normal terminal: a\n // pointer to the on-disk log file, since the in-UI logs are gone once the UI unmounts.\n this.printLogLocation();\n\n // Ink's raw-mode stdin and the Vite dev server keep the event loop alive after teardown;\n // runDevApp already awaited unmount + shutdown, so exit explicitly instead of hanging.\n process.exit();\n });\n }\n\n private printLogLocation(): void {\n const registry = LoggerChannelRegistry.instance;\n const path = registry.getLogFilePath(registry.getDefaultChannel());\n if (path) process.stdout.write(`seedcord dev stopped. logs: ${formatFilePath(path)}\\n`);\n }\n\n private async runDevApp(): Promise<void> {\n let runResult: Promise<void> = Promise.resolve();\n\n const { unmount, waitUntilExit } = render(\n React.createElement(DevApp, {\n store: this.store,\n onQuit: () => this.runner.quit(),\n onDisconnect: () => this.runner.disconnect(),\n onRestart: () => this.runner.restart(),\n onRefreshCommands: (shouldRefresh: boolean) => this.runner.refreshCommands(shouldRefresh),\n onReady: () => {\n runResult = this.runner.run().finally(async () => {\n // Drain buffered logs before unmounting Ink so the final lines aren't dropped.\n await LogStore.instance.flush();\n unmount();\n });\n }\n }),\n // Alternate screen (like vim/lazygit): the original terminal + scrollback are restored on quit,\n // and Ink's ESC[3J scrollback purge never fires.\n { exitOnCtrlC: false, alternateScreen: true }\n );\n\n await waitUntilExit();\n // Surface a run-loop rejection through the action's try/catch instead of racing process.exit().\n await runResult;\n }\n}\n","import { Command } from '@commander-js/extra-typings';\nimport { Logger } from '@seedcord/services';\n\nimport { BuildCommand } from '@commands/build/BuildCommand';\nimport { DevCommand } from '@commands/dev/DevCommand';\n\nimport { version } from '.';\n\nconst LOGGER_LABEL = 'Seedcord CLI';\n\nasync function main(): Promise<void> {\n if (!process.env.ENV && !process.env.ENVIRONMENT && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development';\n }\n\n const program = new Command().name('seedcord').description('Seedcord CLI').version(version);\n\n new DevCommand().register(program);\n new BuildCommand().register(program);\n\n await program.parseAsync(process.argv);\n}\n\nvoid main().catch((error) => {\n const logger = new Logger(LOGGER_LABEL);\n logger.error('Unexpected CLI error', error);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":["createNodeRequire","viteConfig"],"sources":["../src/core/BaseCommand.ts","../src/utils/resolveDefaultExport.ts","../src/core/config/ConfigLoader.ts","../src/core/config/ConfigLocator.ts","../src/core/modules/RuntimeModuleLoader.ts","../src/commands/build/builder/BootstrapWriter.ts","../src/commands/build/builder/TypeScriptProjectBuilder.ts","../src/commands/build/BuildRunner.ts","../src/commands/build/BuildCommand.ts","../src/commands/codegen/RegistryGenerator.ts","../src/commands/codegen/renderRegistry.ts","../src/commands/codegen/CodegenRunner.ts","../src/commands/codegen/CodegenCommand.ts","../src/ui/hooks/useDevState.ts","../src/ui/stores/LogStore.ts","../src/ui/hooks/useLogs.ts","../src/ui/hooks/useScroll.ts","../src/ui/stores/devPhase.ts","../src/ui/hooks/useUptime.ts","../src/ui/hotkeys.ts","../src/ui/components/primitives/LogHeader.tsx","../src/ui/components/CommandRefreshPrompt.tsx","../src/ui/components/ErrorDisplay.tsx","../src/ui/components/RestartRequiredCard.tsx","../src/ui/components/primitives/NotificationStack.tsx","../src/ui/channelColor.ts","../src/ui/components/primitives/ScrollableLogView.tsx","../src/ui/format.ts","../src/ui/components/Banner.tsx","../src/ui/components/primitives/RunningAnimation.tsx","../src/ui/components/StatusBadge.tsx","../src/ui/components/primitives/ChannelToggles.tsx","../src/ui/components/primitives/HotkeyBar.tsx","../src/ui/components/primitives/Sidebar.tsx","../src/ui/layout/DevLayout.tsx","../src/ui/DevApp.tsx","../src/ui/stores/DevStore.ts","../src/utils/SilentLogger.ts","../src/commands/dev/runtime/HmrPlugin.ts","../src/commands/dev/runtime/vite.config.ts","../src/commands/dev/runtime/ViteDevRuntime.ts","../src/commands/dev/TscRunner.ts","../src/commands/dev/DevRunner.ts","../src/commands/dev/DevCommand.ts","../src/cli.ts"],"sourcesContent":["import { Logger } from '@seedcord/services';\n\nimport type { Command } from '@commander-js/extra-typings';\nimport type { ILogger } from '@seedcord/types';\n\nexport abstract class BaseCommand {\n protected readonly logger: ILogger;\n\n constructor(\n public readonly name: string,\n public readonly description: string,\n loggerChannel: string\n ) {\n this.logger = new Logger(loggerChannel);\n }\n\n public abstract register(program: Command): void;\n}\n","export function resolveDefaultExport<TValue>(moduleExport: TValue): unknown {\n let current: unknown = moduleExport;\n const visited = new Set<unknown>();\n\n while (isObjectWithDefault(current) && !visited.has(current)) {\n visited.add(current);\n current = current.default;\n }\n\n return current;\n}\n\nfunction isObjectWithDefault(value: unknown): value is { default: unknown } {\n return Boolean(value && typeof value === 'object' && 'default' in value);\n}\n","import { dirname, isAbsolute, relative, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { resolveDefaultExport } from '@utils/resolveDefaultExport';\n\nimport type {\n ResolvedSeedcordBuildConfig,\n ResolvedSeedcordDevConfig,\n SeedcordBuildConfig,\n SeedcordDevConfig\n} from './schema';\nimport type { ModuleLoader } from '@core/modules/ModuleLoader';\nimport type { ILogger } from '@seedcord/types';\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isOptionalString(value: unknown): boolean {\n return typeof value === 'undefined' || typeof value === 'string';\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === 'string');\n}\n\nfunction validateBuild(value: unknown): void {\n if (typeof value === 'undefined') return;\n if (!isPlainObject(value)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuild);\n if (!isOptionalString(value.outDir)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildOutDir);\n if (!isOptionalString(value.tsconfig)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildTsconfig);\n if (!isOptionalString(value.bootstrap)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidBuildBootstrap);\n}\n\nfunction validateHmr(value: unknown): void {\n if (typeof value === 'undefined') return;\n if (!isPlainObject(value)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidHmr);\n if (!isOptionalString(value.tsconfig)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidTsconfig);\n if (typeof value.restart !== 'undefined' && !isStringArray(value.restart)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidHmrRestart);\n }\n}\n\nfunction validateConfig(raw: unknown): asserts raw is SeedcordDevConfig {\n if (!isPlainObject(raw)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidExport);\n if (typeof raw.instance !== 'string' || raw.instance.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingInstance);\n }\n if (typeof raw.entry !== 'string' || raw.entry.length === 0) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigMissingEntry);\n }\n if (!isOptionalString(raw.root)) throw new SeedcordError(SeedcordErrorCode.CliConfigInvalidRoot);\n validateBuild(raw.build);\n validateHmr(raw.hmr);\n}\n\nexport class ConfigLoader {\n constructor(\n private readonly modules: ModuleLoader,\n private readonly logger: ILogger\n ) {}\n\n public async load(configPath: string): Promise<ResolvedSeedcordDevConfig> {\n const loadedModule = await this.modules.importModule(configPath);\n const config: unknown = await Promise.resolve(resolveDefaultExport(loadedModule));\n validateConfig(config);\n\n const configDir = dirname(configPath);\n const root = resolve(configDir, config.root ?? '.');\n const instance = this.resolveWithinRoot(root, config.instance);\n const entry = this.resolveWithinRoot(root, config.entry);\n this.assertEntryWithinRoot(root, entry);\n const build = this.resolveBuildOptions(configDir, config.build);\n const tsconfig = config.hmr?.tsconfig ? resolve(root, config.hmr.tsconfig) : undefined;\n\n this.logger.info(`Loaded configuration from ${configPath}`);\n this.logger.debug(`Resolved root: ${root}`);\n this.logger.debug(`Resolved instance: ${instance}`);\n this.logger.debug(`Resolved entry: ${entry}`);\n this.logger.debug(`Resolved build outDir: ${build.outDir}`);\n if (build.tsconfig) this.logger.debug(`Resolved build tsconfig: ${build.tsconfig}`);\n if (tsconfig) this.logger.debug(`Resolved dev tsconfig: ${tsconfig}`);\n this.logger.debug(`Resolved bootstrap: ${build.bootstrap}`);\n\n return {\n instance,\n root,\n configFile: configPath,\n entry,\n build,\n tsconfig,\n hmr: config.hmr\n } satisfies ResolvedSeedcordDevConfig;\n }\n\n private resolveWithinRoot(root: string, target: string): string {\n if (isAbsolute(target)) return target;\n return resolve(root, target);\n }\n\n private assertEntryWithinRoot(root: string, entry: string): void {\n const relativePath = relative(root, entry);\n if (relativePath.startsWith('..') || isAbsolute(relativePath)) {\n throw new SeedcordError(SeedcordErrorCode.CliConfigEntryOutsideRoot, [entry, root]);\n }\n }\n\n private resolveBuildOptions(\n configDir: string,\n build: SeedcordBuildConfig | undefined\n ): ResolvedSeedcordBuildConfig {\n const outDir = resolve(configDir, build?.outDir ?? 'dist');\n const bootstrapValue = build?.bootstrap;\n const bootstrap = bootstrapValue ? this.resolveBootstrap(outDir, bootstrapValue) : resolve(outDir, 'index.mjs');\n const tsconfig = build?.tsconfig ? resolve(configDir, build.tsconfig) : undefined;\n\n const resolvedBuild: ResolvedSeedcordBuildConfig = tsconfig\n ? { outDir, bootstrap, tsconfig }\n : { outDir, bootstrap };\n\n return resolvedBuild;\n }\n\n private resolveBootstrap(outDir: string, bootstrap: string): string {\n if (isAbsolute(bootstrap)) return bootstrap;\n return resolve(outDir, bootstrap);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { SEEDCORD_CONFIG_FILENAMES } from './schema';\n\nimport type { ILogger } from '@seedcord/types';\n\nexport class ConfigLocator {\n constructor(private readonly logger: ILogger) {}\n\n public locate(baseDir = process.cwd()): string {\n const normalizedBase = resolve(baseDir);\n for (const candidate of SEEDCORD_CONFIG_FILENAMES) {\n const fullPath = join(normalizedBase, candidate);\n if (existsSync(fullPath)) {\n this.logger.debug(`Found config at ${fullPath}`);\n return fullPath;\n }\n }\n\n throw new SeedcordError(SeedcordErrorCode.CliConfigNotFound, [normalizedBase, SEEDCORD_CONFIG_FILENAMES]);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname, extname, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { createJiti } from 'jiti';\nimport { tsImport } from 'tsx/esm/api';\n\nimport type { ModuleLoader } from './ModuleLoader';\n\ntype TsconfigOption = string | false;\n\ninterface RuntimeModuleLoaderOptions {\n tsconfig?: TsconfigOption;\n forceTsx?: boolean;\n}\n\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nexport class RuntimeModuleLoader implements ModuleLoader {\n private readonly jiti = createJiti(import.meta.url, {\n cache: false,\n interopDefault: true,\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs']\n });\n\n constructor(private readonly options: RuntimeModuleLoaderOptions = {}) {}\n\n public async importModule<TModule = unknown>(entryPath: string): Promise<TModule> {\n const normalized = resolve(entryPath);\n if (!existsSync(normalized)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [normalized]);\n }\n\n if (this.shouldUseTsx(normalized)) {\n return this.importWithTsx<TModule>(normalized);\n }\n\n return this.importWithNode<TModule>(normalized);\n }\n\n private shouldUseTsx(filePath: string): boolean {\n if (this.options.forceTsx) return true;\n return TS_EXTENSIONS.has(extname(filePath).toLowerCase());\n }\n\n private async importWithTsx<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n const tsconfig = this.resolveTsconfig(entryPath);\n\n try {\n return (await tsImport(specifier, { parentURL: import.meta.url, tsconfig })) as TModule;\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown tsx error';\n throw new SeedcordError(SeedcordErrorCode.CliTsxImportFailed, [entryPath, reason]);\n }\n }\n\n private async importWithNode<TModule = unknown>(entryPath: string): Promise<TModule> {\n const specifier = pathToFileURL(entryPath).href;\n\n try {\n return (await import(specifier)) as TModule;\n } catch (nativeError: unknown) {\n try {\n return await this.jiti.import(entryPath);\n } catch (fallbackError: unknown) {\n const nativeReason = nativeError instanceof Error ? nativeError.message : 'Unknown ESM import error';\n const fallbackReason = fallbackError instanceof Error ? fallbackError.message : 'Unknown jiti error';\n throw new SeedcordError(SeedcordErrorCode.CliImportFailed, [entryPath, nativeReason, fallbackReason]);\n }\n }\n }\n\n private resolveTsconfig(entryPath: string): TsconfigOption {\n if (typeof this.options.tsconfig !== 'undefined') {\n return this.options.tsconfig;\n }\n\n return this.findNearestTsconfig(dirname(entryPath)) ?? false;\n }\n\n private findNearestTsconfig(startDir: string): string | undefined {\n const candidate = resolve(startDir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(startDir);\n if (parent === startDir) return undefined;\n\n return this.findNearestTsconfig(parent);\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BootstrapWriter {\n constructor(private readonly logger: ILogger) {}\n\n public async write(config: ResolvedSeedcordDevConfig, emittedEntry: string): Promise<void> {\n const target = config.build.bootstrap;\n const relativeImport = this.formatImportPath(relative(dirname(target), emittedEntry));\n const contents = `import '${relativeImport}';\\n`;\n\n try {\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, contents, 'utf8');\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliBootstrapWriteFailed, [target, reason]);\n }\n\n this.logger.info(`Bootstrap file created at ${target}`);\n }\n\n private formatImportPath(fragment: string): string {\n const normalized = fragment.replaceAll('\\\\', '/');\n return normalized.startsWith('.') ? normalized : `./${normalized}`;\n }\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir } from 'node:fs/promises';\nimport { createRequire as createNodeRequire } from 'node:module';\nimport { dirname, extname, relative, resolve } from 'node:path';\n\nimport { isSeedcordError, SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport interface BuildResult {\n emittedEntry: string;\n}\n\ninterface ProcessResult {\n exitCode: number;\n output: string;\n}\n\nexport class TypeScriptProjectBuilder {\n constructor(private readonly logger: ILogger) {}\n\n public async build(config: ResolvedSeedcordDevConfig): Promise<BuildResult> {\n const tsconfigPath = this.resolveTsconfig(config);\n const projectDir = dirname(config.configFile);\n\n await mkdir(config.build.outDir, { recursive: true });\n\n this.logger.info(`Building Seedcord project via tsc using ${tsconfigPath}`);\n\n try {\n await this.runTsc(projectDir, tsconfigPath);\n await this.fixRelativeSpecifiers(config.build.outDir);\n } catch (error: unknown) {\n if (isSeedcordError(error)) throw error;\n\n const reason = error instanceof Error ? error.message : 'Unknown build error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [reason]);\n }\n\n const emittedEntry = this.resolveEmittedEntry(config);\n if (!existsSync(emittedEntry)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Expected output file ${emittedEntry} missing after build`\n ]);\n }\n\n this.logger.info(`Emitted entry: ${emittedEntry}`);\n return { emittedEntry } satisfies BuildResult;\n }\n\n private async runTsc(projectDir: string, tsconfigPath: string): Promise<void> {\n const tscPath = this.resolveProjectTsc(projectDir);\n\n const args = ['-p', tsconfigPath, '--pretty', 'false', '--inlineSources'];\n // tsc rejects --sourceMap alongside a project's inlineSourceMap; only force it otherwise.\n if (!(await this.usesInlineSourceMap(projectDir, tsconfigPath))) args.push('--sourceMap');\n\n const result = await this.runNodeScript(projectDir, tscPath, args);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `TypeScript compilation failed:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private async usesInlineSourceMap(projectDir: string, tsconfigPath: string): Promise<boolean> {\n const tscPath = this.resolveProjectTsc(projectDir);\n const result = await this.runNodeScript(projectDir, tscPath, ['--showConfig', '-p', tsconfigPath]);\n if (result.exitCode !== 0) return false;\n\n try {\n const config = JSON.parse(result.output) as { compilerOptions?: { inlineSourceMap?: boolean } };\n return config.compilerOptions?.inlineSourceMap === true;\n } catch {\n return false;\n }\n }\n\n private async fixRelativeSpecifiers(outDir: string): Promise<void> {\n const fixPath = this.resolveFixEsmImportPath();\n\n const result = await this.runNodeScript(process.cwd(), fixPath, [outDir]);\n if (result.exitCode === 0) return;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Failed to fix relative import specifiers:\\n${this.truncateOutput(result.output)}`\n ]);\n }\n\n private resolveProjectTsc(projectDir: string): string {\n const projectRequire = this.createProjectRequire(projectDir);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown resolution error';\n throw new SeedcordError(SeedcordErrorCode.CliBuildFailed, [\n `Unable to resolve typescript. Ensure it is installed in this project.\\n${reason}`\n ]);\n }\n }\n\n private resolveFixEsmImportPath(): string {\n const selfRequire = createNodeRequire(import.meta.url);\n\n try {\n return selfRequire.resolve('fix-esm-import-path/fix-esm-import-path.js');\n } catch {\n return selfRequire.resolve('fix-esm-import-path');\n }\n }\n\n private createProjectRequire(projectDir: string): NodeRequire {\n const candidate = resolve(projectDir, 'package.json');\n if (existsSync(candidate)) return createNodeRequire(candidate);\n\n return createNodeRequire(import.meta.url);\n }\n\n private async runNodeScript(cwd: string, scriptPath: string, args: string[]): Promise<ProcessResult> {\n return await this.runProcess(process.execPath, [scriptPath, ...args], cwd);\n }\n\n private runProcess(cmd: string, args: string[], cwd: string): Promise<ProcessResult> {\n return new Promise((resolvePromise, rejectPromise) => {\n const child = spawn(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });\n\n let output = '';\n\n child.stdout.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.stderr.on('data', (chunk) => {\n output += String(chunk);\n });\n\n child.on('error', rejectPromise);\n\n child.on('close', (code) => {\n resolvePromise({ exitCode: code ?? 1, output });\n });\n });\n }\n\n private truncateOutput(text: string, maxChars = 24_000): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}\\n...output truncated...`;\n }\n\n private resolveTsconfig(config: ResolvedSeedcordDevConfig): string {\n if (config.build.tsconfig) {\n if (!existsSync(config.build.tsconfig)) {\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [config.build.tsconfig]);\n }\n\n return config.build.tsconfig;\n }\n\n const configDir = dirname(config.configFile);\n const candidates = ['tsconfig.build.json', 'tsconfig.json']\n .map((file) => resolve(configDir, file))\n .filter((candidate) => existsSync(candidate));\n\n const [firstCandidate] = candidates;\n if (firstCandidate) return firstCandidate;\n\n throw new SeedcordError(SeedcordErrorCode.CliBuildTsconfigNotFound, [configDir]);\n }\n\n private resolveEmittedEntry(config: ResolvedSeedcordDevConfig): string {\n const relFromRoot = relative(config.root, config.entry);\n const relNoExt = relFromRoot.slice(0, relFromRoot.length - extname(relFromRoot).length);\n\n const basePath = resolve(config.build.outDir, relNoExt);\n const candidateExts = ['.js', '.mjs', '.cjs'];\n\n for (const ext of candidateExts) {\n const candidate = `${basePath}${ext}`;\n if (existsSync(candidate)) return candidate;\n }\n\n // Fallback if no emitted file was found\n return `${basePath}.js`;\n }\n}\n","import { existsSync } from 'node:fs';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\n\nimport { ConfigLoader } from '@core/config/ConfigLoader';\nimport { ConfigLocator } from '@core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '@core/modules/RuntimeModuleLoader';\n\nimport { BootstrapWriter } from './builder/BootstrapWriter';\nimport { TypeScriptProjectBuilder } from './builder/TypeScriptProjectBuilder';\n\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger } from '@seedcord/types';\n\nexport class BuildRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly builder: TypeScriptProjectBuilder,\n private readonly bootstrapWriter: BootstrapWriter,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): BuildRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const builder = new TypeScriptProjectBuilder(logger);\n const bootstrapWriter = new BootstrapWriter(logger);\n\n return new BuildRunner(locator, configLoader, builder, bootstrapWriter, logger);\n }\n\n public async run(): Promise<void> {\n const config = await this.loadConfig();\n this.assertEntryExists(config.entry);\n const { emittedEntry } = await this.builder.build(config);\n await this.bootstrapWriter.write(config, emittedEntry);\n this.logger.info('Seedcord build finished successfully.');\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n\n private assertEntryExists(entryPath: string): void {\n if (!existsSync(entryPath)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [entryPath]);\n }\n }\n}\n","import { isSeedcordError } from '@seedcord/services';\n\nimport { BaseCommand } from '@core/BaseCommand';\n\nimport { BuildRunner } from './BuildRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class BuildCommand extends BaseCommand {\n private readonly runner: BuildRunner;\n\n constructor() {\n super('build', 'Compile a Seedcord project from the config file', 'CLI:Build');\n this.runner = BuildRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n try {\n await this.runner.run();\n } catch (error: unknown) {\n this.logger.error('Seedcord build failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { routeLeavesOf, type SlashRouteLeaf } from '@seedcord/utils/internal';\nimport { ApplicationCommandOptionType, ApplicationCommandType } from 'discord-api-types/v10';\n\nimport type { ILogger, OptionKind, SlashOption } from '@seedcord/types';\nimport type {\n APIApplicationCommandBasicOption,\n RESTPostAPIApplicationCommandsJSONBody,\n RESTPostAPIChatInputApplicationCommandsJSONBody,\n RESTPostAPIContextMenuApplicationCommandsJSONBody\n} from 'discord-api-types/v10';\n\n/** One leaf's option set, keyed by option name. */\nexport type RouteOptions = Record<string, SlashOption>;\n\n/** The slash tables, keyed by route string (`cmd`, `cmd/sub`, or `cmd/group/sub`). */\nexport type SlashTables = Record<string, RouteOptions>;\n\n/** Everything codegen emits into the generated file, the slash option tables plus the two context-menu name sets. */\nexport interface GeneratedRegistry {\n slash: SlashTables;\n userContextMenus: string[];\n messageContextMenus: string[];\n}\n\n/** A command discovered by the codegen scan, paired with its source path for diagnostics. */\nexport interface ScannedCommand {\n sourceFile: string;\n json: RESTPostAPIApplicationCommandsJSONBody;\n}\n\ntype CommandOption = SlashRouteLeaf['options'][number];\n\n// keyed by the djs enum so a renamed member breaks here, and constrained to the full set of basic option\n// types so a new upstream option kind fails to satisfy until it is mapped.\nconst KIND_BY_TYPE = {\n [ApplicationCommandOptionType.String]: 'string',\n [ApplicationCommandOptionType.Integer]: 'integer',\n [ApplicationCommandOptionType.Number]: 'number',\n [ApplicationCommandOptionType.Boolean]: 'boolean',\n [ApplicationCommandOptionType.User]: 'user',\n [ApplicationCommandOptionType.Channel]: 'channel',\n [ApplicationCommandOptionType.Role]: 'role',\n [ApplicationCommandOptionType.Mentionable]: 'mentionable',\n [ApplicationCommandOptionType.Attachment]: 'attachment'\n} as const satisfies Record<APIApplicationCommandBasicOption['type'], OptionKind>;\n\n/**\n * Builds the generated registry from each command's `toJSON()`. Chat-input commands become the slash-option\n * tables, context-menu commands contribute their name to the user or message set. Reads the builder back\n * because djs erases option names at the type level.\n */\nexport class RegistryGenerator {\n constructor(private readonly logger: ILogger) {}\n\n public generate(commands: readonly ScannedCommand[]): GeneratedRegistry {\n const slash: SlashTables = {};\n const sourceByRoute = new Map<string, string>();\n const sourceByUserName = new Map<string, string>();\n const sourceByMessageName = new Map<string, string>();\n\n for (const command of commands) {\n const { json } = command;\n if (json.type === ApplicationCommandType.User) {\n this.collectContextMenu('user', json, command.sourceFile, sourceByUserName);\n } else if (json.type === ApplicationCommandType.Message) {\n this.collectContextMenu('message', json, command.sourceFile, sourceByMessageName);\n } else if (json.type === undefined || json.type === ApplicationCommandType.ChatInput) {\n this.collectSlash(json, command.sourceFile, slash, sourceByRoute);\n }\n }\n\n const userContextMenus = [...sourceByUserName.keys()];\n const messageContextMenus = [...sourceByMessageName.keys()];\n this.logger.debug(\n `Generated ${Object.keys(slash).length} slash route(s), ${userContextMenus.length} user and ${messageContextMenus.length} message context-menu command(s)`\n );\n return { slash, userContextMenus, messageContextMenus };\n }\n\n private collectSlash(\n json: RESTPostAPIChatInputApplicationCommandsJSONBody,\n sourceFile: string,\n slash: SlashTables,\n sourceByRoute: Map<string, string>\n ): void {\n this.warnEmptyGroups(json);\n for (const leaf of routeLeavesOf(json)) {\n // an interface registry merges duplicate keys silently, so the route collision must be caught here.\n const firstFile = sourceByRoute.get(leaf.route);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateRoute, [\n leaf.route,\n firstFile,\n sourceFile\n ]);\n }\n sourceByRoute.set(leaf.route, sourceFile);\n slash[leaf.route] = this.mapOptions(leaf.options);\n }\n }\n\n // each kind dedupes against its own map, a same-kind clash would merge silently\n private collectContextMenu(\n kind: 'user' | 'message',\n json: RESTPostAPIContextMenuApplicationCommandsJSONBody,\n sourceFile: string,\n sourceByName: Map<string, string>\n ): void {\n const firstFile = sourceByName.get(json.name);\n if (firstFile !== undefined) {\n throw new SeedcordError(SeedcordErrorCode.CliCodegenDuplicateContextMenu, [\n kind,\n json.name,\n firstFile,\n sourceFile\n ]);\n }\n sourceByName.set(json.name, sourceFile);\n }\n\n // routeLeavesOf drops an empty group silently because it has no route. toJSON() allows one, but Discord\n // rejects it at deploy, so surface it here where the command's source file is known.\n private warnEmptyGroups(json: RESTPostAPIChatInputApplicationCommandsJSONBody): void {\n for (const option of json.options ?? []) {\n if (option.type === ApplicationCommandOptionType.SubcommandGroup && (option.options ?? []).length === 0) {\n this.logger.warn(`Slash group \\`${json.name}/${option.name}\\` has no subcommands and will not deploy.`);\n }\n }\n }\n\n private mapOptions(options: readonly CommandOption[]): RouteOptions {\n const table: RouteOptions = {};\n for (const option of options) {\n if (\n option.type === ApplicationCommandOptionType.Subcommand ||\n option.type === ApplicationCommandOptionType.SubcommandGroup\n ) {\n continue;\n }\n\n // empty choices would narrow the value to never\n const choices =\n 'choices' in option && option.choices && option.choices.length > 0\n ? option.choices.map((choice) => choice.value)\n : undefined;\n const autocomplete = 'autocomplete' in option && option.autocomplete === true ? true : undefined;\n table[option.name] = {\n kind: KIND_BY_TYPE[option.type],\n required: option.required ?? false,\n ...(choices ? { choices } : {}),\n ...(autocomplete ? { autocomplete } : {})\n };\n }\n return table;\n }\n}\n","import type { GeneratedRegistry, RouteOptions, SlashTables } from './RegistryGenerator';\nimport type { SlashOption } from '@seedcord/types';\n\nconst BANNER = `// Generated by \\`seedcord codegen\\`. Do not edit by hand.\n// Run \\`seedcord codegen\\` after changing a command's options.`;\n\nconst DISCLAIMER = ` /**\n * These option types come from your command source. Redeploy your commands to Discord after regenerating,\n * or an interaction from a stale command can return null for an option this file types as non-null.\n */`;\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\nconst CONTROL_CHAR = 0x20;\nconst HEX_RADIX = 16;\n\n/**\n * Renders the generated registry into the committed `declare module 'seedcord'` file, the slash option\n * tables plus the user and message context-menu name registries, all in one augmentation block. Keys are\n * sorted so the output is stable across filesystems. The result is byte-stable so `seedcord codegen --check`\n * can diff it directly.\n */\nexport function renderRegistry(registry: GeneratedRegistry): string {\n return (\n `${BANNER}\\n\\ndeclare module 'seedcord' {\\n` +\n `${DISCLAIMER}\\n` +\n ` interface SlashOptionRegistry {\\n${renderSlashRows(registry.slash)}\\n }\\n` +\n ` interface UserContextMenuRegistry {\\n${renderContextMenuRows(registry.userContextMenus)}\\n }\\n` +\n ` interface MessageContextMenuRegistry {\\n${renderContextMenuRows(registry.messageContextMenus)}\\n }\\n` +\n `}\\n\\nexport {};\\n`\n );\n}\n\nfunction renderSlashRows(tables: SlashTables): string {\n return Object.entries(tables)\n .sort(([first], [second]) => compare(first, second))\n .map(([route, options]) => ` ${renderKey(route)}: ${renderRow(options)};`)\n .join('\\n');\n}\n\n// an empty kind renders the blank-body form (matching the slash registry), so the interface stays present\n// and `keyof` resolves to `never` rather than the file omitting it.\nfunction renderContextMenuRows(names: readonly string[]): string {\n return [...names]\n .sort(compare)\n .map((name) => ` ${renderName(name)}: true;`)\n .join('\\n');\n}\n\nfunction renderRow(options: RouteOptions): string {\n const entries = Object.entries(options);\n if (entries.length === 0) return '{}';\n return `{ ${entries.map(([name, opt]) => `${renderKey(name)}: ${renderOption(opt)}`).join('; ')} }`;\n}\n\nfunction renderOption(opt: SlashOption): string {\n const parts = [`kind: '${opt.kind}'`, `required: ${opt.required}`];\n if (opt.choices && opt.choices.length > 0) parts.push(`choices: [${opt.choices.map(renderChoice).join(', ')}]`);\n if (opt.autocomplete) parts.push('autocomplete: true');\n return `{ ${parts.join('; ')} }`;\n}\n\nfunction renderChoice(value: string | number): string {\n if (typeof value !== 'string') return String(value);\n return `'${escapeLiteral(value)}'`;\n}\n\n// a slash route or option name is restricted to Discord's name charset, so quoting alone is enough. A\n// context-menu name allows spaces, mixed case, and apostrophes, so its quoted form must escape the body.\nfunction renderName(name: string): string {\n return IDENTIFIER.test(name) ? name : `'${escapeLiteral(name)}'`;\n}\n\nfunction renderKey(name: string): string {\n return IDENTIFIER.test(name) ? name : `'${name}'`;\n}\n\n// escape backslashes, single quotes, and control chars or the value emits invalid TS inside a single-quoted literal.\nfunction escapeLiteral(value: string): string {\n let escaped = '';\n for (const char of value) {\n const code = char.charCodeAt(0);\n if (char === '\\\\') escaped += '\\\\\\\\';\n else if (char === \"'\") escaped += \"\\\\'\";\n else if (char === '\\n') escaped += '\\\\n';\n else if (char === '\\r') escaped += '\\\\r';\n else if (char === '\\t') escaped += '\\\\t';\n else if (code < CONTROL_CHAR) escaped += `\\\\x${code.toString(HEX_RADIX).padStart(2, '0')}`;\n else escaped += char;\n }\n return escaped;\n}\n\nfunction compare(first: string, second: string): number {\n if (first < second) return -1;\n return first > second ? 1 : 0;\n}\n","import { existsSync } from 'node:fs';\nimport { mkdir, readdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { SeedcordBrand, type Brandable } from '@seedcord/types/internal';\nimport { isTsOrJsFile } from '@seedcord/utils';\nimport { ApplicationCommandType } from 'discord-api-types/v10';\n\nimport { ConfigLoader } from '@core/config/ConfigLoader';\nimport { ConfigLocator } from '@core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '@core/modules/RuntimeModuleLoader';\nimport { resolveDefaultExport } from '@utils/resolveDefaultExport';\n\nimport { RegistryGenerator } from './RegistryGenerator';\nimport { renderRegistry } from './renderRegistry';\n\nimport type { ScannedCommand } from './RegistryGenerator';\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ModuleLoader } from '@core/modules/ModuleLoader';\nimport type { ILogger, SeedcordInstance } from '@seedcord/types';\nimport type { RESTPostAPIApplicationCommandsJSONBody } from 'discord-api-types/v10';\n\nconst OUTPUT_FILENAME = 'command-registry.gen.ts';\n\ninterface BuilderLike {\n component: { toJSON: () => unknown };\n}\n\n/**\n * Orchestrates `seedcord codegen`. Locates and loads the CLI config, imports the user's Seedcord instance to\n * read its commands directory, scans and instantiates each command for its `toJSON()`, then renders the\n * registry and either writes it or, under `--check`, diffs it against the committed file.\n */\nexport class CodegenRunner {\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly moduleLoader: ModuleLoader,\n private readonly generator: RegistryGenerator,\n private readonly logger: ILogger\n ) {}\n\n public static create(logger: ILogger): CodegenRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const generator = new RegistryGenerator(logger);\n\n return new CodegenRunner(locator, configLoader, moduleLoader, generator, logger);\n }\n\n public async run(check: boolean): Promise<void> {\n const config = await this.loadConfig();\n const rendered = renderRegistry(this.generator.generate(await this.scan(config)));\n const outputPath = resolve(config.root, OUTPUT_FILENAME);\n\n if (check) {\n await this.check(rendered, outputPath);\n return;\n }\n\n await this.write(rendered, outputPath);\n }\n\n private async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n return this.configLoader.load(this.locator.locate());\n }\n\n private async scan(config: ResolvedSeedcordDevConfig): Promise<ScannedCommand[]> {\n const commandsDir = await this.resolveCommandsDir(config);\n if (!commandsDir) return [];\n\n const commands: ScannedCommand[] = [];\n await this.walk(commandsDir, commands, new Set(), true);\n return commands;\n }\n\n // the bot's own scan runs under tsx/vite, so its import() handles .ts. codegen runs under plain node, so\n // it imports each command file through the tsx-backed module loader instead.\n private async walk(dir: string, commands: ScannedCommand[], seen: Set<unknown>, isRoot: boolean): Promise<void> {\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown error';\n // an unreadable top-level commands dir would silently pass --check against a stale registry, so fail.\n if (isRoot) throw new SeedcordError(SeedcordErrorCode.CliCodegenCommandsDirUnreadable, [dir, reason]);\n this.logger.warn(`Skipping unreadable directory ${dir}. ${reason}.`);\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n await this.walk(fullPath, commands, seen, false);\n } else if (isTsOrJsFile(entry)) {\n const imported = await this.moduleLoader.importModule<Record<string, unknown>>(fullPath);\n for (const exported of Object.values(imported)) {\n // a barrel re-exports the same class object, so scan each command once.\n if (seen.has(exported)) continue;\n seen.add(exported);\n const json = this.commandJsonOf(exported);\n if (json) commands.push({ sourceFile: fullPath, json });\n }\n }\n }\n }\n\n private async resolveCommandsDir(config: ResolvedSeedcordDevConfig): Promise<string | undefined> {\n // loading the instance constructs the bot to read commands.path, so its lifecycle and plugin setup logs\n // follow this line. codegen never starts the bot, nothing logs in or connects.\n this.logger.info('Loading instance to resolve the commands directory');\n const module = await this.moduleLoader.importModule(config.instance);\n const instance = resolveDefaultExport(module);\n if (!this.isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n // the bot resolves commands.path relative to cwd, so codegen must too or it scans the wrong dir.\n const commandsPath = instance.config.bot.commands.path;\n return commandsPath ? resolve(process.cwd(), commandsPath) : undefined;\n }\n\n private commandJsonOf(exported: unknown): RESTPostAPIApplicationCommandsJSONBody | undefined {\n if (typeof exported !== 'function') return undefined;\n\n let instance: unknown;\n try {\n instance = new (exported as new () => unknown)();\n } catch {\n // not an instantiable command (or a side-effecting constructor); skip it.\n return undefined;\n }\n\n if (!this.isBuilderLike(instance)) return undefined;\n const json = instance.component.toJSON();\n if (!this.isApplicationCommand(json)) return undefined;\n return json;\n }\n\n private isBuilderLike(value: unknown): value is BuilderLike {\n if (typeof value !== 'object' || value === null) return false;\n const component = (value as { component?: unknown }).component;\n return (\n typeof component === 'object' &&\n component !== null &&\n typeof (component as BuilderLike['component']).toJSON === 'function'\n );\n }\n\n private isApplicationCommand(json: unknown): json is RESTPostAPIApplicationCommandsJSONBody {\n if (typeof json !== 'object' || json === null) return false;\n const { name, type } = json as { name?: unknown; type?: unknown };\n if (typeof name !== 'string') return false;\n // chat-input commands omit type or set it to ChatInput, context menus set User/Message. A\n // PrimaryEntryPoint or any other type is not something codegen registers, so drop it.\n return (\n type === undefined ||\n type === ApplicationCommandType.ChatInput ||\n type === ApplicationCommandType.User ||\n type === ApplicationCommandType.Message\n );\n }\n\n private isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n }\n\n private async write(rendered: string, outputPath: string): Promise<void> {\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, rendered, 'utf8');\n this.logger.info(`Command registry written to ${outputPath}`);\n }\n\n private async check(rendered: string, outputPath: string): Promise<void> {\n const onDisk = existsSync(outputPath) ? await readFile(outputPath, 'utf8') : '';\n if (onDisk === rendered) return;\n\n this.logger.error(`Command registry is out of date. Run \\`seedcord codegen\\` and commit ${outputPath}.`);\n process.exitCode = 1;\n }\n}\n","import { isSeedcordError } from '@seedcord/services';\n\nimport { BaseCommand } from '@core/BaseCommand';\n\nimport { CodegenRunner } from './CodegenRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class CodegenCommand extends BaseCommand {\n private readonly runner: CodegenRunner;\n\n constructor() {\n super(\n 'codegen',\n 'Generate the typed command registry (slash options and context menus) from your commands',\n 'CLI:Codegen'\n );\n this.runner = CodegenRunner.create(this.logger);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .option('--check', 'Verify the committed registry is up to date instead of writing it')\n .action(async (options) => {\n try {\n await this.runner.run(options.check ?? false);\n } catch (error: unknown) {\n this.logger.error('Seedcord codegen failed', error);\n if (isSeedcordError(error)) process.exitCode = 1;\n else process.exit(1);\n }\n });\n }\n}\n","import { useCallback, useSyncExternalStore } from 'react';\n\nimport type { DevState, DevStore } from '@ui/stores/DevStore';\n\nexport function useDevState(store: DevStore): DevState {\n const subscribe = useCallback(\n (onChange: () => void) => {\n store.on('change', onChange);\n return () => {\n store.off('change', onChange);\n };\n },\n [store]\n );\n const getSnapshot = useCallback(() => store.getState(), [store]);\n return useSyncExternalStore(subscribe, getSnapshot);\n}\n","import { LoggerChannelRegistry, StrictEventEmitter } from '@seedcord/services';\n\nimport type { ILoggerSink, ILoggerSinkHandle, LoggerSinkLogEntry } from '@seedcord/services';\n\nexport interface LogEntry {\n id: number;\n channel: string;\n text: string;\n timestamp: number;\n}\n\ninterface LogStoreEvents {\n change: [];\n}\n\n// Buffered log batches flush on this debounce so a noisy bot doesn't re-render the log view per line.\nconst UPDATE_DEBOUNCE_MS = 30;\n\n// eslint-disable-next-line no-magic-numbers -- 27 is the ESC control code\nconst ESC = String.fromCharCode(27);\n\nexport class LogStore extends StrictEventEmitter<LogStoreEvents> implements ILoggerSink {\n private static _instance: LogStore | null = null;\n\n private entries: LogEntry[] = [];\n private buffer: LogEntry[] = [];\n private nextId = 1;\n private sinkHandle: ILoggerSinkHandle | null = null;\n private pendingUpdate = false;\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private readonly MAX_LOGS = 1000;\n\n private constructor() {\n super();\n }\n\n public static get instance(): LogStore {\n LogStore._instance ??= new LogStore();\n return LogStore._instance;\n }\n\n public mount(): void {\n if (this.sinkHandle) return;\n this.sinkHandle = LoggerChannelRegistry.instance.installSink(this, {\n muteConsole: true\n });\n }\n\n public unmount(): void {\n if (!this.sinkHandle) return;\n this.sinkHandle.dispose();\n this.sinkHandle = null;\n }\n\n public onLog(entry: LoggerSinkLogEntry): void {\n // Split on a lone \\r too: a bare carriage return left in a row resets the terminal cursor to column 0\n // on print and overwrites the start of the line. Then drop any other control char (keeping ESC so SGR\n // color sequences still render) for the same corruption reason.\n const lines = entry.rendered.split(/\\r\\n|\\r|\\n/);\n const now = Date.now();\n\n for (const line of lines) {\n this.buffer.push({\n id: this.nextId++,\n channel: entry.channel,\n text: line.replace(/\\p{Cc}/gu, (char) => (char === ESC ? char : '')),\n timestamp: now\n });\n }\n\n this.scheduleUpdate();\n }\n\n // Stays a stable reference for useSyncExternalStore; channel filtering happens in useLogs.\n public getLogs(): readonly LogEntry[] {\n return this.entries;\n }\n\n // Source channels from real log entries, not the registry, so the toggle list never shows an empty\n // \"default\" placeholder.\n public getChannels(): readonly string[] {\n const seen = new Set<string>();\n for (const entry of this.entries) seen.add(entry.channel);\n return [...seen].sort();\n }\n\n public clear(): void {\n this.entries = [];\n this.buffer = [];\n this.emit('change');\n }\n\n // Drain buffered logs immediately and yield once so Ink paints the final lines before a quit unmounts the UI.\n public async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n this.applyBuffer();\n await new Promise<void>((resolve) => setImmediate(resolve));\n }\n\n private scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.flushTimer = setTimeout(() => this.applyBuffer(), UPDATE_DEBOUNCE_MS);\n }\n\n private applyBuffer(): void {\n this.flushTimer = null;\n this.pendingUpdate = false;\n if (this.buffer.length === 0) return;\n\n const newEntries = [...this.entries, ...this.buffer];\n this.buffer = [];\n this.entries = newEntries.length > this.MAX_LOGS ? newEntries.slice(-this.MAX_LOGS) : newEntries;\n\n this.emit('change');\n }\n}\n","import { useCallback, useMemo, useSyncExternalStore } from 'react';\n\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { LogEntry } from '@ui/stores/LogStore';\n\n// `enabled` must be a stable reference between unchanged renders (the shell holds it in state), or the memo\n// recomputes every render. An empty/absent set means all channels.\nexport function useLogs(enabled?: ReadonlySet<string>): readonly LogEntry[] {\n const store = LogStore.instance;\n\n const subscribe = useCallback(\n (cb: () => void) => {\n store.on('change', cb);\n return () => {\n store.off('change', cb);\n };\n },\n [store]\n );\n\n const getSnapshot = useCallback(() => store.getLogs(), [store]);\n\n const allLogs = useSyncExternalStore(subscribe, getSnapshot);\n\n return useMemo(() => {\n if (!enabled || enabled.size === 0) return allLogs;\n return allLogs.filter((l) => enabled.has(l.channel));\n }, [allLogs, enabled]);\n}\n","import { useState } from 'react';\n\nexport interface ScrollApi<Item> {\n // Oldest-first; consumers render in array order.\n readonly visible: readonly Item[];\n readonly following: boolean;\n readonly atTop: boolean;\n // Count of hidden entries above (older) and below (newer) the current window.\n readonly above: number;\n readonly below: number;\n readonly up: (lines?: number) => void;\n readonly down: (lines?: number) => void;\n readonly pageUp: () => void;\n readonly pageDown: () => void;\n readonly toTop: () => void;\n readonly toBottom: () => void;\n}\n\ntype ScrollKey = number | string;\n\ninterface ScrollView<Item> {\n readonly visible: readonly Item[];\n readonly topIndex: number;\n readonly following: boolean;\n readonly atTop: boolean;\n readonly above: number;\n readonly below: number;\n}\n\n// Pure, side-effect free (exported for unit tests). A null anchor follows the tail (newest). A non-null\n// anchor pins the window's top to that entry's CURRENT index, so the visible lines stay put when the buffer\n// trims its head or new lines append while scrolled up; if the anchored entry was trimmed away, it falls\n// back to the oldest line.\nexport function computeScrollView<Item>(\n items: readonly Item[],\n viewportHeight: number,\n anchor: ScrollKey | null,\n getKey: (item: Item) => ScrollKey\n): ScrollView<Item> {\n const height = Math.max(1, viewportHeight);\n const len = items.length;\n const maxTop = Math.max(0, len - height);\n\n let topIndex: number;\n if (anchor === null) {\n topIndex = maxTop;\n } else {\n const found = items.findIndex((item) => getKey(item) === anchor);\n topIndex = found === -1 ? 0 : found;\n }\n topIndex = Math.min(Math.max(0, topIndex), maxTop);\n\n const visible = items.slice(topIndex, topIndex + height);\n return {\n visible,\n topIndex,\n following: anchor === null || topIndex >= maxTop,\n atTop: topIndex === 0,\n above: topIndex,\n below: len - (topIndex + visible.length)\n };\n}\n\n// A virtualized scroll window over an append-mostly list, anchored to an entry KEY (see computeScrollView).\nexport function useScroll<Item>(\n items: readonly Item[],\n viewportHeight: number,\n getKey: (item: Item) => ScrollKey\n): ScrollApi<Item> {\n const [anchor, setAnchor] = useState<ScrollKey | null>(null);\n\n const height = Math.max(1, viewportHeight);\n const maxTop = Math.max(0, items.length - height);\n const view = computeScrollView(items, viewportHeight, anchor, getKey);\n\n // Reaching the tail clears the anchor (back to follow mode) so new lines auto-show again.\n const anchorAt = (nextTop: number): void => {\n const clamped = Math.min(Math.max(0, nextTop), maxTop);\n if (clamped >= maxTop) {\n setAnchor(null);\n return;\n }\n const entry = items[clamped];\n setAnchor(entry === undefined ? null : getKey(entry));\n };\n\n const up = (lines = 1): void => anchorAt(view.topIndex - lines);\n const down = (lines = 1): void => anchorAt(view.topIndex + lines);\n\n return {\n visible: view.visible,\n following: view.following,\n atTop: view.atTop,\n above: view.above,\n below: view.below,\n up,\n down,\n pageUp: () => up(height - 1),\n pageDown: () => down(height - 1),\n toTop: () => {\n const oldest = items[0];\n setAnchor(oldest === undefined ? null : getKey(oldest));\n },\n toBottom: () => setAnchor(null)\n };\n}\n","import type { TextProps } from 'ink';\n\nexport type DevPhase = 'starting' | 'running' | 'restart-required' | 'disconnected' | 'error' | 'quitting';\n\n// Disconnect only applies while a bot session is actually running; the other phases have nothing to stop.\nexport function isSessionLive(phase: DevPhase): boolean {\n return phase === 'running' || phase === 'restart-required';\n}\n\n// Phases where the process is up and emitting logs (in restart-required it is up but stale), so the live\n// dot blinks. disconnected, error, and quitting produce no logs and read as idle.\nexport function isStreaming(phase: DevPhase): boolean {\n return phase === 'starting' || phase === 'running' || phase === 'restart-required';\n}\n\n// How the status glyph animates: a one-shot spinner for transient phases, a steady looping arc while the\n// session is live, or a static icon for resting states.\ntype PhaseGlyph = 'spinner' | 'arc' | 'static';\n\nexport interface PhaseMeta {\n readonly label: string;\n readonly icon: string;\n readonly color: TextProps['color'];\n readonly kind: PhaseGlyph;\n}\n\n// Single source for the status-badge presentation. `satisfies` keeps each entry's literal types while\n// enforcing one entry per DevPhase, so adding a phase is a compile error until its meta is filled in.\nexport const PHASE_META = {\n starting: { label: 'starting', icon: '◐', color: 'cyan', kind: 'spinner' },\n running: { label: 'running', icon: '●', color: 'green', kind: 'arc' },\n 'restart-required': { label: 'restart required', icon: '◆', color: 'yellow', kind: 'static' },\n disconnected: { label: 'offline', icon: '○', color: 'gray', kind: 'static' },\n error: { label: 'error', icon: '✖', color: 'red', kind: 'static' },\n quitting: { label: 'quitting', icon: '◐', color: 'magenta', kind: 'spinner' }\n} as const satisfies Record<DevPhase, PhaseMeta>;\n","import { useAnimation } from 'ink';\n\nimport { isSessionLive } from '@ui/stores/devPhase';\n\nimport type { DevState } from '@ui/stores/DevStore';\n\nconst TICK_MS = 1000;\n\n// Elapsed ms while a session is live (running or restart-required), else null. useAnimation's `time` counts\n// real elapsed ms and resets to 0 when reactivated, so it restarts on each fresh run and keeps counting\n// across restart-required. No stored timestamp, manual timer, or Date.now()-in-render needed.\nexport function useUptime(state: DevState): number | null {\n const active = isSessionLive(state.phase);\n const { time } = useAnimation({ interval: TICK_MS, isActive: active });\n return active ? time : null;\n}\n","import { isSessionLive } from '@ui/stores/devPhase';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { ScrollApi } from '@ui/hooks/useScroll';\nimport type { DevState, DevStore } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { Key } from 'ink';\n\n// Toggling a channel materializes the full list on first use, then flips one entry. When the result is \"all\n// on\" again it collapses back to an empty set so channels that appear later stay visible by default.\nfunction toggleChannel(prev: ReadonlySet<string>, channel: string, all: readonly string[]): ReadonlySet<string> {\n const base = prev.size === 0 ? new Set(all) : new Set(prev);\n if (base.has(channel)) base.delete(channel);\n else base.add(channel);\n return base.size === all.length ? new Set<string>() : base;\n}\n\ninterface HotkeyContext {\n readonly input: string;\n readonly key: Key;\n readonly state: DevState;\n readonly interactive: boolean;\n readonly scroll: ScrollApi<LogEntry>;\n readonly store: DevStore;\n readonly enabled: ReadonlySet<string>;\n readonly setEnabled: (next: ReadonlySet<string>) => void;\n readonly showToggles: boolean;\n readonly setShowToggles: (next: boolean) => void;\n readonly cursor: number;\n readonly setCursor: (next: number) => void;\n readonly onQuit?: (() => Promise<void> | void) | undefined;\n readonly onDisconnect?: (() => Promise<void> | void) | undefined;\n readonly onRestart?: (() => Promise<void> | void) | undefined;\n readonly onRefreshCommands?: ((shouldRefresh: boolean) => Promise<void> | void) | undefined;\n}\n\nfunction quit(ctx: HotkeyContext): void {\n ctx.store.beginQuit();\n void ctx.onQuit?.();\n}\n\n// Ink puts stdin in raw mode, so Ctrl-C arrives as a keypress, not a SIGINT; handle it first so it always quits.\nfunction handleQuitSignal(ctx: HotkeyContext): boolean {\n if (ctx.key.ctrl && ctx.input === 'c') {\n quit(ctx);\n return true;\n }\n return false;\n}\n\nfunction handlePrompt(ctx: HotkeyContext): boolean {\n if (!ctx.state.commandUpdatePrompt) return false;\n if (ctx.input === 'y') {\n void ctx.onRefreshCommands?.(true);\n ctx.store.clearPrompt();\n } else if (ctx.input === 'n') {\n void ctx.onRefreshCommands?.(false);\n ctx.store.clearPrompt();\n }\n return true;\n}\n\nfunction handleToggleMode(ctx: HotkeyContext): boolean {\n if (!ctx.showToggles) return false;\n const channels = LogStore.instance.getChannels();\n\n if (ctx.key.escape || ctx.input === 'c') {\n ctx.setShowToggles(false);\n } else if (ctx.key.upArrow && channels.length > 0) {\n ctx.setCursor((ctx.cursor + channels.length - 1) % channels.length);\n } else if (ctx.key.downArrow && channels.length > 0) {\n ctx.setCursor((ctx.cursor + 1) % channels.length);\n } else if (ctx.input === ' ' || ctx.key.return) {\n const channel = channels[ctx.cursor];\n if (channel !== undefined) ctx.setEnabled(toggleChannel(ctx.enabled, channel, channels));\n }\n return true;\n}\n\nfunction handleScroll(ctx: HotkeyContext): boolean {\n // Runs before session actions, so scroll capture is unconditional (works even when non-interactive). t/b\n // mirror Home/End for keyboards lacking them, and like the arrows are reserved here, a future single-letter\n // action must avoid t and b.\n const { key, input, scroll } = ctx;\n if (key.upArrow) scroll.up();\n else if (key.downArrow) scroll.down();\n else if (key.pageUp) scroll.pageUp();\n else if (key.pageDown) scroll.pageDown();\n else if (key.home || input === 't') scroll.toTop();\n else if (key.end || input === 'b') scroll.toBottom();\n else return false;\n return true;\n}\n\n// Session controls. `q` quits in any state; the rest only apply once the UI is interactive.\nfunction handleActions(ctx: HotkeyContext): void {\n const { input, state, store } = ctx;\n\n if (input === 'q') {\n quit(ctx);\n return;\n }\n if (!ctx.interactive) return;\n\n if (input === 'd') {\n if (!isSessionLive(state.phase)) return;\n store.beginDisconnect();\n void ctx.onDisconnect?.();\n } else if (input === 'r') {\n store.beginRestart();\n void ctx.onRestart?.();\n } else if (input === 'c') {\n ctx.setCursor(0);\n ctx.setShowToggles(true);\n } else if (input === 'l') {\n LogStore.instance.clear();\n ctx.scroll.toBottom();\n }\n}\n\n// Single keyboard dispatcher for the dev UI: a keypress runs through these in order and stops at the first\n// that handles it, the quit signal, then the prompt and toggle modes (which capture all input while open),\n// then scroll, then session controls.\nexport function dispatchHotkey(ctx: HotkeyContext): void {\n if (handleQuitSignal(ctx)) return;\n if (handlePrompt(ctx)) return;\n if (handleToggleMode(ctx)) return;\n if (handleScroll(ctx)) return;\n handleActions(ctx);\n}\n","import { Box, Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nconst BLINK_MS = 530;\n\nfunction LiveDot(): ReactElement {\n // Blink the dot via the animation frame; a steady width (dot or space) keeps \"live\" from shifting.\n const { frame } = useAnimation({ interval: BLINK_MS });\n return (\n <Text>\n <Text color=\"red\">{frame % 2 === 0 ? '●' : ' '}</Text>\n <Text dimColor> live</Text>\n </Text>\n );\n}\n\ninterface LogHeaderProps {\n readonly following: boolean;\n readonly below: number;\n // True only while the session streams; the dot stops blinking once the session stops or crashes.\n readonly live: boolean;\n}\n\n// Sits above the logs: a blinking live dot while tailing a streaming session, a static idle marker once the\n// session stops or crashes, or the scroll status once scrolled away.\nexport function LogHeader({ following, below, live }: LogHeaderProps): ReactElement {\n if (!following) {\n return (\n <Box flexShrink={0}>\n <Text color=\"yellow\" wrap=\"truncate\">{`▲ scrolled · ${below} newer below · b to follow`}</Text>\n </Box>\n );\n }\n\n return <Box flexShrink={0}>{live ? <LiveDot /> : <Text dimColor>○ idle</Text>}</Box>;\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\ninterface CommandRefreshPromptProps {\n files: string[];\n}\n\nexport function CommandRefreshPrompt({ files }: CommandRefreshPromptProps): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor=\"yellow\" flexDirection=\"column\" paddingX={1}>\n <Text>\n <Text color=\"yellow\" bold>\n Commands updated:\n </Text>\n </Text>\n {files.map((file) => (\n <Text key={file} color=\"cyan\">\n - {file}\n </Text>\n ))}\n <Text>Refresh commands? (y/n)</Text>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nconst STACK_PREVIEW_LINES = 6;\n\ninterface ErrorDisplayProps {\n readonly error: Error;\n}\n\nexport function ErrorDisplay({ error }: ErrorDisplayProps): ReactElement {\n // stack[0] repeats \"Error: message\" which we already render, so preview the frames below it.\n const frames = (error.stack?.split('\\n') ?? []).slice(1);\n const preview = frames.slice(0, STACK_PREVIEW_LINES);\n const hidden = frames.length - preview.length;\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"red\" padding={1}>\n <Box marginTop={-1}>\n <Text color=\"red\" bold>\n Error: {error.name}\n </Text>\n </Box>\n <Text>{error.message}</Text>\n {preview.length > 0 && (\n <Box marginTop={1} flexDirection=\"column\">\n {preview.map((line) => (\n <Text key={line} dimColor wrap=\"truncate\">\n {line}\n </Text>\n ))}\n {hidden > 0 && <Text dimColor>{`… ${hidden} more line${hidden === 1 ? '' : 's'}`}</Text>}\n </Box>\n )}\n <Box marginTop={1}>\n <Text>\n press{' '}\n <Text color=\"yellow\" bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { ReactElement } from 'react';\n\nexport function RestartRequiredCard(): ReactElement {\n return (\n <Box borderStyle=\"round\" borderColor=\"yellow\" flexDirection=\"column\" paddingX={1}>\n <Text color=\"yellow\" bold>\n Restart required\n </Text>\n <Text>\n A change needs a full restart. press{' '}\n <Text color=\"yellow\" bold>\n r\n </Text>{' '}\n to restart\n </Text>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { CommandRefreshPrompt } from '../CommandRefreshPrompt';\nimport { ErrorDisplay } from '../ErrorDisplay';\nimport { RestartRequiredCard } from '../RestartRequiredCard';\n\nimport type { ReactElement } from 'react';\n\ninterface NotificationStackProps {\n readonly error: Error | null;\n readonly restartRequired: boolean;\n readonly prompt: readonly string[] | null;\n}\n\n// Notification cards docked below the logs. Renders nothing when idle, so it adds no rows.\nexport function NotificationStack({ error, restartRequired, prompt }: NotificationStackProps): ReactElement | null {\n if (!error && !restartRequired && !prompt) return null;\n\n return (\n <Box flexShrink={0} flexDirection=\"column\">\n {error ? <ErrorDisplay error={error} /> : null}\n {restartRequired ? <RestartRequiredCard /> : null}\n {prompt ? <CommandRefreshPrompt files={[...prompt]} /> : null}\n </Box>\n );\n}\n","// Stable, distinct color per channel so a line's channel tag and its toggle entry always match. Red is\n// reserved for errors and the live dot, so it is left out of the palette.\nconst PALETTE = ['cyan', 'green', 'yellow', 'magenta', 'blue', 'cyanBright'] as const;\n\ntype ChannelColor = (typeof PALETTE)[number];\n\nconst assigned = new Map<string, ChannelColor>();\n\nexport function channelColor(channel: string): ChannelColor {\n const existing = assigned.get(channel);\n if (existing) return existing;\n\n const color = PALETTE[assigned.size % PALETTE.length] ?? PALETTE[0];\n assigned.set(channel, color);\n return color;\n}\n\n// the map is module-level, so clear it per dev session or stale channels skew the next session's colors.\nexport function resetChannelColors(): void {\n assigned.clear();\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '@ui/channelColor';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { ReactElement } from 'react';\n\nconst MIN_LOG_LINES = 3;\nconst MAX_TAG = 10;\n\ninterface ScrollableLogViewProps {\n readonly visible: readonly LogEntry[];\n readonly viewportHeight: number;\n // False until the parent box has been measured; avoids a one-frame \"too small\" flash on mount.\n readonly measured: boolean;\n}\n\nexport function ScrollableLogView({ visible, viewportHeight, measured }: ScrollableLogViewProps): ReactElement | null {\n if (!measured) return null;\n\n if (viewportHeight < MIN_LOG_LINES) {\n return (\n <Text color=\"yellow\" wrap=\"truncate\">\n Terminal too small to show logs.\n </Text>\n );\n }\n\n // Pad channel tags to a common width so messages line up; cap the width so a long channel name is\n // truncated rather than the message.\n const channels = LogStore.instance.getChannels();\n const tagWidth = Math.min(\n MAX_TAG,\n channels.reduce((max, channel) => Math.max(max, channel.length), 0)\n );\n\n return (\n // flex-end pins the newest line to the bottom edge (tail -f): the window grows upward, and when the\n // buffer is sparse the lines sit at the bottom instead of the middle.\n <Box flexDirection=\"column\" flexGrow={1} justifyContent=\"flex-end\" overflow=\"hidden\">\n {visible.length === 0 ? (\n <Text dimColor>Waiting for logs…</Text>\n ) : (\n visible.map((log) => (\n <Text key={log.id} wrap=\"truncate\">\n <Text color={channelColor(log.channel)}>{log.channel.slice(0, tagWidth).padEnd(tagWidth)}</Text>{' '}\n {log.text}\n </Text>\n ))\n )}\n </Box>\n );\n}\n","const MS_PER_SECOND = 1000;\nconst SECONDS_PER_MINUTE = 60;\nconst MINUTES_PER_HOUR = 60;\n\nfunction pad(value: number): string {\n return value.toString().padStart(2, '0');\n}\n\n// Drops empty leading units: 12s, 3m 12s, 1h 02m 03s.\nexport function formatUptime(ms: number): string {\n const totalSeconds = Math.max(0, Math.floor(ms / MS_PER_SECOND));\n const seconds = totalSeconds % SECONDS_PER_MINUTE;\n const totalMinutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);\n const minutes = totalMinutes % MINUTES_PER_HOUR;\n const hours = Math.floor(totalMinutes / MINUTES_PER_HOUR);\n\n if (hours > 0) return `${hours}h ${pad(minutes)}m ${pad(seconds)}s`;\n if (minutes > 0) return `${minutes}m ${pad(seconds)}s`;\n return `${seconds}s`;\n}\n","import { formatFilePath } from '@seedcord/utils';\nimport { Box, Text } from 'ink';\nimport React from 'react';\n\nimport type { Config } from '@seedcord/types';\nimport type { ReactElement } from 'react';\n\nconst SEED_COLOR = '#f04e36';\nconst CORD_COLOR = '#6fab49';\n\ninterface BannerProps {\n readonly config: Config | null;\n // omits config paths. Sidebar sets this when the rail is too short.\n readonly compact?: boolean;\n}\n\nfunction ConfigPath({ path }: { path: string | null | undefined }): ReactElement {\n if (!path) return <Text color=\"gray\">Disabled</Text>;\n return <Text dimColor>{formatFilePath(path)}</Text>;\n}\n\nfunction Wordmark(): ReactElement {\n return (\n <Text bold>\n <Text color={SEED_COLOR}>seed</Text>\n <Text color={CORD_COLOR}>cord</Text>\n </Text>\n );\n}\n\nexport function Banner({ config, compact = false }: BannerProps): ReactElement {\n if (compact || !config) return <Wordmark />;\n\n return (\n <Box flexDirection=\"column\">\n <Wordmark />\n <Box flexDirection=\"column\" paddingTop={1}>\n <Text>\n <Text color=\"blue\">➜</Text> Interactions: <ConfigPath path={config.bot.interactions.path} />\n </Text>\n <Text>\n <Text color=\"blue\">➜</Text> Events: <ConfigPath path={config.bot.events.path} />\n </Text>\n <Text>\n <Text color=\"blue\">➜</Text> Pub/Sub: <ConfigPath path={config.subscribers.path} />\n </Text>\n </Box>\n </Box>\n );\n}\n","import { Text, useAnimation } from 'ink';\nimport React from 'react';\n\nimport type { TextProps } from 'ink';\nimport type { ReactElement } from 'react';\n\n// A slow rotating arc, distinct from ink-spinner's startup `balloon2`, so the running state looks different\n// from the startup spinner.\nconst FRAMES = ['◜', '◠', '◝', '◞', '◡', '◟'] as const;\nconst FRAME_MS = 120;\nconst STATIC_GLYPH = '●';\n\ninterface RunningAnimationProps {\n readonly active: boolean;\n readonly color?: TextProps['color'];\n}\n\nexport function RunningAnimation({ active, color }: RunningAnimationProps): ReactElement {\n const { frame } = useAnimation({ interval: FRAME_MS, isActive: active });\n const glyph = active ? FRAMES[frame % FRAMES.length] : STATIC_GLYPH;\n return color === undefined ? <Text>{glyph}</Text> : <Text color={color}>{glyph}</Text>;\n}\n","import { Text } from 'ink';\nimport Spinner from 'ink-spinner';\nimport React from 'react';\n\nimport { PHASE_META } from '@ui/stores/devPhase';\n\nimport { RunningAnimation } from './primitives/RunningAnimation';\n\nimport type { DevPhase } from '@ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ninterface StatusBadgeProps {\n readonly phase: DevPhase;\n}\n\nfunction Glyph({ phase }: { phase: DevPhase }): ReactElement {\n const meta = PHASE_META[phase];\n if (meta.kind === 'spinner') return <Spinner type=\"balloon2\" />;\n if (meta.kind === 'arc') return <RunningAnimation active color={meta.color} />;\n return <Text>{meta.icon}</Text>;\n}\n\nexport function StatusBadge({ phase }: StatusBadgeProps): ReactElement {\n const meta = PHASE_META[phase];\n return (\n <Text color={meta.color} bold>\n <Glyph phase={phase} /> {meta.label}\n </Text>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { channelColor } from '@ui/channelColor';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { ReactElement } from 'react';\n\ninterface ChannelTogglesProps {\n // Empty set means every channel is on, so channels that appear later default to visible.\n readonly enabled: ReadonlySet<string>;\n // Index of the focused row while in toggle mode, or null when the list is read-only.\n readonly cursor: number | null;\n}\n\nexport function ChannelToggles({ enabled, cursor }: ChannelTogglesProps): ReactElement {\n // Re-read each render; the tree re-renders on every log batch, so no memo is needed.\n const channels = LogStore.instance.getChannels();\n\n if (channels.length === 0) {\n return <Text dimColor>no logs yet</Text>;\n }\n\n return (\n <Box flexDirection=\"column\">\n {channels.map((channel, index) => {\n const on = enabled.size === 0 || enabled.has(channel);\n const focused = cursor === index;\n // Match the per-line log tag color when on, so the toggle and its log lines visually pair up.\n const color = focused ? 'cyan' : on ? channelColor(channel) : 'gray';\n return (\n <Text key={channel} color={color} wrap=\"truncate\">\n {focused ? '❯ ' : ' '}\n {on ? '●' : '○'} {channel}\n </Text>\n );\n })}\n </Box>\n );\n}\n","import { Box, Text } from 'ink';\nimport React from 'react';\n\nimport { isSessionLive } from '@ui/stores/devPhase';\n\nimport type { DevPhase } from '@ui/stores/devPhase';\nimport type { ReactElement } from 'react';\n\ntype HotkeyBarMode = 'default' | 'toggles';\n\ninterface HotkeyBarProps {\n readonly phase: DevPhase;\n readonly interactive: boolean;\n readonly mode: HotkeyBarMode;\n readonly following: boolean;\n}\n\ninterface HotkeyProps {\n readonly keyLabel: string;\n readonly action: string;\n readonly enabled?: boolean;\n readonly highlight?: boolean;\n}\n\nfunction Hotkey({ keyLabel, action, enabled = true, highlight = false }: HotkeyProps): ReactElement {\n const keyColor = !enabled ? 'gray' : highlight ? 'yellow' : 'cyan';\n return (\n <Box marginRight={2}>\n <Text color={keyColor} bold>\n {keyLabel}\n </Text>\n <Text dimColor> {action}</Text>\n </Box>\n );\n}\n\n// Highlight r in the phases the user recovers from with a restart.\nconst RESTART_HINT_PHASES = new Set<DevPhase>(['restart-required', 'disconnected', 'error']);\n\nfunction DefaultKeys({\n phase,\n interactive,\n following\n}: {\n phase: DevPhase;\n interactive: boolean;\n following: boolean;\n}): ReactElement {\n return (\n <>\n <Hotkey keyLabel=\"q\" action=\"quit\" />\n <Hotkey keyLabel=\"r\" action=\"restart\" enabled={interactive} highlight={RESTART_HINT_PHASES.has(phase)} />\n <Hotkey keyLabel=\"d\" action=\"disconnect\" enabled={interactive && isSessionLive(phase)} />\n <Hotkey keyLabel=\"c\" action=\"channels\" enabled={interactive} />\n <Hotkey keyLabel=\"l\" action=\"clear\" enabled={interactive} />\n <Hotkey keyLabel=\"↑↓\" action=\"scroll\" />\n <Hotkey keyLabel=\"t/b\" action=\"top/bottom\" highlight={!following} />\n </>\n );\n}\n\nexport function HotkeyBar({ phase, interactive, mode, following }: HotkeyBarProps): ReactElement {\n return (\n <Box flexDirection=\"column\" flexWrap=\"wrap\">\n {mode === 'toggles' && (\n <>\n <Hotkey keyLabel=\"↑↓\" action=\"move\" />\n <Hotkey keyLabel=\"space\" action=\"toggle\" />\n <Hotkey keyLabel=\"esc\" action=\"done\" />\n </>\n )}\n {mode === 'default' && <DefaultKeys phase={phase} interactive={interactive} following={following} />}\n </Box>\n );\n}\n","import { LoggerChannelRegistry } from '@seedcord/services';\nimport { formatFilePath } from '@seedcord/utils';\nimport { Box, Text, useWindowSize } from 'ink';\nimport React from 'react';\n\nimport { formatUptime } from '@ui/format';\n\nimport { Banner } from '../Banner';\nimport { StatusBadge } from '../StatusBadge';\nimport { ChannelToggles } from './ChannelToggles';\nimport { HotkeyBar } from './HotkeyBar';\n\nimport type { DevState } from '@ui/stores/DevStore';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\n// Below this many terminal rows the rail drops the config paths so the rest still fits.\nconst COMPACT_ROWS = 26;\n\nconst MAX_RAIL = 40;\n\n// Pads the metadata labels so their values line up into a column.\nconst META_LABEL_WIDTH = 5;\n\n// Every channel writes its own per-run file into this directory, so show the directory, not one file.\nfunction logDir(): string | null {\n const registry = LoggerChannelRegistry.instance;\n const path = registry.getLogFilePath(registry.getDefaultChannel());\n return path ? formatFilePath(path, { onlyDir: true }) : null;\n}\n\ninterface SidebarProps {\n readonly state: DevState;\n readonly enabled: ReadonlySet<string>;\n readonly uptimeMs: number | null;\n readonly following: boolean;\n readonly interactive: boolean;\n readonly showToggles: boolean;\n readonly cursor: number;\n readonly width: number | null;\n readonly ref?: Ref<DOMElement>;\n}\n\nfunction Meta({ label, value }: { label: string; value: string }): ReactElement {\n return (\n <Text>\n <Text dimColor>{label.padEnd(META_LABEL_WIDTH)}</Text>\n {value}\n </Text>\n );\n}\n\nfunction StatusBlock({ state, uptimeMs }: { state: DevState; uptimeMs: number | null }): ReactElement {\n const dir = logDir();\n return (\n <Box flexDirection=\"column\">\n <StatusBadge phase={state.phase} />\n {state.status ? <Text>{state.status}</Text> : null}\n {uptimeMs === null ? null : <Meta label=\"up\" value={formatUptime(uptimeMs)} />}\n {dir === null ? null : <Meta label=\"logs\" value={dir} />}\n </Box>\n );\n}\n\n// The left rail with banner, status, channel filter, and hotkeys, stacked from the top alongside the logs.\n// flexShrink={0} on every section keeps each at its natural height, so a short terminal clips from the\n// bottom instead of overlapping rows.\nexport function Sidebar({\n state,\n enabled,\n uptimeMs,\n following,\n interactive,\n showToggles,\n cursor,\n width,\n ref\n}: SidebarProps): ReactElement {\n const { rows } = useWindowSize();\n const compact = rows < COMPACT_ROWS;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"column\"\n width={width ?? undefined}\n maxWidth={MAX_RAIL}\n flexShrink={0}\n paddingX={1}\n overflow=\"hidden\"\n >\n <Box flexShrink={0}>\n <Banner config={state.config} compact={compact} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <StatusBlock state={state} uptimeMs={uptimeMs} />\n </Box>\n <Box flexShrink={0} marginTop={1} flexDirection=\"column\">\n <Text bold color=\"blueBright\">\n channels\n </Text>\n <ChannelToggles enabled={enabled} cursor={showToggles ? cursor : null} />\n </Box>\n <Box flexShrink={0} marginTop={1}>\n <HotkeyBar\n phase={state.phase}\n interactive={interactive}\n mode={showToggles ? 'toggles' : 'default'}\n following={following}\n />\n </Box>\n </Box>\n );\n}\n","import { Box } from 'ink';\nimport React from 'react';\n\nimport { LogHeader } from '@ui/components/primitives/LogHeader';\nimport { NotificationStack } from '@ui/components/primitives/NotificationStack';\nimport { ScrollableLogView } from '@ui/components/primitives/ScrollableLogView';\nimport { Sidebar } from '@ui/components/primitives/Sidebar';\nimport { isStreaming } from '@ui/stores/devPhase';\n\nimport type { ScrollApi } from '@ui/hooks/useScroll';\nimport type { DevState } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement, Ref } from 'react';\n\nexport interface DevLayoutProps {\n readonly state: DevState;\n // measured once to size the rail to its content, then held. null until that first measurement lands\n readonly railRef: Ref<DOMElement>;\n readonly railWidth: number | null;\n // the shell measures this box to size the scroll window. it must be attached or the viewport is empty\n readonly logBoxRef: Ref<DOMElement>;\n readonly scroll: ScrollApi<LogEntry>;\n readonly viewportHeight: number;\n readonly measured: boolean;\n readonly enabled: ReadonlySet<string>;\n readonly showToggles: boolean;\n readonly cursor: number;\n readonly interactive: boolean;\n readonly uptimeMs: number | null;\n}\n\n// Left rail (banner, status, channel filter, hotkeys) and a wide right column for logs, separated by a\n// vertical divider. The log column shows its live/scroll status on top, then the scrolling logs, then\n// notification cards docked beneath where there's room for stack traces.\nexport function DevLayout(props: DevLayoutProps): ReactElement {\n const { state, railRef, railWidth, logBoxRef, scroll, viewportHeight, measured } = props;\n const { enabled, showToggles, cursor, interactive, uptimeMs } = props;\n\n return (\n <Box flexGrow={1}>\n <Sidebar\n ref={railRef}\n state={state}\n enabled={enabled}\n uptimeMs={uptimeMs}\n following={scroll.following}\n interactive={interactive}\n showToggles={showToggles}\n cursor={cursor}\n width={railWidth}\n />\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n minWidth={0}\n borderStyle=\"single\"\n borderColor=\"gray\"\n borderTop={false}\n borderRight={false}\n borderBottom={false}\n paddingLeft={1}\n overflow=\"hidden\"\n >\n <LogHeader following={scroll.following} below={scroll.below} live={isStreaming(state.phase)} />\n <Box ref={logBoxRef} flexGrow={1} overflow=\"hidden\">\n <ScrollableLogView visible={scroll.visible} viewportHeight={viewportHeight} measured={measured} />\n </Box>\n <NotificationStack\n error={state.error}\n restartRequired={state.restartRequired}\n prompt={state.commandUpdatePrompt}\n />\n </Box>\n </Box>\n );\n}\n","import { Box, measureElement, useInput, useWindowSize } from 'ink';\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport { useDevState } from '@ui/hooks/useDevState';\nimport { useLogs } from '@ui/hooks/useLogs';\nimport { useScroll } from '@ui/hooks/useScroll';\nimport { useUptime } from '@ui/hooks/useUptime';\nimport { dispatchHotkey } from '@ui/hotkeys';\nimport { DevLayout } from '@ui/layout/DevLayout';\nimport { LogStore } from '@ui/stores/LogStore';\n\nimport type { DevStore } from '@ui/stores/DevStore';\nimport type { LogEntry } from '@ui/stores/LogStore';\nimport type { DOMElement } from 'ink';\nimport type { ReactElement } from 'react';\n\ninterface DevAppProps {\n readonly store: DevStore;\n readonly onReady: () => void;\n readonly onQuit?: () => Promise<void> | void;\n readonly onDisconnect?: () => Promise<void> | void;\n readonly onRestart?: () => Promise<void> | void;\n readonly onRefreshCommands?: (shouldRefresh: boolean) => Promise<void> | void;\n}\n\nfunction logKey(entry: LogEntry): number {\n return entry.id;\n}\n\nexport function DevApp(props: DevAppProps): ReactElement {\n const { store, onReady } = props;\n const state = useDevState(store);\n const { rows, columns } = useWindowSize();\n\n const [enabled, setEnabled] = useState<ReadonlySet<string>>(() => new Set());\n const [showToggles, setShowToggles] = useState(false);\n const [cursor, setCursor] = useState(0);\n\n const logBoxRef = useRef<DOMElement | null>(null);\n const [logBoxHeight, setLogBoxHeight] = useState(0);\n\n const railRef = useRef<DOMElement | null>(null);\n const [railWidth, setRailWidth] = useState<number | null>(null);\n const measuredConfig = useRef<unknown>(null);\n\n const logs = useLogs(enabled);\n const viewportHeight = Math.max(1, logBoxHeight);\n const scroll = useScroll(logs, viewportHeight, logKey);\n const uptimeMs = useUptime(state);\n\n const interactive = !state.isBusy || state.restartRequired;\n\n // Re-measure only when something can change the box height, a terminal resize or a notification card\n // appearing/clearing. The measured height is the exact log-line budget for the scroll window.\n useEffect(() => {\n if (!logBoxRef.current) return;\n const measured = measureElement(logBoxRef.current).height;\n setLogBoxHeight((prev) => (prev === measured ? prev : measured));\n }, [rows, columns, state.error, state.restartRequired, state.commandUpdatePrompt]);\n\n // Measure the rail's content width once per loaded config, so it holds as logs stream but re-fits when a\n // restart loads a wider config.\n useEffect(() => {\n if (!railRef.current || !state.config || measuredConfig.current === state.config) return;\n const measured = measureElement(railRef.current).width;\n if (measured > 0) {\n measuredConfig.current = state.config;\n setRailWidth(measured);\n }\n }, [rows, columns, state.config]);\n\n useInput((input, key) => {\n dispatchHotkey({\n input,\n key,\n state,\n interactive,\n scroll,\n store,\n enabled,\n setEnabled,\n showToggles,\n setShowToggles,\n cursor,\n setCursor,\n onQuit: props.onQuit,\n onDisconnect: props.onDisconnect,\n onRestart: props.onRestart,\n onRefreshCommands: props.onRefreshCommands\n });\n });\n\n const isInitialized = useRef(false);\n useEffect(() => {\n if (isInitialized.current) return;\n isInitialized.current = true;\n\n LogStore.instance.clear();\n LogStore.instance.mount();\n onReady();\n\n return () => {\n LogStore.instance.unmount();\n };\n }, [onReady]);\n\n return (\n <Box flexDirection=\"column\" width={columns} height={rows} overflow=\"hidden\">\n <DevLayout\n state={state}\n railRef={railRef}\n railWidth={railWidth}\n logBoxRef={logBoxRef}\n scroll={scroll}\n viewportHeight={viewportHeight}\n measured={logBoxHeight > 0}\n enabled={enabled}\n showToggles={showToggles}\n cursor={cursor}\n interactive={interactive}\n uptimeMs={uptimeMs}\n />\n </Box>\n );\n}\n","import { StrictEventEmitter } from '@seedcord/services';\nimport { assertNever } from '@seedcord/utils';\n\nimport type { DevPhase } from './devPhase';\nimport type { DevEvent } from '@commands/dev/runtime/events';\nimport type { Config } from '@seedcord/types';\n\nexport interface DevState {\n readonly phase: DevPhase;\n readonly status: string;\n readonly error: Error | null;\n readonly isBusy: boolean;\n readonly config: Config | null;\n readonly restartRequired: boolean;\n readonly commandUpdatePrompt: string[] | null;\n}\n\nconst INITIAL: DevState = {\n phase: 'starting',\n status: 'Initializing...',\n error: null,\n isBusy: true,\n config: null,\n restartRequired: false,\n commandUpdatePrompt: null\n};\n\n// Single source of truth for the dev UI. The runner pushes scalar updates through the setters; runtime\n// events reduce through `apply`. `getState` returns a stable reference between mutations, which\n// `useSyncExternalStore` requires to avoid render loops.\nexport class DevStore extends StrictEventEmitter<{ change: [] }> {\n private state: DevState = INITIAL;\n\n public getState(): DevState {\n return this.state;\n }\n\n public setStatus(status: string): void {\n this.patch({ status });\n }\n\n public setBusy(isBusy: boolean): void {\n this.patch({ isBusy });\n }\n\n public setPhase(phase: DevPhase): void {\n this.patch({ phase });\n }\n\n public setError(error: Error | null): void {\n this.patch({ error });\n }\n\n public setConfig(config: Config): void {\n this.patch({ config });\n }\n\n public clearPrompt(): void {\n this.patch({ commandUpdatePrompt: null });\n }\n\n // Optimistic UI transitions: the user pressed r/d, so reset to a busy \"reconnecting\" state in one atomic\n // patch (one render) before the runner stops the session and starts the next one.\n public beginRestart(): void {\n this.patch({ phase: 'starting', isBusy: true, restartRequired: false, error: null, status: 'Restarting...' });\n }\n\n public beginDisconnect(): void {\n this.patch({\n phase: 'disconnected',\n isBusy: true,\n restartRequired: false,\n error: null,\n status: 'Disconnecting...'\n });\n }\n\n public beginQuit(): void {\n this.patch({ phase: 'quitting', isBusy: true, status: 'Shutting down...' });\n }\n\n public apply(event: DevEvent): void {\n switch (event.type) {\n case 'restart-required':\n this.patch({\n phase: 'restart-required',\n status: 'Restart required. Press r to restart.',\n restartRequired: true\n });\n break;\n case 'command-update-prompt':\n this.patch({ commandUpdatePrompt: event.files });\n break;\n case 'module-loading':\n case 'module-loaded':\n case 'module-error':\n case 'file-change':\n case 'ready':\n break;\n default:\n assertNever(event);\n }\n }\n\n private patch(next: Partial<DevState>): void {\n this.state = { ...this.state, ...next };\n this.emit('change');\n }\n}\n","import type { ILogger } from '@seedcord/types';\n\nexport class SilentLogger implements ILogger {\n public error(): void {}\n public warn(): void {}\n public info(): void {}\n public http(): void {}\n public verbose(): void {}\n public debug(): void {}\n public silly(): void {}\n}\n","import { relative, resolve } from 'node:path';\n\nimport { Logger, StrictEventEmitter } from '@seedcord/services';\nimport chalk from 'chalk';\nimport { minimatch } from 'minimatch';\n\nimport type { DevEvent } from './events';\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { HmrEventType, HmrUpdateEvent } from '@seedcord/types/internal';\nimport type {\n EnvironmentModuleNode,\n HotUpdateOptions,\n ModuleNode,\n NormalizedHotChannel,\n Plugin,\n ViteDevServer\n} from 'vite';\n\nconst DEBOUNCE_MS = 250;\n\nexport class HmrPlugin extends StrictEventEmitter<{ event: [DevEvent] }> {\n private readonly logger: Logger;\n private readonly lastUpdate = new Map<string, number>();\n private server: ViteDevServer | null = null;\n private readonly dynamicRestartPatterns = new Set<string>();\n\n private get hot(): NormalizedHotChannel | undefined {\n return this.server?.environments.ssr.hot;\n }\n\n constructor(private readonly config: ResolvedSeedcordDevConfig) {\n super();\n this.logger = new Logger('HMR', { channel: 'hmr' });\n }\n\n public get plugin(): Plugin {\n return {\n name: 'seedcord:hmr',\n configureServer: this.configureServer.bind(this),\n hotUpdate: this.hotUpdate.bind(this)\n };\n }\n\n public sendRefreshCommands(shouldRefresh: boolean): void {\n if (this.server) {\n if (this.hot) {\n this.hot.send('seedcord:refresh-commands', { shouldRefresh });\n }\n }\n }\n\n private configureServer(server: ViteDevServer): void {\n this.server = server;\n server.watcher.on('add', (file) => this.handleFileEvent(file, 'create'));\n server.watcher.on('unlink', (file) => this.handleFileEvent(file, 'delete'));\n server.watcher.on('addDir', (file) => this.handleFileEvent(file, 'createDir'));\n server.watcher.on('unlinkDir', (file) => this.handleFileEvent(file, 'deleteDir'));\n\n if (this.hot) {\n this.hot.on('seedcord:commands-update-prompt', (data) => {\n this.emit('event', { type: 'command-update-prompt', files: data.files });\n });\n\n this.hot.on('seedcord:register-critical-files', (data) => {\n for (const pattern of data.patterns) {\n this.dynamicRestartPatterns.add(pattern);\n }\n\n this.logger.utils.list(data.patterns, 'Registered critical file patterns:');\n });\n }\n }\n\n // Debounce per (file, type): a rapid create-then-update of the same file is two distinct events, so a\n // single shared timestamp would drop the second. Returns true when the event should be suppressed.\n private isDebounced(file: string, type: HmrEventType): boolean {\n const key = `${file}::${type}`;\n const now = Date.now();\n const last = this.lastUpdate.get(key);\n if (last !== undefined && now - last < DEBOUNCE_MS) return true;\n this.lastUpdate.set(key, now);\n return false;\n }\n\n private handleFileEvent(file: string, type: HmrEventType): void {\n if (this.isDebounced(file, type)) return;\n\n const relPath = relative(process.cwd(), file);\n const typeColor =\n type === 'create' || type === 'createDir'\n ? chalk.green\n : type === 'delete' || type === 'deleteDir'\n ? chalk.red\n : chalk.blue;\n\n this.logger.info(`${typeColor(type.toUpperCase())} ${chalk.gray(relPath)}`);\n\n const payload: HmrUpdateEvent = { file, type };\n\n if (this.hot) {\n this.hot.send('seedcord:hmr', payload);\n }\n }\n\n private hotUpdate(ctx: HotUpdateOptions): EnvironmentModuleNode[] {\n const { file, modules, server } = ctx;\n const type = 'update';\n\n if (this.isDebounced(file, type)) return [];\n\n const relPath = relative(process.cwd(), file);\n\n this.logger.info(`${chalk.blue(type.toUpperCase())} ${chalk.gray(relPath)}`);\n\n if (this.isCriticalFile(file)) {\n this.logger.warn(`${chalk.red('Critical file changed:')} ${chalk.bold(relPath)}. Restart required.`);\n this.emit('event', { type: 'restart-required' });\n return [];\n }\n\n const moduleGraph = server.moduleGraph;\n const fileModules = moduleGraph.getModulesByFile(file);\n const allModules = fileModules ? Array.from(fileModules) : [];\n\n const combinedModules = new Set([...modules, ...allModules]);\n const affectedModules = this.getAffectedModules(Array.from(combinedModules));\n\n const filesToInvalidate = new Set([file, ...affectedModules]);\n\n for (const fileToInvalidate of filesToInvalidate) {\n const mods = moduleGraph.getModulesByFile(fileToInvalidate);\n if (mods) {\n for (const mod of mods) {\n moduleGraph.invalidateModule(mod);\n }\n }\n }\n\n // file-change tells the runtime to invalidate this module in its evaluated-modules graph.\n this.emit('event', { type: 'file-change', path: file });\n\n const payload: HmrUpdateEvent = { file, type, affectedModules };\n\n if (this.hot) {\n this.hot.send('seedcord:hmr', payload);\n }\n\n // Returning [] suppresses Vite's default client HMR; invalidation runs through the runtime instead.\n return [];\n }\n\n private isCriticalFile(file: string): boolean {\n const root = this.config.root;\n const relPath = relative(root, file);\n\n if (this.config.hmr?.restart) {\n for (const pattern of this.config.hmr.restart) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n }\n\n for (const pattern of this.dynamicRestartPatterns) {\n if (minimatch(relPath, pattern)) {\n return true;\n }\n }\n\n if (\n file === this.config.configFile ||\n file.endsWith('package.json') ||\n file.endsWith('tsconfig.json') ||\n file.endsWith('.env')\n ) {\n return true;\n }\n\n const entryPath = resolve(root, this.config.entry);\n const instancePath = resolve(root, this.config.instance);\n\n if (file === entryPath || file === instancePath) {\n return true;\n }\n\n return false;\n }\n\n private getAffectedModules(modules: (EnvironmentModuleNode | ModuleNode)[]): string[] {\n const affected = new Set<string>();\n const seen = new Set<string>();\n\n const traverse = (mod: EnvironmentModuleNode | ModuleNode): void => {\n if (mod.file && !seen.has(mod.file)) {\n seen.add(mod.file);\n affected.add(mod.file);\n mod.importers.forEach(traverse);\n }\n };\n\n modules.forEach(traverse);\n return Array.from(affected);\n }\n}\n","import { defineConfig } from 'vite';\n\nexport default defineConfig({\n server: {\n middlewareMode: true,\n hmr: true,\n watch: {\n usePolling: false,\n ignored: ['**/node_modules/**', '**/dist/**']\n }\n },\n build: {\n ssr: true,\n outDir: 'dist',\n sourcemap: true,\n minify: false,\n rollupOptions: {\n output: {\n format: 'esm',\n preserveModules: true\n }\n }\n },\n ssr: {\n target: 'node',\n external: ['@seedcord/services'],\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n },\n environments: {\n ssr: {\n resolve: {\n conditions: ['node', 'import'],\n externalConditions: ['node']\n }\n }\n },\n future: {\n removeSsrLoadModule: 'warn',\n removePluginHookHandleHotUpdate: 'warn',\n removePluginHookSsrArgument: 'warn',\n removeServerModuleGraph: 'warn',\n removeServerReloadModule: 'warn',\n removeServerPluginContainer: 'warn',\n removeServerHot: 'warn',\n removeServerTransformRequest: 'warn',\n removeServerWarmupRequest: 'warn'\n },\n clearScreen: false,\n logLevel: 'error',\n appType: 'custom'\n});\n","import { relative } from 'node:path';\n\nimport { SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { createServer, createServerModuleRunner, mergeConfig } from 'vite';\nimport { EvaluatedModules } from 'vite/module-runner';\n\nimport { HmrPlugin } from './HmrPlugin';\nimport viteConfig from './vite.config';\n\nimport type { DevRuntime, DevRuntimeContext, DevRuntimeLoadResult } from './DevRuntime';\nimport type { DevEvent, DevEventHandler } from './events';\nimport type { ViteDevServer } from 'vite';\nimport type { ModuleRunner } from 'vite/module-runner';\n\nexport class ViteDevRuntime implements DevRuntime {\n private context: DevRuntimeContext | null = null;\n private viteServer: ViteDevServer | null = null;\n private moduleRunner: ModuleRunner | null = null;\n private eventHandler: DevEventHandler | null = null;\n private evaluatedModules: EvaluatedModules | null = null;\n private hmrPlugin: HmrPlugin | null = null;\n\n public async start(context: DevRuntimeContext): Promise<void> {\n this.context = context;\n this.eventHandler = context.onEvent ?? null;\n\n const projectRoot = this.context.config.root;\n\n this.emit({ type: 'module-loading', path: projectRoot });\n\n const hmrPlugin = new HmrPlugin(this.context.config);\n this.hmrPlugin = hmrPlugin;\n\n const config = mergeConfig(viteConfig, {\n root: projectRoot,\n plugins: [hmrPlugin.plugin]\n });\n\n this.viteServer = await createServer(config);\n\n this.evaluatedModules = new EvaluatedModules();\n this.moduleRunner = createServerModuleRunner(this.viteServer.environments.ssr, {\n evaluatedModules: this.evaluatedModules\n });\n\n hmrPlugin.on('event', this.handleHmrEvent.bind(this));\n\n this.emit({ type: 'module-loaded', path: projectRoot });\n this.emit({ type: 'ready' });\n }\n\n private handleHmrEvent(event: DevEvent): void {\n if (event.type === 'file-change') {\n this.invalidateModule(event.path);\n }\n this.emit(event);\n }\n\n private invalidateModule(file: string): void {\n const projectRoot = this.context?.config.root;\n if (!projectRoot || !this.evaluatedModules) return;\n\n const moduleId = toModuleId(projectRoot, file);\n const moduleNode = this.evaluatedModules.getModuleById(moduleId);\n if (moduleNode) {\n this.evaluatedModules.invalidateModule(moduleNode);\n }\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.hmrPlugin?.sendRefreshCommands(shouldRefresh);\n }\n\n public async loadEntry(): Promise<DevRuntimeLoadResult> {\n if (!this.context || !this.viteServer || !this.moduleRunner) {\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [\n this.context?.config.instance ?? 'runtime',\n 'ViteDevRuntime.start() must complete before loadEntry()'\n ]);\n }\n\n const { instance: entryPath } = this.context.config;\n const projectRoot = this.context.config.root;\n const startTime = performance.now();\n\n this.emit({ type: 'module-loading', path: entryPath });\n\n try {\n const moduleId = toModuleId(projectRoot, entryPath);\n\n const module = await this.moduleRunner.import<unknown>(moduleId);\n const loadTime = performance.now() - startTime;\n\n this.emit({ type: 'module-loaded', path: entryPath });\n\n return {\n module,\n metadata: {\n loadTime\n }\n };\n } catch (error: unknown) {\n this.emit({ type: 'module-error', path: entryPath, error });\n throw error;\n }\n }\n\n public async dispose(): Promise<void> {\n // Restart/disconnect dispose the runtime without exiting the process, so drop the runtime<->plugin\n // 'event' wiring and references or each new session would leak the prior one's listeners.\n this.hmrPlugin?.removeAllListeners('event');\n\n if (this.viteServer) {\n await this.viteServer.close();\n this.viteServer = null;\n }\n\n this.moduleRunner = null;\n this.evaluatedModules = null;\n this.hmrPlugin = null;\n this.context = null;\n this.eventHandler = null;\n }\n\n private emit(event: DevEvent): void {\n this.eventHandler?.(event);\n }\n}\n\n// Vite normalizes module ids to forward slashes; relative() yields backslashes on Windows, so normalize.\nfunction toModuleId(projectRoot: string, file: string): string {\n return `/${relative(projectRoot, file).replaceAll('\\\\', '/')}`;\n}\n","import { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { resolve } from 'node:path';\n\nimport { Logger } from '@seedcord/services';\n\nconst TSC_GRACEFUL_EXIT_MS = 2000;\n\nexport class TscRunner {\n private process: ChildProcess | null = null;\n private readonly logger: Logger;\n\n constructor(\n private readonly tsconfigPath?: string,\n private readonly cwd?: string\n ) {\n this.logger = new Logger('Typecheck', { channel: 'tsc' });\n }\n\n public start(): void {\n if (this.process) return;\n\n const tscPath = this.resolveProjectTsc();\n if (!tscPath) {\n this.logger.error('Unable to resolve \"typescript\". Install it in the project to enable tsc --watch.');\n return;\n }\n\n const args = [tscPath, '--noEmit', '--watch', '--preserveWatchOutput', '--pretty'];\n if (this.tsconfigPath) {\n args.push('--project', this.tsconfigPath);\n }\n\n this.logger.info('Starting tsc --watch...');\n\n this.process = spawn(process.execPath, args, {\n cwd: this.cwd ?? process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n this.process.stdout?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.info(line.trimEnd());\n }\n }\n });\n\n this.process.stderr?.on('data', (data: Buffer) => {\n const lines = data.toString().split('\\n');\n for (const line of lines) {\n if (line.trim()) {\n this.logger.error(line.trimEnd());\n }\n }\n });\n\n this.process.on('error', (err) => {\n this.logger.error(`Failed to start tsc: ${err.message}`);\n });\n\n this.process.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n this.logger.error(`tsc exited with code ${code}`);\n } else {\n this.logger.info('tsc exited.');\n }\n this.process = null;\n });\n }\n\n public stop(): void {\n const child = this.process;\n if (!child) return;\n\n this.logger.info('Stopping tsc...');\n child.kill('SIGTERM');\n\n // justified: tsc --watch can ignore SIGTERM when stdin is detached (Windows/some Node builds); escalate to SIGKILL after a grace window. unref so the timer never holds the event loop open.\n const killTimer = setTimeout(() => child.kill('SIGKILL'), TSC_GRACEFUL_EXIT_MS);\n killTimer.unref();\n child.once('exit', () => {\n clearTimeout(killTimer);\n });\n // The handle is nulled by the 'exit' listener in start(); leaving it set until exit prevents start() from spawning a second tsc over a still-dying one.\n }\n\n private resolveProjectTsc(): string | null {\n const projectDir = this.cwd ?? process.cwd();\n const manifest = resolve(projectDir, 'package.json');\n const projectRequire = existsSync(manifest) ? createRequire(manifest) : createRequire(import.meta.url);\n\n try {\n return projectRequire.resolve('typescript/bin/tsc');\n } catch {\n return null;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { Logger, SeedcordErrorCode } from '@seedcord/services';\nimport { SeedcordError } from '@seedcord/services/internal';\nimport { SeedcordBrand, type Brandable } from '@seedcord/types/internal';\n\nimport { CodegenRunner } from '@commands/codegen/CodegenRunner';\nimport { ConfigLoader } from '@core/config/ConfigLoader';\nimport { ConfigLocator } from '@core/config/ConfigLocator';\nimport { RuntimeModuleLoader } from '@core/modules/RuntimeModuleLoader';\nimport { resetChannelColors } from '@ui/channelColor';\nimport { resolveDefaultExport } from '@utils/resolveDefaultExport';\n\nimport { ViteDevRuntime } from './runtime/ViteDevRuntime';\nimport { TscRunner } from './TscRunner';\n\nimport type { DevRuntime } from './runtime/DevRuntime';\nimport type { ResolvedSeedcordDevConfig } from '@core/config/schema';\nimport type { ILogger, SeedcordInstance } from '@seedcord/types';\nimport type { DevStore } from '@ui/stores/DevStore';\n\nexport function isSeedcordInstance(candidate: unknown): candidate is SeedcordInstance {\n return typeof candidate === 'object' && candidate !== null && (candidate as Brandable)[SeedcordBrand] === true;\n}\n\nclass SeedcordDevSession {\n private stopResolve?: () => void;\n private instance?: SeedcordInstance;\n private isStopped = false;\n private startupPromise?: Promise<unknown>;\n private tscRunner?: TscRunner;\n private stopPromise?: Promise<void>;\n\n constructor(\n private readonly config: ResolvedSeedcordDevConfig,\n private readonly runtime: DevRuntime,\n private readonly store: DevStore\n ) {}\n\n private async loadInstanceModule(): Promise<unknown> {\n await this.runtime.start({\n config: this.config,\n onEvent: (event) => {\n this.store.apply(event);\n }\n });\n\n // detect a missing entry by path rather than vite's error message, because that wording changed across a minor and broke detection.\n if (!existsSync(this.config.instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliEntryNotFound, [this.config.instance]);\n }\n\n try {\n const { module } = await this.runtime.loadEntry();\n return module;\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, message]);\n }\n }\n\n public async start(onReady?: () => void): Promise<void> {\n const cwd = dirname(this.config.configFile);\n this.tscRunner = new TscRunner(this.config.tsconfig, cwd);\n this.tscRunner.start();\n\n const module = await this.loadInstanceModule();\n const exported = resolveDefaultExport(module);\n const instance = await Promise.resolve(exported);\n\n if (!isSeedcordInstance(instance)) {\n throw new SeedcordError(SeedcordErrorCode.CliInstanceInvalid);\n }\n\n this.instance = instance;\n this.store.setConfig(instance.config);\n\n try {\n this.store.setPhase('starting');\n this.store.setStatus('Starting Seedcord instance...');\n this.startupPromise = Promise.resolve(instance.start());\n await this.startupPromise;\n\n if (this.isStopped) {\n return;\n }\n\n this.store.setPhase('running');\n this.store.setStatus('Seedcord is running.');\n onReady?.();\n\n // Block until stop() is called (by a UI action or the single signal handler in DevCommand). The session\n // registers no process-signal handlers itself, so restarts never accumulate listeners.\n await new Promise<void>((resolve) => {\n this.stopResolve = resolve;\n });\n } catch (error: unknown) {\n const reason = error instanceof Error ? error.message : 'Unknown error';\n throw new SeedcordError(SeedcordErrorCode.CliStartFailed, [this.config.instance, reason]);\n }\n }\n\n // quit(), restart(), and disconnect() all call stop(), and the run loop's finally calls dispose() which calls stop() again, so memoize to run the abort and shutdown sequence exactly once.\n public async stop(): Promise<void> {\n this.stopPromise ??= this.runStop();\n return this.stopPromise;\n }\n\n private async runStop(): Promise<void> {\n this.isStopped = true;\n this.tscRunner?.stop();\n this.instance?.startup.abort();\n\n if (this.startupPromise) {\n // stop() already triggered startup.abort(), so a rejection here is that abort, not a fresh failure (real\n // startup failures surface through start()'s own catch). Awaiting drains it so teardown stays ordered.\n try {\n await this.startupPromise;\n } catch {\n /* drained: see above */\n }\n }\n\n await this.instance?.shutdown.run(0, false);\n this.stopResolve?.();\n }\n\n public async dispose(): Promise<void> {\n await this.stop();\n await this.runtime.dispose();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n this.runtime.refreshCommands?.(shouldRefresh);\n }\n}\n\n/**\n * Coordinates config discovery, loading, and starting a Seedcord instance.\n */\nexport class DevRunner {\n private currentSession: SeedcordDevSession | null = null;\n private signalResolve?: () => void;\n private shouldQuit = false;\n private isDisconnected = false;\n private isRunning = false;\n private isRegenerating = false;\n\n constructor(\n private readonly locator: ConfigLocator,\n private readonly configLoader: ConfigLoader,\n private readonly store: DevStore,\n private readonly codegen: CodegenRunner,\n private readonly codegenLogger: ILogger\n ) {}\n\n public static create(logger: ILogger, store: DevStore): DevRunner {\n const moduleLoader = new RuntimeModuleLoader();\n const locator = new ConfigLocator(logger);\n const configLoader = new ConfigLoader(moduleLoader, logger);\n const codegenLogger = new Logger('CLI:Codegen');\n\n return new DevRunner(locator, configLoader, store, CodegenRunner.create(codegenLogger), codegenLogger);\n }\n\n public async run(): Promise<void> {\n if (this.isRunning) return;\n this.isRunning = true;\n\n try {\n while (!this.shouldQuit) {\n try {\n if (this.isDisconnected) {\n await this.handleDisconnected();\n continue;\n }\n\n await this.runSession();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- quit() flips shouldQuit during the awaited session; TS narrows it to false from the loop guard and can't see the async cross-method mutation\n if (this.shouldQuit) break;\n await this.handleError(error);\n }\n }\n } finally {\n this.isRunning = false;\n }\n }\n\n private async handleDisconnected(): Promise<void> {\n this.store.setPhase('disconnected');\n this.store.setStatus('Disconnected. Press r to restart.');\n this.store.setBusy(false);\n await this.waitForSignal();\n this.store.setBusy(true);\n if (!this.shouldQuit) {\n this.isDisconnected = false;\n }\n }\n\n private async runSession(): Promise<void> {\n resetChannelColors();\n this.store.setPhase('starting');\n this.store.setBusy(true);\n const config = await this.loadConfig();\n const runtime = new ViteDevRuntime();\n this.currentSession = new SeedcordDevSession(config, runtime, this.store);\n\n try {\n await this.currentSession.start(() => {\n this.store.setBusy(false);\n });\n } finally {\n this.store.setBusy(true);\n await this.currentSession.dispose();\n this.currentSession = null;\n }\n }\n\n private async handleError(error: unknown): Promise<void> {\n this.store.setPhase('error');\n this.store.setError(error instanceof Error ? error : new Error(String(error)));\n this.store.setStatus('Error occurred. Press r to restart.');\n this.store.setBusy(false);\n await this.waitForSignal();\n this.store.setBusy(true);\n }\n\n public async quit(): Promise<void> {\n this.shouldQuit = true;\n this.store.setPhase('quitting');\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public async restart(): Promise<void> {\n this.isDisconnected = false;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public async disconnect(): Promise<void> {\n // Already parked in the disconnected wait, waking the signal here would fall through and start a\n // fresh session (i.e. behave like restart). No live session means nothing to disconnect.\n if (this.isDisconnected) return;\n this.isDisconnected = true;\n await this.currentSession?.stop();\n this.signalResolve?.();\n }\n\n public refreshCommands(shouldRefresh: boolean): void {\n if (shouldRefresh) void this.regenerateRegistry();\n this.currentSession?.refreshCommands(shouldRefresh);\n }\n\n // an accepted refresh means the command files changed, so regenerate the typed registry alongside the\n // bot's re-registration, and tsc picks up the new option types when it finishes. codegen throws instead of\n // logging its own failures, so surface one here and leave the dev session running.\n private async regenerateRegistry(): Promise<void> {\n if (this.isRegenerating) return;\n this.isRegenerating = true;\n try {\n await this.codegen.run(false);\n } catch (error: unknown) {\n this.codegenLogger.error('Command registry regeneration failed', error);\n } finally {\n this.isRegenerating = false;\n }\n }\n\n private async waitForSignal(): Promise<void> {\n return new Promise<void>((resolve) => {\n this.signalResolve = resolve;\n });\n }\n\n public async loadConfig(): Promise<ResolvedSeedcordDevConfig> {\n const configPath = this.locator.locate();\n return this.configLoader.load(configPath);\n }\n}\n","import { LoggerChannelRegistry } from '@seedcord/services';\nimport { formatFilePath } from '@seedcord/utils';\nimport { render } from 'ink';\nimport React from 'react';\n\nimport { BaseCommand } from '@core/BaseCommand';\nimport { DevApp } from '@ui/DevApp';\nimport { DevStore } from '@ui/stores/DevStore';\nimport { LogStore } from '@ui/stores/LogStore';\nimport { SilentLogger } from '@utils/SilentLogger';\n\nimport { DevRunner } from './DevRunner';\n\nimport type { Command } from '@commander-js/extra-typings';\n\nexport class DevCommand extends BaseCommand {\n private readonly runner: DevRunner;\n private readonly store: DevStore;\n\n constructor() {\n super('dev', 'Run a Seedcord instance from the config file', 'CLI:Dev');\n this.store = new DevStore();\n this.runner = DevRunner.create(new SilentLogger(), this.store);\n }\n\n public register(program: Command): void {\n program\n .command(this.name)\n .description(this.description)\n .action(async () => {\n // SIGTERM (and SIGINT when stdin is not raw) trigger a graceful quit; Ink handles the raw-mode\n // Ctrl-C keypress itself. once() self-removes; the finally removes them on a normal exit.\n const onSignal = (): void => {\n void this.runner.quit();\n };\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n\n try {\n await this.runDevApp();\n } catch (error: unknown) {\n this.logger.error('Seedcord dev failed', error);\n process.exitCode = 1;\n } finally {\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n\n // The alternate screen has been restored by now, so this lands in the normal terminal: a\n // pointer to the on-disk log file, since the in-UI logs are gone once the UI unmounts.\n this.printLogLocation();\n\n // Ink's raw-mode stdin and the Vite dev server keep the event loop alive after teardown;\n // runDevApp already awaited unmount + shutdown, so exit explicitly instead of hanging.\n process.exit();\n });\n }\n\n private printLogLocation(): void {\n const registry = LoggerChannelRegistry.instance;\n const path = registry.getLogFilePath(registry.getDefaultChannel());\n if (path) process.stdout.write(`seedcord dev stopped. logs: ${formatFilePath(path)}\\n`);\n }\n\n private async runDevApp(): Promise<void> {\n let runResult: Promise<void> = Promise.resolve();\n\n const { unmount, waitUntilExit } = render(\n React.createElement(DevApp, {\n store: this.store,\n onQuit: () => this.runner.quit(),\n onDisconnect: () => this.runner.disconnect(),\n onRestart: () => this.runner.restart(),\n onRefreshCommands: (shouldRefresh: boolean) => this.runner.refreshCommands(shouldRefresh),\n onReady: () => {\n runResult = this.runner.run().finally(async () => {\n // Drain buffered logs before unmounting Ink so the final lines aren't dropped.\n await LogStore.instance.flush();\n unmount();\n });\n }\n }),\n // Alternate screen (like vim/lazygit): the original terminal + scrollback are restored on quit,\n // and Ink's ESC[3J scrollback purge never fires.\n { exitOnCtrlC: false, alternateScreen: true }\n );\n\n await waitUntilExit();\n // Surface a run-loop rejection through the action's try/catch instead of racing process.exit().\n await runResult;\n }\n}\n","import { Command } from '@commander-js/extra-typings';\nimport { Logger } from '@seedcord/services';\n\nimport { BuildCommand } from '@commands/build/BuildCommand';\nimport { CodegenCommand } from '@commands/codegen/CodegenCommand';\nimport { DevCommand } from '@commands/dev/DevCommand';\n\nimport { version } from '.';\n\nconst LOGGER_LABEL = 'Seedcord CLI';\n\nasync function main(): Promise<void> {\n if (!process.env.ENV && !process.env.ENVIRONMENT && !process.env.NODE_ENV) {\n process.env.NODE_ENV = 'development';\n }\n\n const program = new Command().name('seedcord').description('Seedcord CLI').version(version);\n\n new DevCommand().register(program);\n new BuildCommand().register(program);\n new CodegenCommand().register(program);\n\n await program.parseAsync(process.argv);\n}\n\nvoid main().catch((error) => {\n const logger = new Logger(LOGGER_LABEL);\n logger.error('Unexpected CLI error', error);\n process.exit(1);\n});\n"],"mappings":"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"}