diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b071d57..b0d66d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -184,7 +184,7 @@ PlanProof values correctness over persuasion. - [X] PR 3.2: Defensive Rendering - [X] PR 3.3: Failure/Rejection Styles - [X] PR 3.4: Assumptions & Questions (Show the AI's "Why"). -- [ ] PR 4.1: Opik Trace Link (Show the "View Trace" button for the judges). +- [X] PR 4.1: Opik Trace Link (Show the "View Trace" button for the judges). ## Backend Lane (Codex) diff --git a/apps/api/static/app.js b/apps/api/static/app.js index 1d74a33..e8c5dc5 100644 --- a/apps/api/static/app.js +++ b/apps/api/static/app.js @@ -55,6 +55,10 @@ const elements = { // Errors errorsSection: document.getElementById('errors-section'), errorsList: document.getElementById('errors-list'), + + // Opik Trace Link (PR 4.1) + traceSection: document.getElementById('trace-section'), + traceLink: document.getElementById('trace-link'), }; // ========================================================================== @@ -211,6 +215,33 @@ function renderErrors(errors, isPriority = false) { }); } +// ========================================================================== +// Opik Trace Link (PR 4.1) +// ========================================================================== + +/** + * Shows or hides the Opik trace link section. + * @param {boolean} visible - Whether to show the trace link + * @param {string|null} traceUrl - Optional custom trace URL + */ +function renderTraceLink(visible, traceUrl = null) { + const section = elements.traceSection; + const link = elements.traceLink; + if (!section) return; + + if (!visible) { + section.classList.add('trace-section--hidden'); + return; + } + + section.classList.remove('trace-section--hidden'); + + // Update URL if provided (for future per-trace linking) + if (traceUrl && link) { + link.href = traceUrl; + } +} + // ========================================================================== // Metrics Grid Rendering (PR 1.4) // ========================================================================== @@ -558,6 +589,7 @@ function renderValidation(validation) { renderMetricsGrid(null); renderCoverage(null); renderErrors([]); + renderTraceLink(false); return; } @@ -579,6 +611,9 @@ function renderValidation(validation) { // Render errors with priority highlighting if failed (PR 3.3) const isFailed = status === 'fail'; renderErrors(validation.errors || [], isFailed); + + // Show trace link after validation is rendered (PR 4.1) + renderTraceLink(true); } /** @@ -964,6 +999,7 @@ window.PlanProof = { showLoadingState, hideLoadingState, renderApiError, + renderTraceLink, generatePlan, formatTime, }; diff --git a/apps/api/static/index.html b/apps/api/static/index.html index 8872bcd..7ccbb5f 100644 --- a/apps/api/static/index.html +++ b/apps/api/static/index.html @@ -213,6 +213,22 @@