35958b408c
- Web: 点击节点在底部代码面板展示源码(语法高亮、可折叠) - Web: 画布按目录/文件聚类为背景框,头部新增分组模式切换(目录/文件/无) - Web: 流程横幅、流程/分组列表与节点详情展示 summary - CLI: 新增 overview 推导与运行器 - scripts: 手动标注 self-report summary Co-authored-by: Cursor <cursoragent@cursor.com>
61 lines
2.1 KiB
TypeScript
61 lines
2.1 KiB
TypeScript
import { defineConfig, type Plugin } from "vite";
|
|
import react from "@vitejs/plugin-react";
|
|
import { readFileSync } from "node:fs";
|
|
import { resolve, sep } from "node:path";
|
|
|
|
/**
|
|
* 开发期源码服务:GET /__source?root=&file=&start=&end=
|
|
* 按报告里的 location 从磁盘读取真实源码片段,实现「报告 → 代码库」绑定。
|
|
* 仅用于本地开发;做了基本的路径穿越防护(结果路径必须落在 root 内)。
|
|
*/
|
|
function sourceServer(): Plugin {
|
|
return {
|
|
name: "code-visualize-source-server",
|
|
configureServer(server) {
|
|
server.middlewares.use("/__source", (req, res) => {
|
|
try {
|
|
const url = new URL(req.url ?? "", "http://localhost");
|
|
const root = url.searchParams.get("root") ?? "";
|
|
const file = url.searchParams.get("file") ?? "";
|
|
const start = Number(url.searchParams.get("start") ?? "1");
|
|
const end = Number(url.searchParams.get("end") ?? String(start));
|
|
|
|
if (!root || !file) {
|
|
res.statusCode = 400;
|
|
res.end("missing root/file");
|
|
return;
|
|
}
|
|
|
|
const rootResolved = resolve(root);
|
|
const target = resolve(rootResolved, file);
|
|
if (target !== rootResolved && !target.startsWith(rootResolved + sep)) {
|
|
res.statusCode = 403;
|
|
res.end("path escapes root");
|
|
return;
|
|
}
|
|
|
|
const content = readFileSync(target, "utf-8");
|
|
const allLines = content.split(/\r?\n/);
|
|
const from = Math.max(1, start);
|
|
const to = Math.min(allLines.length, Math.max(from, end));
|
|
const code = allLines.slice(from - 1, to).join("\n");
|
|
|
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
res.end(JSON.stringify({ file, startLine: from, endLine: to, code }));
|
|
} catch (e) {
|
|
res.statusCode = 404;
|
|
res.end(e instanceof Error ? e.message : "read error");
|
|
}
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
plugins: [react(), sourceServer()],
|
|
server: {
|
|
port: 5300,
|
|
open: true,
|
|
},
|
|
});
|