fix(mindspace): edit_file 落盘、Finish 聊天 merge 与回归守卫

- finish-sync 支持 edit_file 覆盖 public HTML
- Finish 同步 merge 本地流式消息,剥离 agent 内部前缀
- 新增 verify:mindspace-publish-guards 与 AGENTS.md 跨工具说明
- 发版脚本接入回归门禁;103 runtime 发布含备份回退

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-06-30 00:27:15 +08:00
parent 742aee7148
commit 98721371a4
31 changed files with 1440 additions and 141 deletions
+12 -4
View File
@@ -258,7 +258,7 @@ export function sanitizeSessionConversationPublicHtmlLinks(conversation, current
return conversation.map((message) => sanitizeSessionMessagePublicHtmlLinks(message, currentUser));
}
function createSessionEventSanitizer(currentUser) {
function createSessionEventSanitizer(currentUser, { onEvent } = {}) {
let buffer = '';
const flushChunk = (controller, chunk) => {
if (!chunk) return;
@@ -277,6 +277,13 @@ function createSessionEventSanitizer(currentUser) {
} catch {
return line;
}
if (typeof onEvent === 'function') {
try {
onEvent(event);
} catch {
// Ignore side-effect failures and keep SSE flowing to the client.
}
}
if (event?.type === 'Message' && event.message) {
event.message = sanitizeSessionMessagePublicHtmlLinks(event.message, currentUser);
} else if (event?.type === 'UpdateConversation' && Array.isArray(event.conversation)) {
@@ -1196,7 +1203,7 @@ export function createTkmindProxy({
},
];
const proxySessionEvents = async (req, res, sessionId, { onAfterFinish } = {}) => {
const proxySessionEvents = async (req, res, sessionId, { onAfterFinish, onEvent } = {}) => {
try {
const pathname = `/sessions/${sessionId}/events`;
const sessionTarget = await resolveTarget(sessionId);
@@ -1248,7 +1255,7 @@ export function createTkmindProxy({
});
const source = Readable.fromWeb(upstream.body);
const linkSanitizer = createSessionEventSanitizer(req.currentUser);
const linkSanitizer = createSessionEventSanitizer(req.currentUser, { onEvent });
// 每 20s 发一个注释行保持连接,防止 nginx/代理因静默超时切断 SSE
const keepalive = setInterval(() => {
@@ -1291,7 +1298,8 @@ export function createTkmindProxy({
}
const isAgentRunPath =
(req.method === 'POST' && pathname === '/agent/runs')
|| (req.method === 'GET' && /^\/agent\/runs\/[^/]+$/.test(pathname));
|| (req.method === 'GET' && /^\/agent\/runs\/[^/]+$/.test(pathname))
|| (req.method === 'GET' && /^\/agent\/runs\/[^/]+\/events$/.test(pathname));
if (isAgentRunPath) {
res.status(503).json({
message: 'Agent Run 接口需在 Portal 本地处理,请确认 server.mjs 已更新并重启后端',