Expose bridge handoff status in Ranker results
This commit is contained in:
+66
-3
@@ -52,10 +52,14 @@ function laneClass(lane) {
|
||||
}
|
||||
|
||||
function parsePastedJsonPayload(value) {
|
||||
const text = String(value || '').trim();
|
||||
if (!text.startsWith('{') || !text.endsWith('}')) return null;
|
||||
const text = String(value || '').trim()
|
||||
.replace(/^```(?:json)?\s*/i, '')
|
||||
.replace(/```$/i, '')
|
||||
.trim();
|
||||
const jsonText = text.startsWith('{') && text.endsWith('}') ? text : extractFirstJsonObject(text);
|
||||
if (!jsonText) return null;
|
||||
try {
|
||||
const parsed = JSON.parse(text);
|
||||
const parsed = JSON.parse(jsonText);
|
||||
const looksLikeBridgePayload = parsed && typeof parsed === 'object' && !Array.isArray(parsed) && (
|
||||
parsed.schema || parsed.featureSet || parsed.conceptMap || parsed.lenses || parsed.reference_code || parsed.referenceCode || parsed.artifactId || parsed.ideaText
|
||||
);
|
||||
@@ -65,6 +69,36 @@ function parsePastedJsonPayload(value) {
|
||||
}
|
||||
}
|
||||
|
||||
function extractFirstJsonObject(text = '') {
|
||||
const start = text.indexOf('{');
|
||||
if (start < 0) return '';
|
||||
let depth = 0;
|
||||
let inString = false;
|
||||
let escaped = false;
|
||||
for (let index = start; index < text.length; index += 1) {
|
||||
const char = text[index];
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
if (char === '\\' && inString) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (char === '"') {
|
||||
inString = !inString;
|
||||
continue;
|
||||
}
|
||||
if (inString) continue;
|
||||
if (char === '{') depth += 1;
|
||||
if (char === '}') {
|
||||
depth -= 1;
|
||||
if (depth === 0) return text.slice(start, index + 1);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function payloadFromForm(formPayload) {
|
||||
const ideaJson = parsePastedJsonPayload(formPayload.idea);
|
||||
const optionsJson = parsePastedJsonPayload(formPayload.optionsText);
|
||||
@@ -94,6 +128,33 @@ function renderPills(items = []) {
|
||||
return `<div class="signal-pills">${items.map((item) => `<span>${escapeHtml(item)}</span>`).join('')}</div>`;
|
||||
}
|
||||
|
||||
function renderSourceTrace(sourceTrace = {}) {
|
||||
const hasTrace = sourceTrace.sourceSection || sourceTrace.sourceId || sourceTrace.sourceQuote;
|
||||
if (!hasTrace) return '';
|
||||
const label = [sourceTrace.sourceTitle, sourceTrace.sourceId || sourceTrace.sourceSection].filter(Boolean).join(' · ');
|
||||
return `
|
||||
<div class="source-trace">
|
||||
<span>Source trace</span>
|
||||
${label ? `<b>${escapeHtml(label)}</b>` : ''}
|
||||
${sourceTrace.sourceQuote ? `<p>${escapeHtml(sourceTrace.sourceQuote)}</p>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderHandoffStatus(handoff = {}) {
|
||||
const readiness = handoff.readiness || {};
|
||||
if (!readiness.status) return '';
|
||||
const warnings = handoff.warnings || [];
|
||||
return `
|
||||
<article class="brief-card handoff-card status-${escapeHtml(readiness.status)}">
|
||||
<span>Bridge handoff readiness</span>
|
||||
<p><b>${escapeHtml(readiness.label || readiness.status)}</b> — ${escapeHtml(readiness.summary || '')}</p>
|
||||
${(readiness.nextChecks || []).length ? `<ol>${readiness.nextChecks.map((step) => `<li>${escapeHtml(step)}</li>`).join('')}</ol>` : ''}
|
||||
${warnings.length ? `<div class="handoff-warnings">${warnings.map((warning) => `<code>${escapeHtml(warning)}</code>`).join('')}</div>` : ''}
|
||||
</article>
|
||||
`;
|
||||
}
|
||||
|
||||
function renderRankCard(item) {
|
||||
return `
|
||||
<article class="rank-card ${laneClass(item.lane)}">
|
||||
@@ -198,6 +259,7 @@ function renderResults(data) {
|
||||
<div><span>Proof to collect</span><p>${escapeHtml(glance.evidenceQuestion || 'Name the evidence that would change the ranking.')}</p></div>
|
||||
<div><span>Trap to avoid</span><p>${escapeHtml(glance.biggestTrap || brief.caution || 'Do not treat first-pass judgement as final truth.')}</p></div>
|
||||
</section>
|
||||
${renderSourceTrace(glance.sourceTrace || {})}
|
||||
|
||||
<div class="result-actions" aria-label="Copy result actions">
|
||||
<button class="button ghost" type="button" id="copyBrief">Copy decision brief</button>
|
||||
@@ -218,6 +280,7 @@ function renderResults(data) {
|
||||
<span>Rank confidence</span>
|
||||
<p><b>${escapeHtml(data.rankConfidence?.level || 'First pass')}</b> — ${escapeHtml(data.rankConfidence?.reason || brief.caution || '')}</p>
|
||||
</article>
|
||||
${renderHandoffStatus(data.handoff || {})}
|
||||
${(brief.whatWouldChangeRanking || []).length ? `
|
||||
<article class="brief-card next-card">
|
||||
<span>What would change the order</span>
|
||||
|
||||
Reference in New Issue
Block a user