fix: COD-152 surface Codex generated artifacts

This commit is contained in:
Saqeb Akhter
2026-07-10 20:54:41 -04:00
committed by Aamer Akhter
parent 1fa88cd187
commit f8aa93969b
8 changed files with 304 additions and 21 deletions
+18 -5
View File
@@ -62,6 +62,7 @@ import {
import { imageWatcher } from '../image-watcher.js';
import { workflowRunWatcher, summarizeRun } from '../workflow-run-watcher.js';
import { attachmentRegistry, buildFileThumbnailRoute, registerExternalAttachment } from '../attachment-registry.js';
import { registerGeneratedArtifactAttachment } from '../generated-artifact-attachments.js';
import {
buildDetectedAttachmentHistoryItem,
buildExternalAttachmentHistoryItem,
@@ -1345,13 +1346,25 @@ export class WebServer extends EventEmitter {
* directly inside a managed session). Registration also enforces the COD-53
* blocklist as defense-in-depth.
*/
private async registerAttachment(sessionId: string, filePath: string): Promise<void> {
private async registerAttachment(
sessionId: string,
filePath: string,
source: 'external' | 'codex-generated' = 'external'
): Promise<void> {
const session = this.sessions.get(sessionId);
if (!session) return;
const event = await registerExternalAttachment(sessionId, filePath, {
sessionWorkingDir: session.workingDir,
forceWorkspaceConfinement: true,
});
const event =
source === 'codex-generated'
? await registerGeneratedArtifactAttachment({
sessionId,
filePath,
sessionWorkingDir: session.workingDir,
remote: session.remote,
})
: await registerExternalAttachment(sessionId, filePath, {
sessionWorkingDir: session.workingDir,
forceWorkspaceConfinement: true,
});
const record = attachmentRegistry.get(sessionId, event.attachmentId);
if (record) {
session.upsertAttachmentHistory(
+4 -4
View File
@@ -58,7 +58,7 @@ export interface SessionListenerRefs {
bashToolStart: (tool: ActiveBashTool) => void;
bashToolEnd: (tool: ActiveBashTool) => void;
bashToolsUpdate: (tools: ActiveBashTool[]) => void;
attachmentRequested: (event: { path: string }) => void;
attachmentRequested: (event: { path: string; source?: 'external' | 'codex-generated' }) => void;
}
/** Dependencies injected by WebServer — keeps listener creation decoupled from server internals. */
@@ -78,7 +78,7 @@ interface SessionListenerDeps {
removeSessionListenerRefs(sessionId: string): void;
cleanupRespawnOnExit(sessionId: string): void;
getStore(): import('../state-store.js').StateStore;
registerAttachment(sessionId: string, filePath: string): Promise<void>;
registerAttachment(sessionId: string, filePath: string, source?: 'external' | 'codex-generated'): Promise<void>;
}
/**
@@ -359,8 +359,8 @@ export function createSessionListeners(session: Session, deps: SessionListenerDe
},
/** Registers an explicit attachment card requested by terminal magic text. */
attachmentRequested: (event: { path: string }) => {
deps.registerAttachment(session.id, event.path).catch((err) => {
attachmentRequested: (event: { path: string; source?: 'external' | 'codex-generated' }) => {
deps.registerAttachment(session.id, event.path, event.source).catch((err) => {
console.error(`[Attachment] Failed to register ${event.path} for ${session.id}:`, err);
});
},