feat(工作台): mcn-workshop 会话超 6 小时自动清除(软删除)

- server.js 启动段新增 cleanupExpiredSessions(): cwd 含 mcn-workshop + status=completed + 最后活动超 6h 且未删 → 置 deleted_at 软删除
- 启动时执行一次 + setInterval 每小时自动检查; working 会话不删(安全红线)
- 实测: 清除 9 条(13.6h~114.8h) 保留 1 条(1.5h 新会话)
This commit is contained in:
maogeigei committed 2026-09-01 14:13:17 +08:00
1 parent 6e8698a469
commit 6bf0eca90e
2 files changed
+36

No files matched your search

@@ -667,6 +667,36 @@ const server = http.createServer((req, res) => {
});
});
// ---- 会话自动清理:mcn-workshop 空间超 6 小时无活动的已结束会话自动清除 ----
// 09-01 用户需求:工作台触发(cwd=D:\AgentSkill\mcn-workshop)的 AI 会话任务,超过 6 小时自动清除
// 判定:cwd 含 mcn-workshop + status=completed(执行中一律不删)+ 未删过 + 最后活动时间超过 6 小时
// 方式:软删除(置 deleted_at),客户端左侧会话栏按 deleted_at 过滤即不再显示;可逆安全
const SESSION_TTL_MS = 6 * 3600 * 1000; // 6 小时
const SESSION_CWD_PATTERN = '%mcn-workshop%'; // 与 /api/run 写入的 cwd 一致
const SESSION_CLEAN_INTERVAL_MS = 60 * 60 * 1000; // 每小时检查一次
function cleanupExpiredSessions() {
try {
const { DatabaseSync } = require('node:sqlite');
const db = new DatabaseSync(process.env.WORKBUDDY_DB || path.join(os.homedir(), '.workbuddy', 'workbuddy.db'));
const now = Date.now();
const cutoff = now - SESSION_TTL_MS;
const r = db.prepare(`
UPDATE sessions SET deleted_at = ?
WHERE cwd LIKE ?
AND status = 'completed'
AND deleted_at IS NULL
AND COALESCE(last_activity_at, updated_at, created_at, 0) < ?
`).run(now, SESSION_CWD_PATTERN, cutoff);
db.close();
if (Number(r.changes) > 0) log(`会话自动清理:已清除 mcn-workshop 超 6 小时无活动的已完成会话 ${r.changes} 条`);
} catch (e) {
console.error('会话自动清理失败:', e.message);
}
}
cleanupExpiredSessions();
setInterval(cleanupExpiredSessions, SESSION_CLEAN_INTERVAL_MS);
// ---- 端口自动避让 ----
function listen(port) {
server.once('error', (e) => {