feat(cleanup): exec_review 合并后回收 runs/<runId>/ 工作目录 + 定期扫尾 [tsk_6uziW1Dg-ftQ]
每个 run 在 ~/.maestro/runs/<runId>/ 留下 job.json/outbox.ndjson/heartbeat,
合并(exec_review accept)后不再需要,需回收避免无限堆积。
- protocol.ts:新增 removeRunDir / isPlainRunId(幂等删 runDir,runId 白名单防越界)
- cleanup.ts(新):
- cleanupTaskRunArtifacts:合并/接受后即时回收某任务全部 run 工作目录
- sweepRunArtifacts:周期扫尾终态/孤儿 runDir 与(可选)转录,按保留天数
- isRunCleanable:仅终态(done/cancelled)/孤儿可回收,活跃/在途一律保留
- 双保险:任务状态判定 + heartbeat 新鲜则跳过,绝不误删活跃 run
- 保留策略可配:MAESTRO_RUN_RETENTION_DAYS(默认3) /
MAESTRO_TRANSCRIPT_RETENTION_DAYS(默认0=永久保留,便于排查)
- server.ts:exec_review accept 合并成功后即时清 runDir(与 removeWorktree 同处)
- index.ts:startCleanupLoop 定时扫尾(MAESTRO_CLEANUP_INTERVAL 秒,默认3600,0=关闭)
- test/cleanup.test.ts:终态清/在途留/孤儿清/保留期/heartbeat 兜底/转录开关/配置
测试:npm test → 164 passed;npm run typecheck → clean
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { resolvedExecutorModels } from '../executor/models.js';
|
||||
import { classifyComplexity, type ClassifierFn } from '../executor/classify.js';
|
||||
import { mergeBranch } from '../executor/merge.js';
|
||||
import { git, removeWorktree } from '../executor/worktree.js';
|
||||
import { cleanupTaskRunArtifacts } from '../executor/cleanup.js';
|
||||
import { resolveLogo, LOGO_MIME } from './logo.js';
|
||||
import { readTranscript, TranscriptError } from '../executor/transcript.js';
|
||||
import { createReadStream } from 'node:fs';
|
||||
@@ -332,6 +333,10 @@ export function buildServer(opts: ApiOptions): FastifyInstance {
|
||||
store.decide(id, 'accept', b.actor ?? 'user', b.reason ?? null);
|
||||
// 合并产物记录:复用 prUrl 字段写 merged:<mergeCommit>
|
||||
store.setResult(id, { ...task.result, prUrl: `merged:${mr.mergeCommit}` });
|
||||
// 即时回收 runs/<runId>/(job/outbox/heartbeat 已无价值;转录保留供排查)。
|
||||
// 任务此刻已 done(终态),cleanupTaskRunArtifacts 内部据此放行;同步删(纯本地 fs,快)。
|
||||
const reclaimed = cleanupTaskRunArtifacts(store, id, app.log);
|
||||
if (reclaimed) app.log.info(`任务 ${id} 合并后回收 ${reclaimed} 个 run 工作目录`);
|
||||
// 异步回收:执行 worktree + 已合并的任务分支(失败只记日志,不影响响应)
|
||||
void (async () => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user