devsurface 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/doctor.ts","../../src/core/doctor/index.ts","../../src/core/scanner/index.ts","../../src/core/config/load.ts","../../src/core/config/defaults.ts","../../src/core/scanner/docker.ts","../../src/core/process/executable.ts","../../src/core/scanner/env.ts","../../src/core/scanner/framework.ts","../../src/core/scanner/git.ts","../../src/core/scanner/packageManager.ts","../../src/core/scanner/packageJson.ts","../../src/core/scanner/ports.ts","../../src/core/scanner/scripts.ts","../../src/cli/commands/init.ts","../../src/cli/commands/run.ts","../../src/core/process/runner.ts","../../src/cli/commands/scan.ts","../../src/cli/commands/start.ts","../../src/server/index.ts","../../src/core/process/manager.ts","../../src/server/routes/api.ts","../../src/server/localAccess.ts","../../src/server/routes/ws.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { doctorCommand } from './commands/doctor.js';\nimport { initCommand } from './commands/init.js';\nimport { runCommand } from './commands/run.js';\nimport { scanCommand } from './commands/scan.js';\nimport { startCommand } from './commands/start.js';\n\nconst program = new Command();\n\nfunction toPort(value: string): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port <= 0 || port > 65535) {\n throw new Error('Port must be an integer between 1 and 65535.');\n }\n\n return port;\n}\n\nfunction handle(command: Promise<void>): void {\n command.catch((error) => {\n const message = error instanceof Error ? error.message : String(error);\n console.error(message);\n process.exitCode = 1;\n });\n}\n\nprogram\n .name('devsurface')\n .description('Turn any Node.js repository into a local developer control panel.')\n .version('0.1.0')\n .option('-p, --port <port>', 'dashboard port', toPort, 4567)\n .option('--no-open', 'do not open the browser automatically')\n .action((options: { port: number; open: boolean }) => {\n handle(\n startCommand({\n cwd: process.cwd(),\n port: options.port,\n openBrowser: options.open\n })\n );\n });\n\nprogram\n .command('scan')\n .description('Print detected project info.')\n .action(() => {\n handle(scanCommand(process.cwd()));\n });\n\nprogram\n .command('doctor')\n .description('Print setup health warnings.')\n .action(() => {\n handle(doctorCommand(process.cwd()));\n });\n\nprogram\n .command('init')\n .description('Create a starter devsurface.config.json.')\n .action(() => {\n handle(initCommand(process.cwd()));\n });\n\nprogram\n .command('run')\n .argument('<script>', 'package.json script to run')\n .description('Run a package script and stream logs.')\n .action((script: string) => {\n handle(runCommand(script, process.cwd()));\n });\n\nawait program.parseAsync(process.argv);\n","import pc from 'picocolors';\nimport { runDoctor } from '../../core/doctor/index.js';\n\nfunction colorSeverity(severity: 'error' | 'warning' | 'info'): string {\n if (severity === 'error') {\n return pc.red('error');\n }\n\n if (severity === 'warning') {\n return pc.yellow('warning');\n }\n\n return pc.cyan('info');\n}\n\nexport async function doctorCommand(cwd = process.cwd()): Promise<void> {\n const warnings = await runDoctor(cwd);\n\n if (warnings.length === 0) {\n console.log(pc.green('No health warnings found.'));\n return;\n }\n\n for (const item of warnings) {\n console.log(`${colorSeverity(item.severity)} ${pc.bold(item.title)}`);\n console.log(` ${item.message}`);\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { DoctorWarning, ScanResult } from '../types.js';\nimport { scanProject } from '../scanner/index.js';\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function readIfPresent(filePath: string | null): Promise<string | null> {\n if (filePath === null) {\n return null;\n }\n\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n}\n\nfunction extractReadmeScriptReferences(readmeContent: string): string[] {\n const references = new Set<string>();\n const commandRegexes = [\n /\\bnpm\\s+run\\s+([A-Za-z0-9:_-]+)/g,\n /\\bpnpm\\s+run\\s+([A-Za-z0-9:_-]+)/g,\n /\\bbun\\s+run\\s+([A-Za-z0-9:_-]+)/g,\n /\\byarn\\s+run\\s+([A-Za-z0-9:_-]+)/g,\n /\\bnpm\\s+(test|start|build)\\b/g,\n /\\bpnpm\\s+(test|start|build)\\b/g,\n /\\byarn\\s+(test|start|build)\\b/g,\n /\\bbun\\s+(test|start|build)\\b/g\n ];\n\n for (const regex of commandRegexes) {\n for (const match of readmeContent.matchAll(regex)) {\n references.add(match[1]);\n }\n }\n\n return Array.from(references);\n}\n\nfunction warning(\n id: string,\n severity: DoctorWarning['severity'],\n title: string,\n message: string,\n target?: string\n): DoctorWarning {\n return { id, severity, title, message, target };\n}\n\nexport async function runDoctor(root = process.cwd(), scan?: ScanResult): Promise<DoctorWarning[]> {\n const result = scan ?? (await scanProject(root));\n const warnings: DoctorWarning[] = [];\n\n for (const configWarning of result.config?.warnings ?? []) {\n warnings.push(\n warning('config-warning', 'warning', 'Config warning', configWarning, result.config?.path)\n );\n }\n\n if (result.packageJson === null) {\n warnings.push(\n warning(\n 'missing-package-json',\n 'error',\n 'No package.json',\n 'This directory is not a Node.js project.'\n )\n );\n return warnings;\n }\n\n if (!(await pathExists(path.join(root, 'node_modules', '.bin')))) {\n warnings.push(\n warning(\n 'missing-node-modules',\n 'warning',\n 'Dependencies are not installed',\n 'node_modules/.bin is missing. Run the project install command before starting scripts.'\n )\n );\n }\n\n if (result.env?.hasExample && !result.env.hasLocal) {\n warnings.push(\n warning(\n 'missing-env',\n 'error',\n '.env is missing',\n '.env.example exists, but the local .env file is missing.',\n result.env.examplePath ?? undefined\n )\n );\n }\n\n if (result.env && result.env.missingKeys.length > 0 && result.env.hasLocal) {\n warnings.push(\n warning(\n 'missing-env-keys',\n 'warning',\n 'Environment keys are missing',\n `Missing keys: ${result.env.missingKeys.join(', ')}. Values are intentionally hidden.`\n )\n );\n }\n\n if (result.env && result.env.emptyKeys.length > 0) {\n warnings.push(\n warning(\n 'empty-env-keys',\n 'info',\n 'Environment keys are empty',\n `Empty keys: ${result.env.emptyKeys.join(', ')}. Values are intentionally hidden.`\n )\n );\n }\n\n const missingReadme = !result.readme.exists;\n if (missingReadme) {\n warnings.push(\n warning('missing-readme', 'warning', 'No README', 'No README.md or README file was found.')\n );\n } else {\n const readme = await readIfPresent(result.readme.path);\n if (readme !== null) {\n const references = extractReadmeScriptReferences(readme);\n const missingScripts = references.filter((script) => result.scripts[script] === undefined);\n if (missingScripts.length > 0) {\n warnings.push(\n warning(\n 'readme-script-mismatch',\n 'warning',\n 'README references missing scripts',\n `README mentions scripts not present in package.json: ${missingScripts.join(', ')}.`\n )\n );\n }\n }\n }\n\n for (const port of result.ports.filter((probe) => probe.inUse)) {\n warnings.push(\n warning(\n `port-${port.port}-in-use`,\n 'error',\n `Port ${port.port} is already in use`,\n `Something is already bound to 127.0.0.1:${port.port}.`\n )\n );\n }\n\n if (result.docker && result.docker.dockerRunning === false) {\n warnings.push(\n warning(\n 'docker-not-running',\n 'warning',\n 'Docker Compose found but Docker is not running',\n 'A compose file exists, but the Docker daemon did not answer docker info.'\n )\n );\n }\n\n if (result.scripts.test === undefined) {\n warnings.push(\n warning(\n 'missing-test-script',\n 'warning',\n 'No test script',\n 'package.json does not define a test script.'\n )\n );\n }\n\n if (result.scripts.build === undefined) {\n warnings.push(\n warning(\n 'missing-build-script',\n 'warning',\n 'No build script',\n 'package.json does not define a build script.'\n )\n );\n }\n\n if (!result.license.exists) {\n warnings.push(warning('missing-license', 'info', 'No LICENSE', 'No LICENSE file was found.'));\n }\n\n return warnings;\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { FilePresence, ScanResult } from '../types.js';\nimport { loadConfig } from '../config/load.js';\nimport { detectDocker } from './docker.js';\nimport { detectEnv } from './env.js';\nimport { detectFramework } from './framework.js';\nimport { detectGit } from './git.js';\nimport { detectPackageManager } from './packageManager.js';\nimport { readPackageJson } from './packageJson.js';\nimport { defaultPortsForFramework, detectPorts, inferPortsFromScripts } from './ports.js';\nimport { extractScripts } from './scripts.js';\n\nasync function findFirstFile(root: string, candidates: string[]): Promise<FilePresence> {\n for (const candidate of candidates) {\n const filePath = path.join(root, candidate);\n try {\n const stat = await fs.stat(filePath);\n if (stat.isFile()) {\n return { path: filePath, exists: true };\n }\n } catch {\n // Keep looking through the candidate list.\n }\n }\n\n return { path: null, exists: false };\n}\n\nfunction configuredPorts(configPorts: number[] | undefined): number[] {\n return Array.isArray(configPorts) ? configPorts : [];\n}\n\nexport async function scanProject(root = process.cwd()): Promise<ScanResult> {\n const config = await loadConfig(root);\n const packageJson = await readPackageJson(root);\n const scripts = extractScripts(packageJson) ?? {};\n const framework = detectFramework(packageJson);\n const portsToProbe = [\n ...configuredPorts(config?.config.ports),\n ...inferPortsFromScripts(scripts),\n ...defaultPortsForFramework(framework)\n ];\n\n const [packageManager, env, docker, git, ports, readme, license] = await Promise.all([\n detectPackageManager(root),\n detectEnv(root, config?.config),\n detectDocker(root),\n detectGit(root),\n detectPorts(portsToProbe),\n findFirstFile(root, ['README.md', 'README']),\n findFirstFile(root, ['LICENSE', 'LICENSE.md', 'COPYING'])\n ]);\n\n return {\n root,\n projectName: config?.config.name ?? packageJson?.data.name ?? path.basename(root),\n packageJson,\n packageManager: packageManager ?? (packageJson ? 'npm' : null),\n scripts,\n env,\n docker,\n git,\n framework,\n ports: ports ?? [],\n readme,\n license,\n config\n };\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { ConfigLoadResult, DevSurfaceConfig } from '../types.js';\nimport { CONFIG_FILE_NAME } from './defaults.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction toStringRecord(\n value: unknown,\n warnings: string[],\n label: string\n): Record<string, string> | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (!isRecord(value)) {\n warnings.push(`${label} must be an object.`);\n return undefined;\n }\n\n const record: Record<string, string> = {};\n for (const [key, raw] of Object.entries(value)) {\n if (typeof raw === 'string') {\n record[key] = raw;\n } else {\n warnings.push(`${label}.${key} must be a string.`);\n }\n }\n\n return record;\n}\n\nfunction toGroups(value: unknown, warnings: string[]): Record<string, string[]> | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (!isRecord(value)) {\n warnings.push('groups must be an object.');\n return undefined;\n }\n\n const groups: Record<string, string[]> = {};\n for (const [key, raw] of Object.entries(value)) {\n if (Array.isArray(raw) && raw.every((entry) => typeof entry === 'string')) {\n groups[key] = raw;\n } else {\n warnings.push(`groups.${key} must be an array of command names.`);\n }\n }\n\n return groups;\n}\n\nfunction toPorts(value: unknown, warnings: string[]): number[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n if (!Array.isArray(value)) {\n warnings.push('ports must be an array of numbers.');\n return undefined;\n }\n\n const ports = value.filter(\n (port): port is number => Number.isInteger(port) && port > 0 && port < 65536\n );\n if (ports.length !== value.length) {\n warnings.push('ports may only contain integers between 1 and 65535.');\n }\n\n return ports;\n}\n\nexport function validateConfig(raw: unknown): { config: DevSurfaceConfig; warnings: string[] } {\n const warnings: string[] = [];\n if (!isRecord(raw)) {\n return { config: {}, warnings: ['devsurface.config.json must contain a JSON object.'] };\n }\n\n const env = isRecord(raw.env)\n ? {\n example: typeof raw.env.example === 'string' ? raw.env.example : undefined,\n local: typeof raw.env.local === 'string' ? raw.env.local : undefined\n }\n : undefined;\n\n if (raw.env !== undefined && !isRecord(raw.env)) {\n warnings.push('env must be an object.');\n }\n\n const services = isRecord(raw.services)\n ? {\n docker: typeof raw.services.docker === 'boolean' ? raw.services.docker : undefined\n }\n : undefined;\n\n if (raw.services !== undefined && !isRecord(raw.services)) {\n warnings.push('services must be an object.');\n }\n\n return {\n config: {\n name: typeof raw.name === 'string' ? raw.name : undefined,\n description: typeof raw.description === 'string' ? raw.description : undefined,\n commands: toStringRecord(raw.commands, warnings, 'commands'),\n groups: toGroups(raw.groups, warnings),\n ports: toPorts(raw.ports, warnings),\n env,\n services,\n docs: typeof raw.docs === 'string' ? raw.docs : undefined\n },\n warnings\n };\n}\n\nexport async function loadConfig(root: string): Promise<ConfigLoadResult | null> {\n const configPath = path.join(root, CONFIG_FILE_NAME);\n\n try {\n const content = await fs.readFile(configPath, 'utf8');\n const parsed = JSON.parse(content) as unknown;\n const { config, warnings } = validateConfig(parsed);\n return { path: configPath, config, warnings };\n } catch (error) {\n const code =\n typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'ENOENT') {\n return null;\n }\n\n if (error instanceof SyntaxError) {\n return {\n path: configPath,\n config: {},\n warnings: [`${CONFIG_FILE_NAME} contains invalid JSON.`]\n };\n }\n\n return null;\n }\n}\n","import type { DevSurfaceConfig } from '../types.js';\n\nexport const CONFIG_FILE_NAME = 'devsurface.config.json';\n\nexport const defaultConfig: DevSurfaceConfig = {\n name: 'My App',\n description: 'Local developer control panel',\n commands: {\n install: 'npm install',\n dev: 'npm run dev',\n build: 'npm run build',\n test: 'npm test',\n lint: 'npm run lint'\n },\n groups: {\n Setup: ['install'],\n Development: ['dev'],\n Quality: ['test', 'lint'],\n Build: ['build']\n },\n ports: [3000],\n env: {\n example: '.env.example',\n local: '.env'\n },\n services: {\n docker: true\n },\n docs: ''\n};\n","import { promises as fs } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport spawn from 'cross-spawn';\nimport { parse as parseYaml } from 'yaml';\nimport { resolveExecutableOutsideRoot } from '../process/executable.js';\nimport type { DockerInfo, DockerServiceInfo } from '../types.js';\n\nconst COMPOSE_FILES = ['docker-compose.yml', 'docker-compose.yaml', 'compose.yml', 'compose.yaml'];\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function getComposeFiles(root: string): Promise<string[]> {\n const checks = await Promise.all(\n COMPOSE_FILES.map(async (file) => {\n const filePath = path.join(root, file);\n return (await fileExists(filePath)) ? filePath : null;\n })\n );\n\n return checks.filter((filePath): filePath is string => filePath !== null);\n}\n\nasync function extractServices(composePath: string): Promise<string[]> {\n try {\n const content = await fs.readFile(composePath, 'utf8');\n const parsed = parseYaml(content) as unknown;\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'services' in parsed &&\n typeof parsed.services === 'object' &&\n parsed.services !== null\n ) {\n return Object.keys(parsed.services);\n }\n } catch {\n return [];\n }\n\n return [];\n}\n\nfunction isWithinRoot(root: string, target: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(target));\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nfunction dockerCommandCwd(root: string): string {\n const candidates = [os.homedir(), os.tmpdir(), path.parse(path.resolve(root)).root];\n return candidates.find((candidate) => !isWithinRoot(root, candidate)) ?? os.homedir();\n}\n\nasync function runDockerCommand(\n root: string,\n args: string[],\n timeoutMs = 2500\n): Promise<{ code: number | null; stdout: string; stderr: string }> {\n const dockerExecutable = await resolveExecutableOutsideRoot(root, 'docker');\n if (dockerExecutable === null) {\n return { code: null, stdout: '', stderr: '' };\n }\n\n return await new Promise((resolve) => {\n const child = spawn(dockerExecutable, args, {\n cwd: dockerCommandCwd(root),\n windowsHide: true\n });\n let settled = false;\n let stdout = '';\n let stderr = '';\n\n const timeout = setTimeout(() => {\n settled = true;\n child.kill();\n resolve({ code: null, stdout, stderr });\n }, timeoutMs);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n\n child.on('error', () => {\n clearTimeout(timeout);\n if (!settled) {\n settled = true;\n resolve({ code: null, stdout, stderr });\n }\n });\n\n child.on('close', (code) => {\n clearTimeout(timeout);\n if (!settled) {\n settled = true;\n resolve({ code, stdout, stderr });\n }\n });\n });\n}\n\nexport async function isDockerRunning(root: string): Promise<boolean> {\n const result = await runDockerCommand(root, ['info']);\n return result.code === 0;\n}\n\nfunction parseComposePs(output: string): Map<string, DockerServiceInfo> {\n const statuses = new Map<string, DockerServiceInfo>();\n const compactOutput = output.trim();\n if (!compactOutput) {\n return statuses;\n }\n\n try {\n const parsed = JSON.parse(compactOutput) as unknown;\n const rows = Array.isArray(parsed) ? parsed : [parsed];\n for (const row of rows) {\n addComposeStatusRow(statuses, row);\n }\n return statuses;\n } catch {\n // Older Docker Compose builds can write one JSON object per line.\n }\n\n const rows = compactOutput\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(Boolean);\n\n for (const row of rows) {\n try {\n const parsed = JSON.parse(row) as {\n Service?: unknown;\n State?: unknown;\n ID?: unknown;\n };\n addComposeStatusRow(statuses, parsed);\n } catch {\n return statuses;\n }\n }\n\n return statuses;\n}\n\nfunction addComposeStatusRow(statuses: Map<string, DockerServiceInfo>, row: unknown): void {\n if (typeof row !== 'object' || row === null) {\n return;\n }\n\n const record = row as {\n Service?: unknown;\n State?: unknown;\n ID?: unknown;\n };\n if (typeof record.Service !== 'string') {\n return;\n }\n\n const state = typeof record.State === 'string' ? record.State.toLowerCase() : '';\n statuses.set(record.Service, {\n name: record.Service,\n status: state === 'running' ? 'running' : state ? 'stopped' : 'unknown',\n containerId: typeof record.ID === 'string' && record.ID.length > 0 ? record.ID : null\n });\n}\n\nasync function getServiceStatuses(\n root: string,\n serviceNames: string[],\n dockerRunning: boolean\n): Promise<DockerServiceInfo[]> {\n if (serviceNames.length === 0) {\n return [];\n }\n\n if (!dockerRunning) {\n return serviceNames.map((service) => ({\n name: service,\n status: 'unknown',\n containerId: null\n }));\n }\n\n const ps = await runDockerCommand(root, [\n 'compose',\n '--project-directory',\n root,\n 'ps',\n '--format',\n 'json'\n ]);\n const statuses = ps.code === 0 ? parseComposePs(ps.stdout) : new Map<string, DockerServiceInfo>();\n\n return serviceNames.map(\n (service) =>\n statuses.get(service) ?? {\n name: service,\n status: 'stopped',\n containerId: null\n }\n );\n}\n\nexport async function detectDocker(root: string): Promise<DockerInfo | null> {\n const composeFiles = await getComposeFiles(root);\n if (composeFiles.length === 0) {\n return null;\n }\n\n const serviceLists = await Promise.all(\n composeFiles.map((composeFile) => extractServices(composeFile))\n );\n const serviceNames = Array.from(new Set(serviceLists.flat()));\n const dockerRunning = await isDockerRunning(root);\n\n return {\n composeFiles,\n services: await getServiceStatuses(root, serviceNames, dockerRunning),\n dockerRunning\n };\n}\n","import { constants } from 'node:fs';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\n\nfunction isWithinRoot(root: string, target: string): boolean {\n const resolvedRoot = path.resolve(root);\n const resolvedTarget = path.resolve(target);\n const relative = path.relative(resolvedRoot, resolvedTarget);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nfunction pathEntries(pathValue: string): string[] {\n return pathValue\n .split(path.delimiter)\n .map((entry) => entry.trim().replace(/^\"|\"$/g, ''))\n .filter((entry) => entry.length > 0);\n}\n\nfunction hasPathSeparator(command: string): boolean {\n return command.includes('/') || command.includes('\\\\');\n}\n\nfunction executableNames(command: string): string[] {\n if (process.platform !== 'win32' || path.extname(command)) {\n return [command];\n }\n\n const extensions = (process.env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD')\n .split(';')\n .map((extension) => extension.trim().toLowerCase())\n .filter(Boolean);\n return extensions.map((extension) => `${command}${extension}`);\n}\n\nasync function executableOutsideRoot(root: string, candidate: string): Promise<string | null> {\n if (isWithinRoot(root, candidate)) {\n return null;\n }\n\n try {\n const [realRoot, realCandidate] = await Promise.all([\n fs.realpath(root),\n fs.realpath(candidate)\n ]);\n if (isWithinRoot(realRoot, realCandidate)) {\n return null;\n }\n\n await fs.access(realCandidate, constants.X_OK);\n return realCandidate;\n } catch {\n return null;\n }\n}\n\nexport async function resolveExecutableOutsideRoot(\n root: string,\n command: string\n): Promise<string | null> {\n if (path.isAbsolute(command) || hasPathSeparator(command)) {\n return await executableOutsideRoot(root, path.resolve(command));\n }\n\n for (const entry of pathEntries(process.env.PATH ?? '')) {\n const directory = path.resolve(entry);\n if (isWithinRoot(root, directory)) {\n continue;\n }\n\n for (const executableName of executableNames(command)) {\n const executable = await executableOutsideRoot(root, path.join(directory, executableName));\n if (executable !== null) {\n return executable;\n }\n }\n }\n\n return null;\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { DevSurfaceConfig, EnvInfo } from '../types.js';\n\ninterface ParsedEnv {\n keys: string[];\n emptyKeys: string[];\n}\n\nasync function readIfPresent(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf8');\n } catch {\n return null;\n }\n}\n\nfunction resolveInsideRoot(root: string, configuredPath: string): string | null {\n const resolvedRoot = path.resolve(root);\n const resolvedPath = path.resolve(resolvedRoot, configuredPath);\n const relative = path.relative(resolvedRoot, resolvedPath);\n const insideRoot = relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n return insideRoot ? resolvedPath : null;\n}\n\nasync function resolveExistingInsideRoot(\n root: string,\n configuredPath: string\n): Promise<string | null> {\n const candidate = resolveInsideRoot(root, configuredPath);\n if (candidate === null) {\n return null;\n }\n\n try {\n const [realRoot, realCandidate] = await Promise.all([\n fs.realpath(root),\n fs.realpath(candidate)\n ]);\n const relative = path.relative(realRoot, realCandidate);\n const insideRoot =\n relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n return insideRoot ? candidate : null;\n } catch {\n return null;\n }\n}\n\nexport function parseEnvKeys(content: string): ParsedEnv {\n const keys: string[] = [];\n const emptyKeys: string[] = [];\n\n for (const rawLine of content.split(/\\r?\\n/)) {\n const line = rawLine.trim();\n if (!line || line.startsWith('#')) {\n continue;\n }\n\n const normalized = line.startsWith('export ') ? line.slice('export '.length).trim() : line;\n const separator = normalized.indexOf('=');\n if (separator <= 0) {\n continue;\n }\n\n const key = normalized.slice(0, separator).trim();\n const value = normalized.slice(separator + 1).trim();\n if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {\n keys.push(key);\n if (value.length === 0 || value === '\"\"' || value === \"''\") {\n emptyKeys.push(key);\n }\n }\n }\n\n return { keys: Array.from(new Set(keys)), emptyKeys: Array.from(new Set(emptyKeys)) };\n}\n\nexport async function detectEnv(\n root: string,\n config?: DevSurfaceConfig | null\n): Promise<EnvInfo | null> {\n const exampleName = config?.env?.example ?? '.env.example';\n const localName = config?.env?.local ?? '.env';\n const [examplePath, localPath] = await Promise.all([\n resolveExistingInsideRoot(root, exampleName),\n resolveExistingInsideRoot(root, localName)\n ]);\n const [exampleContent, localContent] = await Promise.all([\n examplePath === null ? null : readIfPresent(examplePath),\n localPath === null ? null : readIfPresent(localPath)\n ]);\n\n if (exampleContent === null && localContent === null) {\n return null;\n }\n\n const example =\n exampleContent === null ? { keys: [], emptyKeys: [] } : parseEnvKeys(exampleContent);\n const local = localContent === null ? { keys: [], emptyKeys: [] } : parseEnvKeys(localContent);\n const localKeySet = new Set(local.keys);\n const localEmptySet = new Set(local.emptyKeys);\n const missingKeys = example.keys.filter((key) => !localKeySet.has(key));\n const emptyKeys = local.keys.filter((key) => localEmptySet.has(key));\n\n return {\n examplePath: exampleContent === null ? null : examplePath,\n localPath: localContent === null ? null : localPath,\n hasExample: exampleContent !== null,\n hasLocal: localContent !== null,\n exampleKeys: example.keys,\n localKeys: local.keys,\n missingKeys,\n emptyKeys,\n keys: example.keys.map((key) => ({\n key,\n present: localKeySet.has(key),\n empty: localEmptySet.has(key)\n }))\n };\n}\n","import type { FrameworkInfo, PackageJsonInfo } from '../types.js';\n\nconst frameworkPackages: Array<{ packageName: string; label: string }> = [\n { packageName: 'next', label: 'Next.js' },\n { packageName: 'vite', label: 'Vite' },\n { packageName: 'express', label: 'Express' },\n { packageName: 'fastify', label: 'Fastify' },\n { packageName: '@nestjs/core', label: 'NestJS' },\n { packageName: '@remix-run/react', label: 'Remix' },\n { packageName: 'prisma', label: 'Prisma' }\n];\n\nexport function detectFramework(packageJson: PackageJsonInfo | null): FrameworkInfo | null {\n if (packageJson === null) {\n return null;\n }\n\n const dependencies = {\n ...packageJson.data.dependencies,\n ...packageJson.data.devDependencies,\n ...packageJson.data.optionalDependencies,\n ...packageJson.data.peerDependencies\n };\n\n const detected = frameworkPackages\n .filter((framework) => dependencies[framework.packageName] !== undefined)\n .map((framework) => framework.label);\n\n if (detected.length === 0) {\n return {\n type: 'Node.js',\n detected: ['Node.js']\n };\n }\n\n return {\n type: ['Node.js', ...detected].join(' / '),\n detected\n };\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { GitInfo } from '../types.js';\n\nfunction isWithinRoot(root: string, target: string): boolean {\n const resolvedRoot = path.resolve(root);\n const resolvedTarget = path.resolve(target);\n const relative = path.relative(resolvedRoot, resolvedTarget);\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nasync function resolveGitDirectory(root: string): Promise<string | null> {\n const gitPath = path.join(root, '.git');\n\n try {\n const stat = await fs.stat(gitPath);\n if (stat.isDirectory()) {\n return gitPath;\n }\n\n if (stat.isFile()) {\n const content = await fs.readFile(gitPath, 'utf8');\n const match = content.match(/^gitdir:\\s*(.+)\\s*$/m);\n if (match) {\n const gitDir = match[1].trim();\n const resolvedGitDir = path.isAbsolute(gitDir)\n ? path.resolve(gitDir)\n : path.resolve(root, gitDir);\n if (!isWithinRoot(root, resolvedGitDir)) {\n return null;\n }\n\n const [realRoot, realGitDir] = await Promise.all([\n fs.realpath(root),\n fs.realpath(resolvedGitDir)\n ]);\n return isWithinRoot(realRoot, realGitDir) ? resolvedGitDir : null;\n }\n }\n } catch {\n return null;\n }\n\n return null;\n}\n\nexport async function detectGit(root: string): Promise<GitInfo | null> {\n const gitRoot = await resolveGitDirectory(root);\n if (gitRoot === null) {\n return null;\n }\n\n try {\n const head = await fs.readFile(path.join(gitRoot, 'HEAD'), 'utf8');\n const refMatch = head.match(/^ref:\\s+refs\\/heads\\/(.+)\\s*$/);\n return {\n root: gitRoot,\n branch: refMatch ? refMatch[1] : head.trim().slice(0, 12)\n };\n } catch {\n return {\n root: gitRoot,\n branch: null\n };\n }\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { PackageManager } from '../types.js';\n\nconst lockFiles: Array<{ file: string; manager: PackageManager }> = [\n { file: 'pnpm-lock.yaml', manager: 'pnpm' },\n { file: 'yarn.lock', manager: 'yarn' },\n { file: 'bun.lockb', manager: 'bun' },\n { file: 'bun.lock', manager: 'bun' },\n { file: 'package-lock.json', manager: 'npm' }\n];\n\nasync function exists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function detectPackageManager(root: string): Promise<PackageManager | null> {\n for (const lockFile of lockFiles) {\n if (await exists(path.join(root, lockFile.file))) {\n return lockFile.manager;\n }\n }\n\n return null;\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport type { PackageJsonInfo } from '../types.js';\n\nexport async function readPackageJson(root: string): Promise<PackageJsonInfo | null> {\n const packageJsonPath = path.join(root, 'package.json');\n\n try {\n const content = await fs.readFile(packageJsonPath, 'utf8');\n const data = JSON.parse(content) as PackageJsonInfo['data'];\n return { path: packageJsonPath, data };\n } catch {\n return null;\n }\n}\n","import net from 'node:net';\nimport type { FrameworkInfo, PortProbe } from '../types.js';\n\nexport const DEFAULT_PORTS = [3000, 5173];\n\nfunction uniquePorts(ports: number[]): number[] {\n return Array.from(\n new Set(ports.filter((port) => Number.isInteger(port) && port > 0 && port < 65536))\n );\n}\n\nexport function inferPortsFromScripts(scripts: Record<string, string>): number[] {\n const ports: number[] = [];\n\n for (const command of Object.values(scripts)) {\n const patterns = [\n /(?:--port|-p)\\s+(\\d{2,5})/g,\n /\\bPORT=(\\d{2,5})\\b/g,\n /localhost:(\\d{2,5})/g,\n /127\\.0\\.0\\.1:(\\d{2,5})/g\n ];\n\n for (const pattern of patterns) {\n for (const match of command.matchAll(pattern)) {\n ports.push(Number(match[1]));\n }\n }\n }\n\n return uniquePorts(ports);\n}\n\nexport function defaultPortsForFramework(framework: FrameworkInfo | null): number[] {\n if (framework === null) {\n return [];\n }\n\n const ports: number[] = [];\n if (framework.detected.includes('Next.js') || framework.detected.includes('Express')) {\n ports.push(3000);\n }\n\n if (framework.detected.includes('Vite')) {\n ports.push(5173);\n }\n\n if (framework.detected.includes('Prisma')) {\n ports.push(5555);\n }\n\n return uniquePorts(ports);\n}\n\nexport async function probePort(port: number): Promise<PortProbe> {\n return await new Promise((resolve) => {\n const server = net.createServer();\n\n server.once('error', () => {\n resolve({ port, inUse: true });\n });\n\n server.once('listening', () => {\n server.close(() => {\n resolve({ port, inUse: false });\n });\n });\n\n server.listen(port, '127.0.0.1');\n });\n}\n\nexport async function detectPorts(ports: number[]): Promise<PortProbe[] | null> {\n const normalized = uniquePorts(ports);\n if (normalized.length === 0) {\n return null;\n }\n\n return await Promise.all(normalized.map((port) => probePort(port)));\n}\n","import type { PackageJsonInfo } from '../types.js';\n\nexport function extractScripts(packageJson: PackageJsonInfo | null): Record<string, string> | null {\n if (\n !packageJson?.data.scripts ||\n typeof packageJson.data.scripts !== 'object' ||\n Array.isArray(packageJson.data.scripts)\n ) {\n return null;\n }\n\n return Object.fromEntries(\n Object.entries(packageJson.data.scripts).filter((entry): entry is [string, string] => {\n const [, command] = entry;\n return typeof command === 'string';\n })\n );\n}\n","import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport pc from 'picocolors';\nimport { CONFIG_FILE_NAME, defaultConfig } from '../../core/config/defaults.js';\n\nexport async function initCommand(cwd = process.cwd()): Promise<void> {\n const configPath = path.join(cwd, CONFIG_FILE_NAME);\n\n try {\n await fs.access(configPath);\n console.log(pc.yellow(`${CONFIG_FILE_NAME} already exists.`));\n return;\n } catch {\n await fs.writeFile(configPath, `${JSON.stringify(defaultConfig, null, 2)}\\n`, 'utf8');\n console.log(pc.green(`Created ${CONFIG_FILE_NAME}.`));\n }\n}\n","import pc from 'picocolors';\nimport { runPackageScriptToTerminal } from '../../core/process/runner.js';\nimport { scanProject } from '../../core/scanner/index.js';\n\nexport async function runCommand(script: string, cwd = process.cwd()): Promise<void> {\n const scan = await scanProject(cwd);\n\n if (scan.packageJson === null) {\n console.error(pc.red('No package.json was found in this directory.'));\n process.exitCode = 1;\n return;\n }\n\n if (scan.scripts[script] === undefined) {\n console.error(pc.red(`Script \"${script}\" was not found in package.json.`));\n process.exitCode = 1;\n return;\n }\n\n const exitCode = await runPackageScriptToTerminal({\n cwd,\n packageManager: scan.packageManager,\n script\n });\n process.exitCode = exitCode;\n}\n","import spawn from 'cross-spawn';\nimport type { PackageManager } from '../types.js';\nimport { resolveExecutableOutsideRoot } from './executable.js';\n\nexport interface PackageRunCommand {\n command: string;\n args: string[];\n displayCommand: string;\n}\n\nexport function getPackageRunCommand(\n packageManager: PackageManager | null,\n script: string\n): PackageRunCommand {\n const manager = packageManager ?? 'npm';\n const args = ['run', script];\n return {\n command: manager,\n args,\n displayCommand: `${manager} ${args.join(' ')}`\n };\n}\n\nexport async function resolvePackageRunCommand(options: {\n cwd: string;\n packageManager: PackageManager | null;\n script: string;\n}): Promise<PackageRunCommand | null> {\n const runCommand = getPackageRunCommand(options.packageManager, options.script);\n const executable = await resolveExecutableOutsideRoot(options.cwd, runCommand.command);\n if (executable === null) {\n return null;\n }\n\n return {\n ...runCommand,\n command: executable\n };\n}\n\nexport function getPackageInstallCommand(packageManager: PackageManager | null): PackageRunCommand {\n const manager = packageManager ?? 'npm';\n if (manager === 'npm') {\n return {\n command: manager,\n args: ['ci'],\n displayCommand: 'npm ci'\n };\n }\n\n if (manager === 'pnpm') {\n return {\n command: manager,\n args: ['install', '--frozen-lockfile'],\n displayCommand: 'pnpm install --frozen-lockfile'\n };\n }\n\n if (manager === 'yarn') {\n return {\n command: manager,\n args: ['install', '--frozen-lockfile'],\n displayCommand: 'yarn install --frozen-lockfile'\n };\n }\n\n return {\n command: manager,\n args: ['install'],\n displayCommand: 'bun install'\n };\n}\n\nexport async function resolvePackageInstallCommand(options: {\n cwd: string;\n packageManager: PackageManager | null;\n}): Promise<PackageRunCommand | null> {\n const installCommand = getPackageInstallCommand(options.packageManager);\n const executable = await resolveExecutableOutsideRoot(options.cwd, installCommand.command);\n if (executable === null) {\n return null;\n }\n\n return {\n ...installCommand,\n command: executable\n };\n}\n\nexport function isDangerousCommand(command: string): boolean {\n return /\\b(rm\\s+-rf|docker\\s+volume\\s+rm|drop\\s+database|prisma\\s+migrate\\s+reset|git\\s+clean\\s+-fd)\\b/i.test(\n command\n );\n}\n\nexport async function runPackageScriptToTerminal(options: {\n cwd: string;\n packageManager: PackageManager | null;\n script: string;\n}): Promise<number> {\n const runCommand = await resolvePackageRunCommand(options);\n if (runCommand === null) {\n return 1;\n }\n\n return await new Promise((resolve) => {\n const child = spawn(runCommand.command, runCommand.args, {\n cwd: options.cwd,\n stdio: 'inherit',\n windowsHide: true\n });\n\n child.on('error', () => {\n resolve(1);\n });\n\n child.on('close', (code) => {\n resolve(code ?? 1);\n });\n });\n}\n","import pc from 'picocolors';\nimport type { ScanResult } from '../../core/types.js';\nimport { scanProject } from '../../core/scanner/index.js';\n\nfunction formatList(values: string[]): string {\n return values.length > 0 ? values.join(', ') : 'none';\n}\n\nexport function printScanResult(scan: ScanResult): void {\n console.log(pc.bold(`Project: ${scan.projectName}`));\n console.log(`Type: ${scan.framework?.type ?? 'Unknown'}`);\n console.log(`Manager: ${scan.packageManager ?? 'unknown'}`);\n console.log(`Scripts: ${formatList(Object.keys(scan.scripts))}`);\n console.log(`Git: ${scan.git?.branch ?? 'not detected'}`);\n console.log(`README: ${scan.readme.exists ? 'found' : 'missing'}`);\n console.log(`LICENSE: ${scan.license.exists ? 'found' : 'missing'}`);\n\n if (scan.env !== null) {\n console.log(`Env: ${scan.env.hasLocal ? '.env found' : '.env missing'}`);\n }\n\n if (scan.ports.length > 0) {\n const ports = scan.ports.map((port) => `${port.port}${port.inUse ? ' in use' : ' free'}`);\n console.log(`Ports: ${ports.join(', ')}`);\n }\n\n if (scan.docker !== null) {\n console.log(\n `Docker: compose found (${formatList(scan.docker.services.map((service) => service.name))})`\n );\n }\n}\n\nexport async function scanCommand(cwd = process.cwd()): Promise<void> {\n printScanResult(await scanProject(cwd));\n}\n","import pc from 'picocolors';\nimport { runDoctor } from '../../core/doctor/index.js';\nimport { scanProject } from '../../core/scanner/index.js';\nimport { startDevSurfaceServer } from '../../server/index.js';\nimport { printScanResult } from './scan.js';\n\nexport async function startCommand(options: {\n cwd?: string;\n port?: number;\n openBrowser?: boolean;\n}): Promise<void> {\n const cwd = options.cwd ?? process.cwd();\n console.log(pc.bold(`DevSurface v0.1.0`));\n console.log('Scanning project...\\n');\n\n const scan = await scanProject(cwd);\n printScanResult(scan);\n\n const warnings = await runDoctor(cwd, scan);\n if (warnings.length > 0) {\n console.log('\\nWarnings:');\n for (const item of warnings) {\n const marker = item.severity === 'error' ? pc.red('!') : pc.yellow('!');\n console.log(` ${marker} ${item.title}`);\n }\n }\n\n const server = await startDevSurfaceServer({\n projectRoot: cwd,\n port: options.port,\n openBrowser: options.openBrowser\n });\n\n console.log(`\\nDashboard running at -> ${pc.cyan(server.url)}`);\n}\n","import { promises as fs } from 'node:fs';\nimport type { Server } from 'node:http';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { serve } from '@hono/node-server';\nimport { serveStatic } from '@hono/node-server/serve-static';\nimport { Hono } from 'hono';\nimport open from 'open';\nimport { ProcessManager } from '../core/process/manager.js';\nimport { registerApiRoutes } from './routes/api.js';\nimport { setupWebSocket } from './routes/ws.js';\n\nexport const HOST = '127.0.0.1';\nexport const DEFAULT_PORT = 4567;\n\nexport interface DevSurfaceServer {\n url: string;\n port: number;\n close: () => Promise<void>;\n processManager: ProcessManager;\n}\n\nfunction assertLocalHost(host: string): void {\n if (host !== HOST) {\n throw new Error('DevSurface must bind only to 127.0.0.1.');\n }\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function findWebDistDir(): Promise<string | null> {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.join(moduleDir, '..', 'web', 'dist'),\n path.join(moduleDir, '..', '..', 'src', 'web', 'dist'),\n path.join(moduleDir, 'web', 'dist')\n ];\n\n for (const candidate of candidates) {\n if (await fileExists(path.join(candidate, 'index.html'))) {\n return candidate;\n }\n }\n\n return null;\n}\n\nexport async function createApp(options: {\n projectRoot: string;\n processManager: ProcessManager;\n}): Promise<Hono> {\n const app = new Hono();\n registerApiRoutes(app, options);\n\n const webDistDir = await findWebDistDir();\n if (webDistDir !== null) {\n app.use('/assets/*', serveStatic({ root: webDistDir }));\n app.get('/favicon.svg', serveStatic({ root: webDistDir }));\n app.get('*', async (context) => {\n const html = await fs.readFile(path.join(webDistDir, 'index.html'), 'utf8');\n return context.html(html);\n });\n } else {\n app.get('*', (context) =>\n context.html(\n '<!doctype html><title>DevSurface</title><main><h1>DevSurface</h1><p>Run npm run build:web to build the dashboard.</p></main>',\n 503\n )\n );\n }\n\n return app;\n}\n\nexport async function startDevSurfaceServer(options: {\n projectRoot: string;\n port?: number;\n openBrowser?: boolean;\n}): Promise<DevSurfaceServer> {\n assertLocalHost(HOST);\n const port = options.port ?? DEFAULT_PORT;\n const processManager = new ProcessManager();\n processManager.attachCleanupHandlers();\n const app = await createApp({\n projectRoot: options.projectRoot,\n processManager\n });\n\n const server = serve({\n fetch: app.fetch,\n port,\n hostname: HOST\n }) as Server;\n const wss = setupWebSocket(server, processManager);\n const url = `http://${HOST}:${port}`;\n\n if (options.openBrowser !== false) {\n await open(url);\n }\n\n return {\n url,\n port,\n processManager,\n close: async () => {\n processManager.killAll();\n await new Promise<void>((resolve) => {\n wss.close(() => resolve());\n });\n await new Promise<void>((resolve, reject) => {\n server.close((error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n };\n}\n","import { EventEmitter } from 'node:events';\nimport type { ChildProcess } from 'node:child_process';\nimport spawn from 'cross-spawn';\nimport type { ManagedProcessSnapshot, ProcessLogEvent } from '../types.js';\n\ninterface ProcessRecord extends ManagedProcessSnapshot {\n child: ChildProcess;\n}\n\nexport class ProcessManager extends EventEmitter {\n private readonly processes = new Map<string, ProcessRecord>();\n private readonly logs: ProcessLogEvent[] = [];\n private cleanupInstalled = false;\n\n start(options: {\n cwd: string;\n script: string;\n command: string;\n args: string[];\n displayCommand: string;\n shell?: boolean;\n }): ManagedProcessSnapshot {\n const child = spawn(options.command, options.args, {\n cwd: options.cwd,\n shell: options.shell ?? false,\n windowsHide: true\n });\n\n const pid = String(child.pid ?? `${Date.now()}-${Math.random().toString(16).slice(2)}`);\n const record: ProcessRecord = {\n child,\n pid,\n script: options.script,\n command: options.displayCommand,\n status: 'running',\n startedAt: new Date().toISOString(),\n endedAt: null,\n exitCode: null\n };\n\n this.processes.set(pid, record);\n this.emitSystem(record, `Started ${options.displayCommand}`);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n this.emitLog(record, 'stdout', chunk.toString());\n });\n\n child.stderr?.on('data', (chunk: Buffer) => {\n this.emitLog(record, 'stderr', chunk.toString());\n });\n\n child.on('error', (error) => {\n record.status = 'failed';\n record.endedAt = new Date().toISOString();\n this.emitLog(record, 'system', error.message);\n this.emit('process', this.snapshot(record));\n });\n\n child.on('close', (code) => {\n if (record.status === 'stopped') {\n record.exitCode = code;\n } else {\n record.status = code === 0 ? 'exited' : 'failed';\n record.exitCode = code;\n }\n record.endedAt = new Date().toISOString();\n this.emitSystem(record, `Exited with code ${code ?? 'unknown'}`);\n this.emit('process', this.snapshot(record));\n });\n\n this.emit('process', this.snapshot(record));\n return this.snapshot(record);\n }\n\n stop(pid: string): boolean {\n const record = this.processes.get(pid);\n if (!record || record.status !== 'running') {\n return false;\n }\n\n record.status = 'stopped';\n record.endedAt = new Date().toISOString();\n record.child.kill();\n this.emitSystem(record, 'Stopped by DevSurface');\n this.emit('process', this.snapshot(record));\n return true;\n }\n\n list(): ManagedProcessSnapshot[] {\n return Array.from(this.processes.values()).map((record) => this.snapshot(record));\n }\n\n listLogs(): ProcessLogEvent[] {\n return [...this.logs];\n }\n\n killAll(): void {\n for (const record of this.processes.values()) {\n if (record.status === 'running') {\n record.status = 'stopped';\n record.endedAt = new Date().toISOString();\n record.child.kill();\n }\n }\n }\n\n attachCleanupHandlers(): void {\n if (this.cleanupInstalled) {\n return;\n }\n\n this.cleanupInstalled = true;\n process.once('exit', () => {\n this.killAll();\n });\n process.once('SIGINT', () => {\n this.killAll();\n process.exit(130);\n });\n }\n\n private emitLog(record: ProcessRecord, stream: ProcessLogEvent['stream'], message: string): void {\n const event: ProcessLogEvent = {\n pid: record.pid,\n script: record.script,\n stream,\n message,\n timestamp: new Date().toISOString()\n };\n\n this.logs.push(event);\n if (this.logs.length > 1000) {\n this.logs.splice(0, this.logs.length - 1000);\n }\n\n this.emit('log', event);\n }\n\n private emitSystem(record: ProcessRecord, message: string): void {\n this.emitLog(record, 'system', message);\n }\n\n private snapshot(record: ProcessRecord): ManagedProcessSnapshot {\n return {\n pid: record.pid,\n script: record.script,\n command: record.command,\n status: record.status,\n startedAt: record.startedAt,\n endedAt: record.endedAt,\n exitCode: record.exitCode\n };\n }\n}\n","import { constants, existsSync } from 'node:fs';\nimport { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport spawn from 'cross-spawn';\nimport type { Hono } from 'hono';\nimport open from 'open';\nimport type { ProcessManager } from '../../core/process/manager.js';\nimport {\n resolvePackageInstallCommand,\n resolvePackageRunCommand\n} from '../../core/process/runner.js';\nimport { runDoctor } from '../../core/doctor/index.js';\nimport { scanProject } from '../../core/scanner/index.js';\nimport { isAllowedLocalHostHeader, isAllowedLocalOrigin, isSameOrigin } from '../localAccess.js';\n\nfunction isWithinRoot(root: string, target: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(target));\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));\n}\n\nfunction isAllowedMutationOrigin(requestUrl: string, origin: string | null): boolean {\n if (origin === null) {\n return true;\n }\n\n return isAllowedLocalOrigin(origin) && isSameOrigin(requestUrl, origin);\n}\n\nfunction isCrossSiteFetch(secFetchSite: string | null): boolean {\n return secFetchSite === 'cross-site';\n}\n\nfunction hasMutationIntent(intent: string | null): boolean {\n return intent === 'dashboard';\n}\n\nasync function realPathWithinRoot(root: string, target: string): Promise<boolean> {\n if (!isWithinRoot(root, target)) {\n return false;\n }\n\n try {\n const [realRoot, realTarget] = await Promise.all([fs.realpath(root), fs.realpath(target)]);\n return isWithinRoot(realRoot, realTarget);\n } catch {\n return false;\n }\n}\n\nasync function writableDestinationWithinRoot(root: string, destination: string): Promise<boolean> {\n if (!isWithinRoot(root, destination)) {\n return false;\n }\n\n try {\n const [realRoot, realParent] = await Promise.all([\n fs.realpath(root),\n fs.realpath(path.dirname(destination))\n ]);\n return isWithinRoot(realRoot, realParent);\n } catch {\n return false;\n }\n}\n\nasync function copyFileExclusive(\n source: string,\n destination: string\n): Promise<'copied' | 'exists'> {\n const content = await fs.readFile(source);\n let handle: fs.FileHandle | null = null;\n try {\n handle = await fs.open(\n destination,\n constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY,\n 0o600\n );\n await handle.writeFile(content);\n return 'copied';\n } catch (error) {\n const code =\n typeof error === 'object' && error !== null && 'code' in error ? error.code : undefined;\n if (code === 'EEXIST') {\n return 'exists';\n }\n\n throw error;\n } finally {\n await handle?.close();\n }\n}\n\nfunction quotePowerShellString(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`;\n}\n\nfunction quotePosixString(value: string): string {\n return `'${value.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction resolveCommandPromptExecutable(): string {\n return process.env.ComSpec ?? 'cmd.exe';\n}\n\nfunction findExecutable(command: string): string | null {\n if (path.isAbsolute(command)) {\n return existsSync(command) ? command : null;\n }\n\n const pathValue = process.env.PATH ?? '';\n for (const directory of pathValue.split(path.delimiter)) {\n if (directory.length === 0) {\n continue;\n }\n\n const candidate = path.join(directory, command);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction launchDetached(command: string, args: string[], root: string): boolean {\n const child = spawn(command, args, {\n cwd: root,\n detached: true,\n stdio: 'ignore',\n windowsHide: process.platform === 'win32'\n });\n child.on('error', () => undefined);\n child.unref();\n return true;\n}\n\nfunction openTerminalAt(root: string): boolean {\n if (process.platform === 'win32') {\n return launchDetached(\n resolveCommandPromptExecutable(),\n [\n '/d',\n '/c',\n 'start',\n '\"\"',\n '/D',\n root,\n 'powershell.exe',\n '-NoExit',\n '-NoLogo',\n '-Command',\n `Set-Location -LiteralPath ${quotePowerShellString(root)}`\n ],\n root\n );\n }\n\n if (process.platform === 'darwin') {\n return launchDetached('open', ['-a', 'Terminal', root], root);\n }\n\n const configuredTerminal = process.env.TERMINAL;\n if (configuredTerminal !== undefined && findExecutable(configuredTerminal) !== null) {\n return launchDetached(configuredTerminal, [], root);\n }\n\n const linuxTerminals: Array<{ command: string; args: string[] }> = [\n { command: 'x-terminal-emulator', args: [] },\n { command: 'gnome-terminal', args: ['--working-directory', root] },\n { command: 'konsole', args: ['--workdir', root] },\n { command: 'xfce4-terminal', args: ['--working-directory', root] },\n {\n command: 'xterm',\n args: [\n '-e',\n 'sh',\n '-lc',\n `cd ${quotePosixString(root)} && exec ${quotePosixString(process.env.SHELL ?? 'sh')}`\n ]\n }\n ];\n\n const terminal = linuxTerminals.find((candidate) => findExecutable(candidate.command) !== null);\n if (terminal === undefined) {\n return false;\n }\n\n return launchDetached(terminal.command, terminal.args, root);\n}\n\nexport function registerApiRoutes(\n app: Hono,\n options: {\n projectRoot: string;\n processManager: ProcessManager;\n }\n): void {\n app.use('/api/*', async (context, next) => {\n const host = context.req.header('host') ?? new URL(context.req.url).host;\n if (!isAllowedLocalHostHeader(host)) {\n return context.json({ error: 'Non-local host rejected.' }, 403);\n }\n\n if (context.req.method !== 'GET' && context.req.method !== 'HEAD') {\n const origin = context.req.header('origin') ?? null;\n const secFetchSite = context.req.header('sec-fetch-site') ?? null;\n const intent = context.req.header('x-devsurface-intent') ?? null;\n if (\n !hasMutationIntent(intent) ||\n isCrossSiteFetch(secFetchSite) ||\n !isAllowedMutationOrigin(context.req.url, origin)\n ) {\n return context.json({ error: 'Cross-origin mutation rejected.' }, 403);\n }\n }\n\n await next();\n });\n\n app.get('/api/project', async (context) => {\n return context.json(await scanProject(options.projectRoot));\n });\n\n app.get('/api/health', async (context) => {\n return context.json(await runDoctor(options.projectRoot));\n });\n\n app.get('/api/processes', (context) => {\n return context.json(options.processManager.list());\n });\n\n app.post('/api/run/:script', async (context) => {\n const script = decodeURIComponent(context.req.param('script'));\n const scan = await scanProject(options.projectRoot);\n const packageScript = scan.scripts[script];\n\n if (packageScript === undefined) {\n return context.json({ error: `Script \"${script}\" was not found.` }, 404);\n }\n\n const command = await resolvePackageRunCommand({\n cwd: options.projectRoot,\n packageManager: scan.packageManager,\n script\n });\n if (command === null) {\n return context.json({ error: 'Package manager executable was not found.' }, 503);\n }\n\n const processInfo = options.processManager.start({\n cwd: options.projectRoot,\n script,\n command: command.command,\n args: command.args,\n displayCommand: command.displayCommand\n });\n\n return context.json({\n ...processInfo,\n packageScript\n });\n });\n\n app.post('/api/install', async (context) => {\n const scan = await scanProject(options.projectRoot);\n const command = await resolvePackageInstallCommand({\n cwd: options.projectRoot,\n packageManager: scan.packageManager\n });\n if (command === null) {\n return context.json({ error: 'Package manager executable was not found.' }, 503);\n }\n\n const processInfo = options.processManager.start({\n cwd: options.projectRoot,\n script: 'install',\n command: command.command,\n args: command.args,\n displayCommand: command.displayCommand\n });\n\n return context.json(processInfo);\n });\n\n app.post('/api/commands/:name', async (context) => {\n const name = decodeURIComponent(context.req.param('name'));\n const scan = await scanProject(options.projectRoot);\n const configuredCommand = scan.config?.config.commands?.[name] ?? null;\n\n if (configuredCommand === null) {\n return context.json({ error: `Configured command \"${name}\" was not found.` }, 404);\n }\n\n const processInfo = options.processManager.start({\n cwd: options.projectRoot,\n script: name,\n command: configuredCommand,\n args: [],\n displayCommand: configuredCommand,\n shell: true\n });\n\n return context.json({\n ...processInfo,\n configuredCommand\n });\n });\n\n app.post('/api/open/folder', async (context) => {\n await open(options.projectRoot);\n return context.json({ opened: true, target: 'folder' });\n });\n\n app.post('/api/open/package', async (context) => {\n const packagePath = path.join(options.projectRoot, 'package.json');\n if (!(await realPathWithinRoot(options.projectRoot, packagePath))) {\n return context.json({ error: 'package.json was not found inside the project root.' }, 404);\n }\n\n await open(packagePath);\n return context.json({ opened: true, target: 'package' });\n });\n\n app.post('/api/open/terminal', (context) => {\n const opened = openTerminalAt(options.projectRoot);\n return context.json({ opened, target: 'terminal' }, opened ? 200 : 501);\n });\n\n app.post('/api/env/copy', async (context) => {\n const scan = await scanProject(options.projectRoot);\n const examplePath = scan.env?.examplePath ?? null;\n const localPath = scan.env?.localPath ?? null;\n\n if (examplePath === null) {\n return context.json({ error: '.env.example was not found.' }, 404);\n }\n\n const destination =\n localPath ?? path.join(options.projectRoot, scan.config?.config.env?.local ?? '.env');\n if (\n !(await realPathWithinRoot(options.projectRoot, examplePath)) ||\n !(await writableDestinationWithinRoot(options.projectRoot, destination))\n ) {\n return context.json({ error: 'Refusing to copy env files outside the project root.' }, 400);\n }\n\n const copyResult = await copyFileExclusive(examplePath, destination);\n if (copyResult === 'exists') {\n return context.json({ error: '.env already exists.' }, 409);\n }\n\n return context.json({ copied: true });\n });\n\n app.delete('/api/run/:pid', (context) => {\n const pid = decodeURIComponent(context.req.param('pid'));\n const stopped = options.processManager.stop(pid);\n return context.json({ stopped });\n });\n}\n","const LOCAL_HOSTNAMES = new Set(['127.0.0.1', 'localhost', '::1']);\n\nfunction hostnameFromHostHeader(host: string): string | null {\n const trimmed = host.trim().toLowerCase();\n if (trimmed.length === 0) {\n return null;\n }\n\n if (trimmed.startsWith('[')) {\n const end = trimmed.indexOf(']');\n return end > 0 ? trimmed.slice(1, end) : null;\n }\n\n return trimmed.split(':')[0] ?? null;\n}\n\nexport function isAllowedLocalHostHeader(host: string | null | undefined): boolean {\n if (typeof host !== 'string') {\n return false;\n }\n\n const hostname = hostnameFromHostHeader(host);\n return hostname !== null && LOCAL_HOSTNAMES.has(hostname);\n}\n\nexport function isAllowedLocalOrigin(origin: string | null): boolean {\n if (origin === null) {\n return true;\n }\n\n try {\n const url = new URL(origin);\n return (\n (url.protocol === 'http:' || url.protocol === 'https:') &&\n LOCAL_HOSTNAMES.has(url.hostname.toLowerCase())\n );\n } catch {\n return false;\n }\n}\n\nexport function isSameOrigin(requestUrl: string, origin: string): boolean {\n try {\n return new URL(requestUrl).origin === new URL(origin).origin;\n } catch {\n return false;\n }\n}\n","import type { Server } from 'node:http';\nimport type { IncomingMessage } from 'node:http';\nimport { WebSocket, WebSocketServer } from 'ws';\nimport type { ProcessManager } from '../../core/process/manager.js';\nimport type { ManagedProcessSnapshot, ProcessLogEvent } from '../../core/types.js';\nimport { isAllowedLocalHostHeader, isAllowedLocalOrigin } from '../localAccess.js';\n\nfunction isAllowedWebSocketRequest(request: IncomingMessage): boolean {\n const origin = request.headers.origin;\n const host = request.headers.host;\n const secFetchSite = request.headers['sec-fetch-site'];\n\n if (typeof host !== 'string' || !isAllowedLocalHostHeader(host)) {\n return false;\n }\n\n if (secFetchSite === 'cross-site') {\n return false;\n }\n\n if (typeof origin !== 'string') {\n return true;\n }\n\n if (!isAllowedLocalOrigin(origin)) {\n return false;\n }\n\n try {\n return new URL(origin).host.toLowerCase() === host.toLowerCase();\n } catch {\n return false;\n }\n}\n\nexport function setupWebSocket(server: Server, processManager: ProcessManager): WebSocketServer {\n const wss = new WebSocketServer({\n server,\n path: '/ws',\n verifyClient: (info: { req: IncomingMessage }) => isAllowedWebSocketRequest(info.req)\n });\n\n function broadcast(payload: unknown): void {\n const serialized = JSON.stringify(payload);\n for (const client of wss.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(serialized);\n }\n }\n }\n\n processManager.on('log', (event: ProcessLogEvent) => {\n broadcast({ type: 'log', event });\n });\n\n processManager.on('process', (processInfo: ManagedProcessSnapshot) => {\n broadcast({ type: 'process', process: processInfo });\n });\n\n wss.on('connection', (socket) => {\n socket.send(\n JSON.stringify({\n type: 'hello',\n processes: processManager.list(),\n logs: processManager.listLogs()\n })\n );\n });\n\n return wss;\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","fs","path","fs","path","isWithinRoot","rows","fs","path","fs","path","isWithinRoot","fs","path","fs","path","path","fs","fs","readIfPresent","path","fs","path","pc","path","fs","pc","pc","spawn","runCommand","runCommand","spawn","pc","pc","pc","pc","fs","path","open","spawn","constants","fs","path","spawn","isWithinRoot","path","fs","handle","constants","spawn","fileExists","fs","path","open","pc"]}
@@ -0,0 +1,17 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="164" height="28" viewBox="0 0 164 28" role="img" aria-label="DevSurface ready">
2
+ <title>DevSurface ready</title>
3
+ <defs>
4
+ <linearGradient id="surface" x1="0" x2="1" y1="0" y2="1">
5
+ <stop offset="0" stop-color="#151513" />
6
+ <stop offset="1" stop-color="#2f332d" />
7
+ </linearGradient>
8
+ </defs>
9
+ <rect width="164" height="28" rx="4" fill="#0f0f0e" />
10
+ <rect x="1" y="1" width="162" height="26" rx="3" fill="url(#surface)" />
11
+ <rect x="8" y="6" width="18" height="16" rx="2" fill="#ffffff" fill-opacity=".08" stroke="#f4f0e8" stroke-width="1.3" />
12
+ <path d="M12 11.2 15.1 14 12 16.8" fill="none" stroke="#f4f0e8" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
13
+ <path d="M17 17h5" fill="none" stroke="#f4f0e8" stroke-width="1.5" stroke-linecap="round" />
14
+ <text x="34" y="18.7" fill="#f4f0e8" font-family="Inter,Segoe UI,Arial,sans-serif" font-size="13" font-weight="700">DevSurface</text>
15
+ <rect x="112" y="5" width="45" height="18" rx="3" fill="#08751f" />
16
+ <text x="122" y="18.3" fill="#ffffff" font-family="Inter,Segoe UI,Arial,sans-serif" font-size="11" font-weight="800">ready</text>
17
+ </svg>
Binary file
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "devsurface",
3
+ "version": "0.1.0",
4
+ "description": "Turn any Node.js repository into a local developer control panel.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "mrfandu1",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/mrfandu1/devsurface.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/mrfandu1/devsurface/issues"
14
+ },
15
+ "homepage": "https://github.com/mrfandu1/devsurface#readme",
16
+ "bin": {
17
+ "devsurface": "./dist/cli/index.js"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "src/web/dist",
22
+ "docs/devsurface-badge.svg",
23
+ "docs/devsurface-demo.gif",
24
+ "README.md",
25
+ "LICENSE",
26
+ "CHANGELOG.md"
27
+ ],
28
+ "scripts": {
29
+ "build": "npm run build:web && npm run build:cli",
30
+ "build:cli": "tsup src/cli/index.ts --format esm --dts --sourcemap --clean --out-dir dist/cli",
31
+ "build:web": "vite build",
32
+ "dev": "tsx src/cli/index.ts",
33
+ "format": "prettier --write .",
34
+ "format:check": "prettier --check .",
35
+ "lint": "eslint . --ext .ts,.tsx",
36
+ "test": "vitest run",
37
+ "typecheck": "tsc --noEmit"
38
+ },
39
+ "dependencies": {
40
+ "@hono/node-server": "^1.13.8",
41
+ "commander": "^12.1.0",
42
+ "cross-spawn": "^7.0.6",
43
+ "hono": "^4.6.16",
44
+ "open": "^10.1.0",
45
+ "picocolors": "^1.1.1",
46
+ "react": "^18.3.1",
47
+ "react-dom": "^18.3.1",
48
+ "ws": "^8.18.0",
49
+ "yaml": "^2.6.1"
50
+ },
51
+ "devDependencies": {
52
+ "@types/cross-spawn": "^6.0.6",
53
+ "@types/node": "^22.10.5",
54
+ "@types/react": "^18.3.18",
55
+ "@types/react-dom": "^18.3.5",
56
+ "@types/ws": "^8.5.13",
57
+ "@vitejs/plugin-react": "^6.0.2",
58
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
59
+ "@typescript-eslint/parser": "^8.19.1",
60
+ "eslint": "^8.57.1",
61
+ "eslint-config-prettier": "^9.1.0",
62
+ "prettier": "^3.4.2",
63
+ "tsup": "^8.5.1",
64
+ "tsx": "^4.19.2",
65
+ "typescript": "^5.7.2",
66
+ "vite": "^8.0.16",
67
+ "vitest": "^4.1.9"
68
+ },
69
+ "overrides": {
70
+ "esbuild": "^0.28.1"
71
+ },
72
+ "engines": {
73
+ "node": ">=18.18"
74
+ }
75
+ }
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="12" fill="#142033" />
3
+ <path d="M15 22h34v20H15z" fill="#f8fafc" />
4
+ <path d="M20 28h10M20 34h17M20 40h8" stroke="#2563eb" stroke-width="3" stroke-linecap="round" />
5
+ <path d="M42 30l6 6-6 6" stroke="#10b981" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" fill="none" />
6
+ </svg>