vibe-coding-master 0.4.39 → 0.4.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -14,8 +14,8 @@ export function registerTranslationRoutes(app, deps) {
|
|
|
14
14
|
});
|
|
15
15
|
});
|
|
16
16
|
app.get("/api/translation/sessions/:sessionId/events", async (request) => {
|
|
17
|
-
await requireCurrentProject(deps.projectService);
|
|
18
|
-
return deps.translationService.pollSessionEvents(request.params.sessionId, Number(request.query.after ?? "1"), request.query.limit === undefined ? undefined : Number(request.query.limit));
|
|
17
|
+
const project = await requireCurrentProject(deps.projectService);
|
|
18
|
+
return deps.translationService.pollSessionEvents(request.params.sessionId, Number(request.query.after ?? "1"), request.query.limit === undefined ? undefined : Number(request.query.limit), { repoRoot: project.repoRoot });
|
|
19
19
|
});
|
|
20
20
|
app.post("/api/tasks/:taskSlug/sessions/:role/translation/input", async (request) => {
|
|
21
21
|
const project = await requireCurrentProject(deps.projectService);
|
|
@@ -124,6 +124,7 @@ export function createTranslationService(deps) {
|
|
|
124
124
|
for (const event of state.events) {
|
|
125
125
|
if (event.type === "entry") {
|
|
126
126
|
state.entries = upsertEntry(state.entries, event.entry);
|
|
127
|
+
state.seenTranscriptIds.add(event.entry.id);
|
|
127
128
|
}
|
|
128
129
|
else if (event.type === "status") {
|
|
129
130
|
state.status = event.status;
|
|
@@ -159,10 +160,20 @@ export function createTranslationService(deps) {
|
|
|
159
160
|
const state = getState(roleSession.id);
|
|
160
161
|
state.taskSlug = roleSession.taskSlug;
|
|
161
162
|
state.role = roleSession.role;
|
|
162
|
-
|
|
163
|
+
const transcriptSessionKey = getTranscriptSessionKey(roleSession);
|
|
164
|
+
if (!transcriptSessionKey) {
|
|
163
165
|
return;
|
|
164
166
|
}
|
|
167
|
+
if (state.unsubscribeTranscript) {
|
|
168
|
+
if (state.transcriptSessionKey === transcriptSessionKey) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
state.unsubscribeTranscript();
|
|
172
|
+
state.unsubscribeTranscript = undefined;
|
|
173
|
+
state.transcriptSessionKey = undefined;
|
|
174
|
+
}
|
|
165
175
|
const replaySince = getTranscriptReplaySince(roleSession);
|
|
176
|
+
state.transcriptSessionKey = transcriptSessionKey;
|
|
166
177
|
state.unsubscribeTranscript = deps.transcripts.subscribeToRoleSession(roleSession, (event) => {
|
|
167
178
|
void handleTranscriptEvent(roleSession.id, event).catch((error) => {
|
|
168
179
|
publishError(roleSession.id, normalizeTranslationError(error, "Process Claude transcript event for translation failed."));
|
|
@@ -537,6 +548,7 @@ export function createTranslationService(deps) {
|
|
|
537
548
|
state.unsubscribeTranscript();
|
|
538
549
|
state.unsubscribeTranscript = undefined;
|
|
539
550
|
}
|
|
551
|
+
state.transcriptSessionKey = undefined;
|
|
540
552
|
if (state.outputBatch?.timer) {
|
|
541
553
|
clearTimeout(state.outputBatch.timer);
|
|
542
554
|
}
|
|
@@ -551,6 +563,24 @@ export function createTranslationService(deps) {
|
|
|
551
563
|
await state.persistChain?.catch(() => undefined);
|
|
552
564
|
sessionStates.delete(sessionId);
|
|
553
565
|
}
|
|
566
|
+
async function ensureSessionForPoll(sessionId, context) {
|
|
567
|
+
const roleSession = deps.sessionRegistry.get(sessionId);
|
|
568
|
+
const existing = sessionStates.get(sessionId);
|
|
569
|
+
if (!roleSession || roleSession.status !== "running") {
|
|
570
|
+
return existing;
|
|
571
|
+
}
|
|
572
|
+
const state = context
|
|
573
|
+
? await prepareCache({
|
|
574
|
+
repoRoot: roleSession.cwd,
|
|
575
|
+
baseRepoRoot: context.repoRoot,
|
|
576
|
+
taskSlug: roleSession.taskSlug,
|
|
577
|
+
role: roleSession.role,
|
|
578
|
+
sessionId: roleSession.id
|
|
579
|
+
})
|
|
580
|
+
: getState(sessionId);
|
|
581
|
+
startTranscriptTail(roleSession);
|
|
582
|
+
return state;
|
|
583
|
+
}
|
|
554
584
|
return {
|
|
555
585
|
async startSession(input) {
|
|
556
586
|
const roleSession = await deps.sessionService.getRoleSession(input.repoRoot, input.taskSlug, input.role);
|
|
@@ -575,9 +605,9 @@ export function createTranslationService(deps) {
|
|
|
575
605
|
nextCursor: 1
|
|
576
606
|
};
|
|
577
607
|
},
|
|
578
|
-
async pollSessionEvents(sessionId, after, limit = 200) {
|
|
608
|
+
async pollSessionEvents(sessionId, after, limit = 200, context) {
|
|
579
609
|
const cursor = Number.isFinite(after) ? Math.max(1, Math.floor(after)) : 1;
|
|
580
|
-
const state =
|
|
610
|
+
const state = await ensureSessionForPoll(sessionId, context);
|
|
581
611
|
if (!state) {
|
|
582
612
|
return {
|
|
583
613
|
sessionId,
|
|
@@ -1010,13 +1040,26 @@ function delay(ms) {
|
|
|
1010
1040
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1011
1041
|
}
|
|
1012
1042
|
function getTranscriptReplaySince(roleSession) {
|
|
1013
|
-
const rawTimestamp = roleSession.
|
|
1043
|
+
const rawTimestamp = roleSession.lastTurnStartedAt
|
|
1044
|
+
?? roleSession.lastHookEventAt
|
|
1045
|
+
?? roleSession.updatedAt
|
|
1046
|
+
?? roleSession.startedAt;
|
|
1014
1047
|
const timestampMs = Date.parse(rawTimestamp);
|
|
1015
1048
|
if (!Number.isFinite(timestampMs)) {
|
|
1016
1049
|
return undefined;
|
|
1017
1050
|
}
|
|
1018
1051
|
return new Date(Math.max(0, timestampMs - TRANSCRIPT_REPLAY_GRACE_MS)).toISOString();
|
|
1019
1052
|
}
|
|
1053
|
+
function getTranscriptSessionKey(roleSession) {
|
|
1054
|
+
if (!roleSession.claudeSessionId && !roleSession.transcriptPath) {
|
|
1055
|
+
return undefined;
|
|
1056
|
+
}
|
|
1057
|
+
return [
|
|
1058
|
+
roleSession.cwd,
|
|
1059
|
+
roleSession.claudeSessionId,
|
|
1060
|
+
roleSession.transcriptPath
|
|
1061
|
+
].join("\n");
|
|
1062
|
+
}
|
|
1020
1063
|
function formatStructuredTranscriptEvent(event) {
|
|
1021
1064
|
if (event.kind === "question") {
|
|
1022
1065
|
return event.question.questions.map((question, index) => {
|