@claritylabs/cl-sdk 3.0.4 → 3.0.6
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/dist/index.js +157 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +157 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9411,6 +9411,150 @@ function cleanText(value, fallback) {
|
|
|
9411
9411
|
const text = value?.replace(/\s+/g, " ").trim();
|
|
9412
9412
|
return text || fallback;
|
|
9413
9413
|
}
|
|
9414
|
+
function simplifyOrganizerTitle(value, fallback, kind) {
|
|
9415
|
+
const title = cleanText(value, fallback);
|
|
9416
|
+
if (/^declarations\b/i.test(title)) return "Declarations";
|
|
9417
|
+
if (/^policy\s+form\b/i.test(title)) return "Policy Form";
|
|
9418
|
+
if (/^definitions\b/i.test(title)) return "Definitions";
|
|
9419
|
+
if (kind === "page_group" && /^endorsements?\b/i.test(title)) return "Endorsements";
|
|
9420
|
+
const endorsementNumber = title.match(/^endorsement\s+(?:no\.?|number|#)?\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1];
|
|
9421
|
+
if (endorsementNumber) return `Endorsement No. ${endorsementNumber}`;
|
|
9422
|
+
if (kind === "endorsement" && /^endorsements?\s+\d+\s*[–-]\s*\d+\b/i.test(title)) {
|
|
9423
|
+
return title.replace(/[–—]/g, "-").replace(/\s*\(.*/, "").trim();
|
|
9424
|
+
}
|
|
9425
|
+
return title;
|
|
9426
|
+
}
|
|
9427
|
+
function endorsementReference(value) {
|
|
9428
|
+
return value?.match(/\bendorsement\s+(?:no\.?|number|#)?\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9429
|
+
}
|
|
9430
|
+
function endorsementTitle(value) {
|
|
9431
|
+
const text = cleanText(value, "");
|
|
9432
|
+
const number = text.match(/\bendorsement\s+(?:no\.?|number|#)\s*([A-Z0-9][A-Z0-9.-]*)\b/i)?.[1]?.toUpperCase();
|
|
9433
|
+
return number ? `Endorsement No. ${number}` : void 0;
|
|
9434
|
+
}
|
|
9435
|
+
function rejectsOrganizerGroup(group, children) {
|
|
9436
|
+
if (/^endorsements?\b/i.test(group.title) && group.kind !== "page_group") return true;
|
|
9437
|
+
if (group.kind !== "endorsement") return false;
|
|
9438
|
+
if (/^endorsements?\s+\d+\s*[–-]\s*\d+\b/i.test(group.title)) return true;
|
|
9439
|
+
const childNumbers = new Set(
|
|
9440
|
+
children.map((child) => endorsementReference([child.title, child.description, child.textExcerpt].filter(Boolean).join(" "))).filter((value) => Boolean(value))
|
|
9441
|
+
);
|
|
9442
|
+
return childNumbers.size > 1;
|
|
9443
|
+
}
|
|
9444
|
+
function isEndorsementGroup(node) {
|
|
9445
|
+
return node.kind === "page_group" && /^endorsements?\b/i.test(node.title);
|
|
9446
|
+
}
|
|
9447
|
+
function endorsementGroupNodeId(documentId, parentId) {
|
|
9448
|
+
return [
|
|
9449
|
+
documentId.replace(/[^a-zA-Z0-9_.:-]/g, "_"),
|
|
9450
|
+
"source_node",
|
|
9451
|
+
"page_group",
|
|
9452
|
+
"endorsements",
|
|
9453
|
+
parentId?.replace(/[^a-zA-Z0-9_.:-]/g, "_").slice(0, 48) ?? "root"
|
|
9454
|
+
].join(":");
|
|
9455
|
+
}
|
|
9456
|
+
function applyEndorsementGrouping(sourceTree) {
|
|
9457
|
+
const relabeledTree = sourceTree.map((node) => {
|
|
9458
|
+
if (node.kind === "document" || isEndorsementGroup(node) || node.kind === "endorsement") return node;
|
|
9459
|
+
const title = endorsementTitle([node.title, node.description, node.textExcerpt].filter(Boolean).join(" "));
|
|
9460
|
+
if (!title) return node;
|
|
9461
|
+
return {
|
|
9462
|
+
...node,
|
|
9463
|
+
kind: "endorsement",
|
|
9464
|
+
title,
|
|
9465
|
+
description: cleanText(
|
|
9466
|
+
[title, "endorsement", node.pageStart ? `page ${node.pageStart}` : void 0, node.textExcerpt].filter(Boolean).join(" | "),
|
|
9467
|
+
title
|
|
9468
|
+
),
|
|
9469
|
+
metadata: {
|
|
9470
|
+
...node.metadata,
|
|
9471
|
+
organizerRepair: "normalize_endorsement_grouping"
|
|
9472
|
+
}
|
|
9473
|
+
};
|
|
9474
|
+
});
|
|
9475
|
+
const byParent = nodesByParent(relabeledTree);
|
|
9476
|
+
const groupsByParent = /* @__PURE__ */ new Map();
|
|
9477
|
+
const endorsementGroupIds = new Set(
|
|
9478
|
+
relabeledTree.filter(isEndorsementGroup).map((node) => node.id)
|
|
9479
|
+
);
|
|
9480
|
+
let nextTree = relabeledTree.map((node) => {
|
|
9481
|
+
if (!isEndorsementGroup(node)) return node;
|
|
9482
|
+
const normalized = {
|
|
9483
|
+
...node,
|
|
9484
|
+
kind: "page_group",
|
|
9485
|
+
title: "Endorsements",
|
|
9486
|
+
description: cleanText(node.description, "Endorsement forms grouped by source order"),
|
|
9487
|
+
metadata: {
|
|
9488
|
+
...node.metadata,
|
|
9489
|
+
sourceTreeVersion: "v3",
|
|
9490
|
+
organizer: node.metadata?.organizer ?? "endorsement_grouping"
|
|
9491
|
+
}
|
|
9492
|
+
};
|
|
9493
|
+
groupsByParent.set(node.parentId, normalized);
|
|
9494
|
+
endorsementGroupIds.add(node.id);
|
|
9495
|
+
return normalized;
|
|
9496
|
+
});
|
|
9497
|
+
nextTree = nextTree.map((node) => {
|
|
9498
|
+
if (!endorsementGroupIds.has(node.parentId ?? "")) return node;
|
|
9499
|
+
const title = endorsementTitle([node.title, node.description, node.textExcerpt].filter(Boolean).join(" "));
|
|
9500
|
+
if (!title) return node;
|
|
9501
|
+
return {
|
|
9502
|
+
...node,
|
|
9503
|
+
kind: "endorsement",
|
|
9504
|
+
title,
|
|
9505
|
+
description: cleanText(
|
|
9506
|
+
[title, "endorsement", node.pageStart ? `page ${node.pageStart}` : void 0, node.textExcerpt].filter(Boolean).join(" | "),
|
|
9507
|
+
title
|
|
9508
|
+
),
|
|
9509
|
+
metadata: {
|
|
9510
|
+
...node.metadata,
|
|
9511
|
+
organizerRepair: "normalize_endorsement_grouping"
|
|
9512
|
+
}
|
|
9513
|
+
};
|
|
9514
|
+
});
|
|
9515
|
+
for (const [parentId, children] of byParent) {
|
|
9516
|
+
if (endorsementGroupIds.has(parentId ?? "")) continue;
|
|
9517
|
+
const endorsementChildren = children.filter((child) => child.kind === "endorsement" && !isEndorsementGroup(child));
|
|
9518
|
+
if (endorsementChildren.length < 2) continue;
|
|
9519
|
+
const documentId = endorsementChildren[0].documentId;
|
|
9520
|
+
const pageStarts = endorsementChildren.map((child) => child.pageStart).filter((page) => typeof page === "number");
|
|
9521
|
+
const pageEnds = endorsementChildren.map((child) => child.pageEnd ?? child.pageStart).filter((page) => typeof page === "number");
|
|
9522
|
+
const order = Math.min(...endorsementChildren.map((child) => child.order));
|
|
9523
|
+
const existingGroup = groupsByParent.get(parentId);
|
|
9524
|
+
const groupId = existingGroup?.id ?? endorsementGroupNodeId(documentId, parentId);
|
|
9525
|
+
const groupNode = existingGroup ?? {
|
|
9526
|
+
id: groupId,
|
|
9527
|
+
documentId,
|
|
9528
|
+
parentId,
|
|
9529
|
+
kind: "page_group",
|
|
9530
|
+
title: "Endorsements",
|
|
9531
|
+
description: "Endorsement forms grouped by source order",
|
|
9532
|
+
textExcerpt: void 0,
|
|
9533
|
+
sourceSpanIds: [],
|
|
9534
|
+
pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
|
|
9535
|
+
pageEnd: pageEnds.length ? Math.max(...pageEnds) : void 0,
|
|
9536
|
+
bbox: endorsementChildren.flatMap((child) => child.bbox ?? []).slice(0, 12),
|
|
9537
|
+
order,
|
|
9538
|
+
path: "",
|
|
9539
|
+
metadata: { sourceTreeVersion: "v3", organizer: "endorsement_grouping" }
|
|
9540
|
+
};
|
|
9541
|
+
const childSpanIds = [...new Set(endorsementChildren.flatMap((child) => child.sourceSpanIds))];
|
|
9542
|
+
const normalizedGroup = {
|
|
9543
|
+
...groupNode,
|
|
9544
|
+
sourceSpanIds: groupNode.sourceSpanIds.length ? groupNode.sourceSpanIds : childSpanIds,
|
|
9545
|
+
pageStart: groupNode.pageStart ?? (pageStarts.length ? Math.min(...pageStarts) : void 0),
|
|
9546
|
+
pageEnd: groupNode.pageEnd ?? (pageEnds.length ? Math.max(...pageEnds) : void 0),
|
|
9547
|
+
order
|
|
9548
|
+
};
|
|
9549
|
+
groupsByParent.set(parentId, normalizedGroup);
|
|
9550
|
+
if (!existingGroup) nextTree.push(normalizedGroup);
|
|
9551
|
+
else nextTree = nextTree.map((node) => node.id === normalizedGroup.id ? normalizedGroup : node);
|
|
9552
|
+
nextTree = nextTree.map(
|
|
9553
|
+
(node) => endorsementChildren.some((child) => child.id === node.id) ? { ...node, parentId: groupId, order: node.order + 1e-3 } : node
|
|
9554
|
+
);
|
|
9555
|
+
}
|
|
9556
|
+
return normalizeDocumentSourceTreePaths(nextTree);
|
|
9557
|
+
}
|
|
9414
9558
|
function compactNode(node, maxText = 700) {
|
|
9415
9559
|
return {
|
|
9416
9560
|
id: node.id,
|
|
@@ -9498,8 +9642,11 @@ Scope:
|
|
|
9498
9642
|
Rules:
|
|
9499
9643
|
- Use only node IDs from the provided list.
|
|
9500
9644
|
- Do not invent text, page numbers, source spans, limits, or policy facts.
|
|
9501
|
-
- You may relabel existing nodes and group adjacent top-level/page nodes from this batch when they are clearly one form,
|
|
9645
|
+
- You may relabel existing nodes and group adjacent top-level/page nodes from this batch only when they are clearly one continuous form, one declarations set, one schedule, or one clause family.
|
|
9646
|
+
- Group adjacent separately numbered endorsements under a single generic "Endorsements" page_group parent, with each individual endorsement preserved as its own child node.
|
|
9647
|
+
- Never create rollup titles such as "Endorsements 1-3 (...)" or merge multiple endorsements into one endorsement node.
|
|
9502
9648
|
- Add concise, human-readable titles to generic text, table, row, and cell nodes when the text makes their role clear.
|
|
9649
|
+
- Keep organizer titles terse. Use the printed heading or a compact canonical title such as "Declarations", "Policy Form", "Definitions", or "Endorsement No. 3"; do not add parenthetical summaries.
|
|
9503
9650
|
- Groups must list existing childNodeIds only.
|
|
9504
9651
|
- Keep descriptions short and useful for search.
|
|
9505
9652
|
- Prefer the document's own form titles, endorsement titles, schedules, declarations headings, and page order over keyword-only guessing.
|
|
@@ -9549,17 +9696,20 @@ function applyOrganization(sourceTree, organization) {
|
|
|
9549
9696
|
return {
|
|
9550
9697
|
...node,
|
|
9551
9698
|
kind: label.kind ?? node.kind,
|
|
9552
|
-
title:
|
|
9699
|
+
title: simplifyOrganizerTitle(label.title, node.title, label.kind ?? node.kind),
|
|
9553
9700
|
description: cleanText(label.description, node.description)
|
|
9554
9701
|
};
|
|
9555
9702
|
});
|
|
9556
9703
|
for (const group of organization.groups) {
|
|
9557
9704
|
const children = group.childNodeIds.map((id2) => byId.get(id2)).filter((node2) => Boolean(node2));
|
|
9558
9705
|
if (children.length === 0) continue;
|
|
9706
|
+
if (rejectsOrganizerGroup(group, children)) continue;
|
|
9559
9707
|
const parentId = children[0].parentId;
|
|
9560
9708
|
if (!children.every((child) => child.parentId === parentId)) continue;
|
|
9561
9709
|
const documentId = children[0].documentId;
|
|
9562
|
-
const
|
|
9710
|
+
const title = simplifyOrganizerTitle(group.title, group.title, group.kind);
|
|
9711
|
+
const description = cleanText(group.description, title);
|
|
9712
|
+
const id = groupNodeId(documentId, { ...group, title });
|
|
9563
9713
|
if (byId.has(id)) continue;
|
|
9564
9714
|
const sourceSpanIds = [...new Set(children.flatMap((child) => child.sourceSpanIds))];
|
|
9565
9715
|
const pageStarts = children.map((child) => child.pageStart).filter((page) => typeof page === "number");
|
|
@@ -9570,8 +9720,8 @@ function applyOrganization(sourceTree, organization) {
|
|
|
9570
9720
|
documentId,
|
|
9571
9721
|
parentId,
|
|
9572
9722
|
kind: group.kind,
|
|
9573
|
-
title
|
|
9574
|
-
description
|
|
9723
|
+
title,
|
|
9724
|
+
description,
|
|
9575
9725
|
textExcerpt: children.map((child) => child.textExcerpt ?? child.description).filter(Boolean).join("\n\n").slice(0, 1600),
|
|
9576
9726
|
sourceSpanIds,
|
|
9577
9727
|
pageStart: pageStarts.length ? Math.min(...pageStarts) : void 0,
|
|
@@ -9589,7 +9739,7 @@ function applyOrganization(sourceTree, organization) {
|
|
|
9589
9739
|
];
|
|
9590
9740
|
byId.set(id, node);
|
|
9591
9741
|
}
|
|
9592
|
-
return normalizeDocumentSourceTreePaths(nextTree);
|
|
9742
|
+
return applyEndorsementGrouping(normalizeDocumentSourceTreePaths(nextTree));
|
|
9593
9743
|
}
|
|
9594
9744
|
function sourceTreeToOutline(sourceTree) {
|
|
9595
9745
|
const byParent = /* @__PURE__ */ new Map();
|
|
@@ -9808,6 +9958,7 @@ async function runSourceTreeExtraction(params) {
|
|
|
9808
9958
|
} catch (error) {
|
|
9809
9959
|
warnings.push(`Operational profile model pass failed; deterministic profile used (${error instanceof Error ? error.message : String(error)})`);
|
|
9810
9960
|
}
|
|
9961
|
+
sourceTree = applyEndorsementGrouping(sourceTree);
|
|
9811
9962
|
const document = materializeDocument({
|
|
9812
9963
|
id: params.id,
|
|
9813
9964
|
sourceTree,
|