@kontourai/survey 0.7.2 → 1.0.0
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.
- package/README.md +13 -0
- package/bin/survey-review-console.mjs +7 -0
- package/dist/src/console/review-console-server.d.ts +28 -0
- package/dist/src/console/review-console-server.js +616 -0
- package/dist/src/review-workbench/review-workbench-css.generated.js +274 -63
- package/dist/src/review-workbench/review-workbench-element.js +25 -0
- package/dist/src/review-workbench/review-workbench.css +274 -63
- package/dist/src/review-workbench/review-workbench.js +114 -32
- package/dist/src/review-workbench/review-workbench.standalone.css +274 -63
- package/package.json +4 -3
|
@@ -654,7 +654,7 @@ function renderReviewFocus(state, presentationAdapter) {
|
|
|
654
654
|
<dl class="focus-evidence">
|
|
655
655
|
${fieldItem("Target", presentation.targetLabel)}
|
|
656
656
|
${fieldItem("Proposed source", proposed.source.sourceRef)}
|
|
657
|
-
${
|
|
657
|
+
${fieldItemClamped("Proposed excerpt", proposed.locator?.excerpt ?? "none", "excerpt")}
|
|
658
658
|
</dl>
|
|
659
659
|
</section>
|
|
660
660
|
`;
|
|
@@ -782,13 +782,18 @@ function renderCanonicalClaim(preview) {
|
|
|
782
782
|
]);
|
|
783
783
|
}
|
|
784
784
|
function renderReviewEvent(preview) {
|
|
785
|
-
return
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
785
|
+
return `
|
|
786
|
+
<section class="preview-section" data-testid="surface-review-event">
|
|
787
|
+
<h3>${escapeHtml("Review event")}</h3>
|
|
788
|
+
<dl class="field-stack compact">
|
|
789
|
+
${fieldItem("Actor", preview.reviewEvent?.actor ?? "unknown")}
|
|
790
|
+
${fieldItem("Reviewed at", preview.reviewEvent?.reviewedAt ?? "not recorded")}
|
|
791
|
+
${fieldItem("Status", preview.reviewEvent?.status ?? "pending")}
|
|
792
|
+
${fieldItem("Rationale", preview.reviewEvent?.rationale ?? "No reviewer rationale provided.", "rationale-clamp")}
|
|
793
|
+
${fieldItem("Outcome", preview.reviewEvent?.reviewOutcomeId ?? "not provided")}
|
|
794
|
+
</dl>
|
|
795
|
+
</section>
|
|
796
|
+
`;
|
|
792
797
|
}
|
|
793
798
|
function renderIntegrityPosture(preview) {
|
|
794
799
|
return renderPreviewSection("Integrity posture", "surface-integrity-posture", [
|
|
@@ -806,32 +811,68 @@ function renderAuthorityTrace(preview) {
|
|
|
806
811
|
], preview.authorityTrace.status === "empty" ? " is-neutral" : "");
|
|
807
812
|
}
|
|
808
813
|
function renderCandidateHistory(preview) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
814
|
+
if (preview.candidateHistory.length === 0) {
|
|
815
|
+
return renderPreviewSection("Unselected candidate history", "surface-candidate-history", [["History", "No unselected candidates."]], undefined, []);
|
|
816
|
+
}
|
|
817
|
+
const VISIBLE_COUNT = 3;
|
|
818
|
+
const total = preview.candidateHistory.length;
|
|
819
|
+
const visibleCandidates = preview.candidateHistory.slice(0, VISIBLE_COUNT);
|
|
820
|
+
const overflowCandidates = preview.candidateHistory.slice(VISIBLE_COUNT);
|
|
821
|
+
const renderHistoryRows = (candidates) => candidates.flatMap((candidate) => [
|
|
822
|
+
fieldItem("History", candidate.historyLabel),
|
|
823
|
+
fieldItem("Value", candidate.value),
|
|
824
|
+
]).join("");
|
|
825
|
+
const referenceRows = preview.candidateHistory.map((candidate) => fieldItem("Candidate ID", candidate.candidateId)).join("");
|
|
826
|
+
const overflowHtml = overflowCandidates.length > 0
|
|
827
|
+
? `<div class="history-overflow">${renderHistoryRows(overflowCandidates)}</div>`
|
|
828
|
+
: "";
|
|
829
|
+
const expanderHtml = overflowCandidates.length > 0
|
|
830
|
+
? `<button class="history-expand-btn" type="button" data-history-expand aria-expanded="false">
|
|
831
|
+
<span class="expand-label">view all (${total})</span>
|
|
832
|
+
<span class="collapse-label">show less</span>
|
|
833
|
+
</button>`
|
|
834
|
+
: "";
|
|
835
|
+
return `
|
|
836
|
+
<section class="preview-section" data-testid="surface-candidate-history">
|
|
837
|
+
<h3>${escapeHtml("Unselected candidate history")}</h3>
|
|
838
|
+
<div class="history-expander${overflowCandidates.length > 0 ? "" : ""}" data-history-expander>
|
|
839
|
+
<dl class="field-stack compact">
|
|
840
|
+
${renderHistoryRows(visibleCandidates)}
|
|
841
|
+
${overflowHtml}
|
|
842
|
+
</dl>
|
|
843
|
+
${expanderHtml}
|
|
844
|
+
</div>
|
|
845
|
+
${preview.candidateHistory.length > 0 ? `<details class="reference-details">
|
|
846
|
+
<summary>IDs and trace links</summary>
|
|
847
|
+
<dl class="field-stack compact">${referenceRows}</dl>
|
|
848
|
+
</details>` : ""}
|
|
849
|
+
</section>
|
|
850
|
+
`;
|
|
819
851
|
}
|
|
820
852
|
function renderSourceEvidence(preview) {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
853
|
+
// Excerpt uses a 3-line clamp wrapper with a toggle button.
|
|
854
|
+
const clampedExcerptHtml = fieldItemClamped("Excerpt", preview.sourceEvidence.excerpt, "excerpt");
|
|
855
|
+
// Build source evidence section with clamped excerpt inline
|
|
856
|
+
return `
|
|
857
|
+
<section class="preview-section" data-testid="surface-source-evidence">
|
|
858
|
+
<h3>${escapeHtml("Source evidence")}</h3>
|
|
859
|
+
<dl class="field-stack compact">
|
|
860
|
+
${fieldItem("Source URL", preview.sourceEvidence.sourceRef)}
|
|
861
|
+
${clampedExcerptHtml}
|
|
862
|
+
${fieldItem("Extractor", preview.sourceEvidence.extractor)}
|
|
863
|
+
${fieldItem("Observed", preview.sourceEvidence.observedAt)}
|
|
864
|
+
${preview.sourceEvidence.sourceAuthority ? [
|
|
865
|
+
fieldItem("Source authority class", preview.sourceEvidence.sourceAuthority.authorityClass),
|
|
866
|
+
fieldItem("Declared by", preview.sourceEvidence.sourceAuthority.declaredBy),
|
|
867
|
+
fieldItem("Authority scope", preview.sourceEvidence.sourceAuthority.scope),
|
|
868
|
+
].join("") : ""}
|
|
869
|
+
</dl>
|
|
870
|
+
${renderReferenceDetails([
|
|
828
871
|
["Source ID", preview.sourceEvidence.sourceId],
|
|
829
872
|
["Extraction ID", preview.sourceEvidence.extractionId],
|
|
830
|
-
]
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
}
|
|
834
|
-
return renderPreviewSection("Source evidence", "surface-source-evidence", rows);
|
|
873
|
+
])}
|
|
874
|
+
</section>
|
|
875
|
+
`;
|
|
835
876
|
}
|
|
836
877
|
function renderPreviewSection(title, testId, rows, extraClass = "", references = []) {
|
|
837
878
|
return `
|
|
@@ -969,6 +1010,8 @@ function renderCurrentState(root, session, controller, presentationAdapter) {
|
|
|
969
1010
|
controller.renderCurrentState();
|
|
970
1011
|
});
|
|
971
1012
|
bindQueueDrawer(root);
|
|
1013
|
+
bindClampToggles(root);
|
|
1014
|
+
bindHistoryExpanders(root);
|
|
972
1015
|
}
|
|
973
1016
|
function queueSessionFromStartState(startState) {
|
|
974
1017
|
if ("items" in startState) {
|
|
@@ -1015,6 +1058,29 @@ function bindNextUnresolved(root, goToNextUnresolved) {
|
|
|
1015
1058
|
});
|
|
1016
1059
|
});
|
|
1017
1060
|
}
|
|
1061
|
+
function bindClampToggles(root) {
|
|
1062
|
+
root.querySelectorAll("[data-clamp-toggle]").forEach((button) => {
|
|
1063
|
+
button.addEventListener("click", () => {
|
|
1064
|
+
const clampContainer = button.closest("[data-clamp]");
|
|
1065
|
+
if (!clampContainer)
|
|
1066
|
+
return;
|
|
1067
|
+
const expanded = clampContainer.classList.toggle("is-expanded");
|
|
1068
|
+
button.setAttribute("aria-expanded", String(expanded));
|
|
1069
|
+
button.textContent = expanded ? "less" : "more";
|
|
1070
|
+
});
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
function bindHistoryExpanders(root) {
|
|
1074
|
+
root.querySelectorAll("[data-history-expand]").forEach((button) => {
|
|
1075
|
+
button.addEventListener("click", () => {
|
|
1076
|
+
const expander = button.closest("[data-history-expander]");
|
|
1077
|
+
if (!expander)
|
|
1078
|
+
return;
|
|
1079
|
+
const expanded = expander.classList.toggle("is-expanded");
|
|
1080
|
+
button.setAttribute("aria-expanded", String(expanded));
|
|
1081
|
+
});
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1018
1084
|
function bindQueueDrawer(root) {
|
|
1019
1085
|
const openButton = root.querySelector("[data-testid='mobile-queue-open']");
|
|
1020
1086
|
const closeButton = root.querySelector("[data-testid='queue-drawer-close']");
|
|
@@ -1081,7 +1147,12 @@ function refreshDecisionOutputs(root, state, renderCurrentState, presentationAda
|
|
|
1081
1147
|
}
|
|
1082
1148
|
const wrapper = document.createElement("div");
|
|
1083
1149
|
wrapper.innerHTML = renderSurfacePreview(state, presentationAdapter);
|
|
1084
|
-
|
|
1150
|
+
const newPreview = wrapper.firstElementChild;
|
|
1151
|
+
preview.replaceWith(newPreview);
|
|
1152
|
+
if (newPreview && typeof newPreview.querySelectorAll === "function") {
|
|
1153
|
+
bindClampToggles(newPreview);
|
|
1154
|
+
bindHistoryExpanders(newPreview);
|
|
1155
|
+
}
|
|
1085
1156
|
}
|
|
1086
1157
|
function refreshSessionAudit(root, session, sessionExport, renderCurrentState) {
|
|
1087
1158
|
const audit = root.querySelector("[data-testid='session-audit']");
|
|
@@ -1125,7 +1196,7 @@ function renderCandidateCard(candidate, state, presentationAdapter) {
|
|
|
1125
1196
|
<dl class="field-stack">
|
|
1126
1197
|
${fieldItem("Source URL", presentation.sourceText)}
|
|
1127
1198
|
${fieldItem("Locator", candidate.locator?.locator ?? candidate.locator?.scheme ?? "none")}
|
|
1128
|
-
${
|
|
1199
|
+
${fieldItemClamped("Excerpt", candidate.locator?.excerpt ?? "none", "excerpt")}
|
|
1129
1200
|
${fieldItem("Extraction confidence", confidence === undefined ? "unknown" : formatConfidence(confidence))}
|
|
1130
1201
|
${fieldItem("Extractor", candidate.extraction.extractor ?? "unknown")}
|
|
1131
1202
|
</dl>
|
|
@@ -1153,6 +1224,17 @@ function metaItem(label, value) {
|
|
|
1153
1224
|
</div>
|
|
1154
1225
|
`;
|
|
1155
1226
|
}
|
|
1227
|
+
function fieldItemClamped(label, value, extraClass = "") {
|
|
1228
|
+
return `
|
|
1229
|
+
<div class="field ${extraClass}">
|
|
1230
|
+
<dt class="field-label">${escapeHtml(label)}</dt>
|
|
1231
|
+
<div class="excerpt-clamp" data-clamp>
|
|
1232
|
+
<dd class="field-value">${escapeHtml(value)}</dd>
|
|
1233
|
+
<button class="clamp-toggle" type="button" data-clamp-toggle aria-expanded="false">more</button>
|
|
1234
|
+
</div>
|
|
1235
|
+
</div>
|
|
1236
|
+
`;
|
|
1237
|
+
}
|
|
1156
1238
|
function fieldItem(label, value, extraClass = "") {
|
|
1157
1239
|
return `
|
|
1158
1240
|
<div class="field ${extraClass}">
|