merge: maestro/tsk_O9q0_u78_NPo [tsk_O9q0_u78_NPo]

This commit is contained in:
maestro
2026-06-13 11:35:20 +08:00
6 changed files with 512 additions and 6 deletions
+22
View File
@@ -10,6 +10,7 @@ import { resolvedExecutorModels } from '../executor/models.js';
import { mergeBranch } from '../executor/merge.js';
import { git, removeWorktree } from '../executor/worktree.js';
import { resolveLogo, LOGO_MIME } from './logo.js';
import { readTranscript, TranscriptError } from '../executor/transcript.js';
import { createReadStream } from 'node:fs';
import { createUsageFetcher, type UsageInfo } from '../daemon/usage.js';
@@ -205,6 +206,27 @@ export function buildServer(opts: ApiOptions): FastifyInstance {
return store.listRuns(id);
});
// 执行转录回放:读 run.transcriptRef 指向的 jsonl,逐行解析成脱敏后的结构化消息数组。
// 校验:runId 合法 → 关联任务/项目存在(可访问)→ 有转录记录 → 路径在 transcriptDir 下(防穿越)。
app.get('/api/runs/:id/transcript', (req, reply) => {
const { id } = req.params as { id: string };
const run = store.getRun(id);
if (!run) return reply.code(404).send({ error: `run 不存在: ${id}` });
const task = store.getTask(run.taskId);
if (!task) return reply.code(404).send({ error: `run 关联任务不存在: ${run.taskId}` });
if (!store.getProject(task.projectId)) return reply.code(404).send({ error: `run 关联项目不存在: ${task.projectId}` });
if (!run.transcriptRef) return reply.code(404).send({ error: '该 run 没有转录记录' });
try {
const messages = readTranscript(run.transcriptRef);
return { runId: run.id, taskId: run.taskId, kind: run.kind, status: run.status, messages };
} catch (e) {
if (e instanceof TranscriptError) {
return reply.code(e.code === 'invalid_path' ? 400 : 404).send({ error: e.message });
}
throw e;
}
});
// 单任务全量事件(升序):归档详情的状态流转时间线
app.get('/api/tasks/:id/events', (req) => {
const { id } = req.params as { id: string };