diff --git a/src/cli/commands/serve.ts b/src/cli/commands/serve.ts index b4c9bd1..b50357e 100644 --- a/src/cli/commands/serve.ts +++ b/src/cli/commands/serve.ts @@ -4,6 +4,7 @@ import { readdirSync, statSync, readFileSync, existsSync } from "fs"; import { createReadStream } from "fs"; import { join, resolve, extname, sep, relative, dirname } from "path"; import { watch } from "chokidar"; +import { networkInterfaces } from "os"; import { fileURLToPath } from "url"; import { createJournalServer } from "../journal.js"; import { @@ -49,6 +50,35 @@ function getMimeType(filePath: string): string { return MIME_TYPES[ext] || "application/octet-stream"; } +/** + * Get the best network IP for display (prefer LAN IPv4, fallback to localhost). + */ +function getBestIP(): string { + const interfaces = networkInterfaces(); + let best: string | null = null; + + for (const [, addrs] of Object.entries(interfaces)) { + if (!addrs) continue; + for (const addr of addrs) { + if (addr.family !== "IPv4" || addr.internal) continue; + // Prefer a 192.168.x.x or 10.x.x.x address + if (addr.address.startsWith("192.168.")) { + best = addr.address; + break; + } + if ( + !best && + (addr.address.startsWith("10.") || addr.address.startsWith("172.")) + ) { + best = addr.address; + } + } + if (best?.startsWith("192.168.")) break; + } + + return best || "localhost"; +} + /** * 扫描目录内的 .md 文件,生成索引 */ @@ -320,11 +350,16 @@ export function createContentServer( }); server.listen(port, host, () => { - const displayHost = host === "0.0.0.0" ? "localhost" : host; + const bestIP = getBestIP(); + const displayHost = host === "0.0.0.0" ? bestIP : host; console.log(`\n开发服务器已启动:http://${displayHost}:${port}`); + console.log(`本机访问:http://localhost:${port}`); + if (bestIP !== "localhost") { + console.log(`局域网访问:http://${bestIP}:${port}`); + } console.log(`内容目录:${contentDir}`); console.log(`静态资源目录:${distPath}`); - console.log(`Journal 连接:ws://${displayHost}:${port}\n`); + console.log(`Journal 连接:ws://${bestIP}:${port}\n`); }); return { diff --git a/src/components/journal/JournalInput.tsx b/src/components/journal/JournalInput.tsx index 73057ab..4e558c8 100644 --- a/src/components/journal/JournalInput.tsx +++ b/src/components/journal/JournalInput.tsx @@ -259,7 +259,7 @@ export const JournalInput: Component = () => { ]; } return matches.map((s) => ({ - label: `${s.filePath} § ${s.slug} (${s.notation})`, + label: `${s.slug} (${s.notation})`, kind: "value" as const, insertText: `/spark ${s.slug}`, }));