@agent-scope/site 1.19.0 → 1.20.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/dist/index.cjs +190 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +190 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -71,7 +71,7 @@ function slugify(name) {
|
|
|
71
71
|
function renderDOMTree(node, depth = 0) {
|
|
72
72
|
const indent = " ".repeat(depth);
|
|
73
73
|
const attrsHtml = Object.entries(node.attrs).map(([k, v]) => {
|
|
74
|
-
const display = v.length > 60 ? v.slice(0, 57)
|
|
74
|
+
const display = v.length > 60 ? `${v.slice(0, 57)}\u2026` : v;
|
|
75
75
|
return ` <span class="dom-attr-name">${escapeHtml(k)}</span>=<span class="dom-attr-value">"${escapeHtml(display)}"</span>`;
|
|
76
76
|
}).join("");
|
|
77
77
|
const nodeIdAttr = node.nodeId !== void 0 ? ` data-node-id="${node.nodeId}"` : "";
|
|
@@ -519,6 +519,58 @@ details.dom-node > summary::-webkit-details-marker { display: none; }
|
|
|
519
519
|
.content-body { padding: 20px 16px; }
|
|
520
520
|
.analysis-grid { grid-template-columns: 1fr; }
|
|
521
521
|
.composition-lists { grid-template-columns: 1fr; }
|
|
522
|
+
}
|
|
523
|
+
/* Collection section headers in sidebar */
|
|
524
|
+
.sidebar-collection-header {
|
|
525
|
+
font-size: 10px;
|
|
526
|
+
font-weight: 700;
|
|
527
|
+
letter-spacing: 0.08em;
|
|
528
|
+
text-transform: uppercase;
|
|
529
|
+
color: var(--color-muted);
|
|
530
|
+
padding: 12px 16px 4px;
|
|
531
|
+
margin-top: 4px;
|
|
532
|
+
border-top: 1px solid var(--color-border);
|
|
533
|
+
}
|
|
534
|
+
.sidebar-collection-header:first-child {
|
|
535
|
+
margin-top: 0;
|
|
536
|
+
border-top: none;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/* Collection section headers on index page */
|
|
540
|
+
.collection-section {
|
|
541
|
+
margin-bottom: 40px;
|
|
542
|
+
}
|
|
543
|
+
.collection-section-header {
|
|
544
|
+
margin-bottom: 16px;
|
|
545
|
+
padding-bottom: 10px;
|
|
546
|
+
border-bottom: 2px solid var(--color-border);
|
|
547
|
+
}
|
|
548
|
+
.collection-section-header h2 {
|
|
549
|
+
font-size: 18px;
|
|
550
|
+
font-weight: 600;
|
|
551
|
+
margin: 0 0 4px;
|
|
552
|
+
color: var(--color-text);
|
|
553
|
+
}
|
|
554
|
+
.collection-section-header p {
|
|
555
|
+
font-size: 13px;
|
|
556
|
+
color: var(--color-muted);
|
|
557
|
+
margin: 0;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/* Internal component badge */
|
|
561
|
+
.badge-internal {
|
|
562
|
+
display: inline-flex;
|
|
563
|
+
align-items: center;
|
|
564
|
+
padding: 1px 6px;
|
|
565
|
+
border-radius: 999px;
|
|
566
|
+
font-size: 10px;
|
|
567
|
+
font-weight: 500;
|
|
568
|
+
border: 1px solid #d1d5db;
|
|
569
|
+
color: #9ca3af;
|
|
570
|
+
background: #f3f4f6;
|
|
571
|
+
margin-left: 4px;
|
|
572
|
+
vertical-align: middle;
|
|
573
|
+
line-height: 1.4;
|
|
522
574
|
}`;
|
|
523
575
|
return `<style>
|
|
524
576
|
${css}
|
|
@@ -526,14 +578,54 @@ ${css}
|
|
|
526
578
|
}
|
|
527
579
|
|
|
528
580
|
// src/templates/layout.ts
|
|
529
|
-
function sidebarLinks(
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
581
|
+
function sidebarLinks(data, currentSlug) {
|
|
582
|
+
const { components } = data.manifest;
|
|
583
|
+
const collections = data.manifest.collections ?? [];
|
|
584
|
+
const basePath = data.options.basePath;
|
|
585
|
+
const visibleEntries = Object.entries(components).filter(([, c]) => !c.internal);
|
|
586
|
+
const collectionMap = /* @__PURE__ */ new Map();
|
|
587
|
+
for (const col of collections) {
|
|
588
|
+
collectionMap.set(col.name, []);
|
|
589
|
+
}
|
|
590
|
+
const ungrouped = [];
|
|
591
|
+
for (const [name, component] of visibleEntries) {
|
|
592
|
+
if (component.collection) {
|
|
593
|
+
if (!collectionMap.has(component.collection)) {
|
|
594
|
+
collectionMap.set(component.collection, []);
|
|
595
|
+
}
|
|
596
|
+
collectionMap.get(component.collection)?.push(name);
|
|
597
|
+
} else {
|
|
598
|
+
ungrouped.push(name);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
const hasAnyCollections = collectionMap.size > 0 || ungrouped.length < visibleEntries.length;
|
|
602
|
+
function renderLinks(names) {
|
|
603
|
+
return names.sort().map((name) => {
|
|
604
|
+
const slug = slugify(name);
|
|
605
|
+
const isActive = slug === currentSlug;
|
|
606
|
+
return `<a href="${basePath}${slug}.html" class="${isActive ? "active" : ""}">${escapeHtml(name)}</a>`;
|
|
607
|
+
}).join("\n");
|
|
608
|
+
}
|
|
609
|
+
if (!hasAnyCollections) {
|
|
610
|
+
const links = renderLinks(visibleEntries.map(([name]) => name));
|
|
611
|
+
return `<div class="sidebar-heading">Components</div>
|
|
536
612
|
${links}`;
|
|
613
|
+
}
|
|
614
|
+
const sections = [];
|
|
615
|
+
for (const [colName, names] of collectionMap) {
|
|
616
|
+
if (names.length === 0) continue;
|
|
617
|
+
sections.push(
|
|
618
|
+
`<div class="sidebar-collection-header">${escapeHtml(colName)}</div>
|
|
619
|
+
${renderLinks(names)}`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
if (ungrouped.length > 0) {
|
|
623
|
+
sections.push(
|
|
624
|
+
`<div class="sidebar-collection-header">Ungrouped</div>
|
|
625
|
+
${renderLinks(ungrouped)}`
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
return sections.join("\n");
|
|
537
629
|
}
|
|
538
630
|
function htmlShell(options) {
|
|
539
631
|
const { title, body, sidebar, onThisPage, basePath } = options;
|
|
@@ -896,9 +988,11 @@ function renderComposition(name, data) {
|
|
|
896
988
|
if (items.length === 0) {
|
|
897
989
|
return `<div class="comp-list"><h3>${escapeHtml(title)}</h3><p style="color:var(--color-muted);font-size:12px">None</p></div>`;
|
|
898
990
|
}
|
|
899
|
-
const liItems = items.map(
|
|
900
|
-
|
|
901
|
-
|
|
991
|
+
const liItems = items.map((n) => {
|
|
992
|
+
const compData = data.manifest.components[n];
|
|
993
|
+
const internalBadge = compData?.internal === true ? `<span class="badge-internal">internal</span>` : "";
|
|
994
|
+
return `<li><a href="${data.options.basePath}${slugify(n)}.html">${escapeHtml(n)}</a>${internalBadge}</li>`;
|
|
995
|
+
}).join("");
|
|
902
996
|
return `<div class="comp-list"><h3>${escapeHtml(title)}</h3><ul>${liItems}</ul></div>`;
|
|
903
997
|
}
|
|
904
998
|
return sectionWrap(
|
|
@@ -952,8 +1046,7 @@ function renderComponentDetail(name, data) {
|
|
|
952
1046
|
const id = s.toLowerCase().replace(/\s+/g, "-");
|
|
953
1047
|
return `<a href="#${id}">${escapeHtml(s)}</a>`;
|
|
954
1048
|
}).join("\n");
|
|
955
|
-
const
|
|
956
|
-
const sidebar = sidebarLinks(componentNames, slug, data.options.basePath);
|
|
1049
|
+
const sidebar = sidebarLinks(data, slug);
|
|
957
1050
|
return htmlShell({
|
|
958
1051
|
title: `${name} \u2014 ${data.options.title}`,
|
|
959
1052
|
body,
|
|
@@ -964,17 +1057,45 @@ function renderComponentDetail(name, data) {
|
|
|
964
1057
|
}
|
|
965
1058
|
|
|
966
1059
|
// src/templates/component-index.ts
|
|
1060
|
+
function renderCard(name, data) {
|
|
1061
|
+
const component = data.manifest.components[name];
|
|
1062
|
+
if (!component) return "";
|
|
1063
|
+
const slug = slugify(name);
|
|
1064
|
+
const render = data.renders.get(name);
|
|
1065
|
+
const propCount = Object.keys(component.props).length;
|
|
1066
|
+
const hookCount = component.detectedHooks.length;
|
|
1067
|
+
const previewHtml = render?.screenshot ? `<img class="scope-screenshot" src="data:image/png;base64,${render.screenshot}" alt="${escapeHtml(name)}" />` : `<span class="no-preview">No preview</span>`;
|
|
1068
|
+
return `<a class="component-card" href="${data.options.basePath}${slug}.html" data-name="${escapeHtml(name.toLowerCase())}">
|
|
1069
|
+
<div class="card-preview">${previewHtml}</div>
|
|
1070
|
+
<div class="card-body">
|
|
1071
|
+
<div class="card-name">${escapeHtml(name)}</div>
|
|
1072
|
+
<div class="card-meta">
|
|
1073
|
+
<span>${propCount} props</span>
|
|
1074
|
+
<span class="badge ${component.complexityClass}" style="font-size:10px">${escapeHtml(component.complexityClass)}</span>
|
|
1075
|
+
${hookCount > 0 ? `<span>${hookCount} hooks</span>` : ""}
|
|
1076
|
+
</div>
|
|
1077
|
+
</div>
|
|
1078
|
+
</a>`;
|
|
1079
|
+
}
|
|
967
1080
|
function renderComponentIndex(data) {
|
|
968
|
-
const
|
|
969
|
-
const
|
|
970
|
-
const
|
|
971
|
-
const
|
|
972
|
-
const
|
|
1081
|
+
const allComponents = Object.entries(data.manifest.components);
|
|
1082
|
+
const collections = data.manifest.collections ?? [];
|
|
1083
|
+
const visibleComponents = allComponents.filter(([, c]) => !c.internal);
|
|
1084
|
+
const totalCount = allComponents.length;
|
|
1085
|
+
const visibleCount = visibleComponents.length;
|
|
1086
|
+
const collectionCount = collections.length;
|
|
1087
|
+
const simpleCount = visibleComponents.filter(([, c]) => c.complexityClass === "simple").length;
|
|
1088
|
+
const complexCount = visibleComponents.filter(([, c]) => c.complexityClass === "complex").length;
|
|
1089
|
+
const memoizedCount = visibleComponents.filter(([, c]) => c.memoized).length;
|
|
973
1090
|
const statsGrid = `<div class="stats-grid">
|
|
974
1091
|
<div class="stat-card">
|
|
975
1092
|
<div class="stat-label">Total Components</div>
|
|
976
1093
|
<div class="stat-value">${totalCount}</div>
|
|
977
1094
|
</div>
|
|
1095
|
+
<div class="stat-card">
|
|
1096
|
+
<div class="stat-label">Collections</div>
|
|
1097
|
+
<div class="stat-value">${collectionCount}</div>
|
|
1098
|
+
</div>
|
|
978
1099
|
<div class="stat-card">
|
|
979
1100
|
<div class="stat-label">Simple</div>
|
|
980
1101
|
<div class="stat-value">${simpleCount}</div>
|
|
@@ -988,25 +1109,54 @@ function renderComponentIndex(data) {
|
|
|
988
1109
|
<div class="stat-value">${memoizedCount}</div>
|
|
989
1110
|
</div>
|
|
990
1111
|
</div>`;
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1112
|
+
const collectionMap = /* @__PURE__ */ new Map();
|
|
1113
|
+
for (const col of collections) {
|
|
1114
|
+
collectionMap.set(col.name, []);
|
|
1115
|
+
}
|
|
1116
|
+
const ungrouped = [];
|
|
1117
|
+
for (const [name, component] of visibleComponents) {
|
|
1118
|
+
if (component.collection) {
|
|
1119
|
+
if (!collectionMap.has(component.collection)) {
|
|
1120
|
+
collectionMap.set(component.collection, []);
|
|
1121
|
+
}
|
|
1122
|
+
collectionMap.get(component.collection)?.push(name);
|
|
1123
|
+
} else {
|
|
1124
|
+
ungrouped.push(name);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
const hasCollections = collectionCount > 0 || visibleComponents.some(([, c]) => c.collection);
|
|
1128
|
+
let cardSections;
|
|
1129
|
+
if (!hasCollections) {
|
|
1130
|
+
const cards = visibleComponents.sort(([a], [b]) => a.localeCompare(b)).map(([name]) => renderCard(name, data)).join("\n");
|
|
1131
|
+
cardSections = `<div class="component-grid" id="component-grid">${cards}</div>`;
|
|
1132
|
+
} else {
|
|
1133
|
+
const sectionParts = [];
|
|
1134
|
+
for (const col of collections) {
|
|
1135
|
+
const names = collectionMap.get(col.name) ?? [];
|
|
1136
|
+
if (names.length === 0) continue;
|
|
1137
|
+
const collectionConfig = collections.find((c) => c.name === col.name);
|
|
1138
|
+
const descHtml = collectionConfig?.description ? `<p>${escapeHtml(collectionConfig.description)}</p>` : "";
|
|
1139
|
+
const cards = names.sort().map((name) => renderCard(name, data)).join("\n");
|
|
1140
|
+
sectionParts.push(`<div class="collection-section">
|
|
1141
|
+
<div class="collection-section-header">
|
|
1142
|
+
<h2>${escapeHtml(col.name)}</h2>
|
|
1143
|
+
${descHtml}
|
|
1006
1144
|
</div>
|
|
1007
|
-
</
|
|
1008
|
-
|
|
1009
|
-
|
|
1145
|
+
<div class="component-grid">${cards}</div>
|
|
1146
|
+
</div>`);
|
|
1147
|
+
}
|
|
1148
|
+
if (ungrouped.length > 0) {
|
|
1149
|
+
const cards = ungrouped.sort().map((name) => renderCard(name, data)).join("\n");
|
|
1150
|
+
sectionParts.push(`<div class="collection-section">
|
|
1151
|
+
<div class="collection-section-header">
|
|
1152
|
+
<h2>Ungrouped</h2>
|
|
1153
|
+
<p>Components not assigned to a collection.</p>
|
|
1154
|
+
</div>
|
|
1155
|
+
<div class="component-grid">${cards}</div>
|
|
1156
|
+
</div>`);
|
|
1157
|
+
}
|
|
1158
|
+
cardSections = `<div id="component-grid">${sectionParts.join("\n")}</div>`;
|
|
1159
|
+
}
|
|
1010
1160
|
const filterScript = `<script>
|
|
1011
1161
|
(function () {
|
|
1012
1162
|
var grid = document.getElementById('component-grid');
|
|
@@ -1028,12 +1178,11 @@ function renderComponentIndex(data) {
|
|
|
1028
1178
|
</script>`;
|
|
1029
1179
|
const header = `<div class="index-header">
|
|
1030
1180
|
<h1>${escapeHtml(data.options.title)}</h1>
|
|
1031
|
-
<p>${
|
|
1181
|
+
<p>${visibleCount} component${visibleCount === 1 ? "" : "s"} analysed</p>
|
|
1032
1182
|
<input class="search-box" type="search" id="index-search" placeholder="Filter components\u2026" style="margin-top:12px" />
|
|
1033
1183
|
</div>`;
|
|
1034
|
-
const body = `${header}${statsGrid}${
|
|
1035
|
-
const
|
|
1036
|
-
const sidebar = sidebarLinks(componentNames, null, data.options.basePath);
|
|
1184
|
+
const body = `${header}${statsGrid}${cardSections}${filterScript}`;
|
|
1185
|
+
const sidebar = sidebarLinks(data, null);
|
|
1037
1186
|
const onThisPage = `<a href="#top">Overview</a>
|
|
1038
1187
|
<a href="#component-grid">Components</a>`;
|
|
1039
1188
|
return htmlShell({
|
|
@@ -1143,8 +1292,7 @@ function renderDashboard(data) {
|
|
|
1143
1292
|
<p style="color:var(--color-muted);font-size:14px">Overview of all ${totalCount} analysed components.</p>
|
|
1144
1293
|
</div>`;
|
|
1145
1294
|
const body = `${header}${statsGrid}${complexitySection}${topPropsSection}${complianceSection}`;
|
|
1146
|
-
const
|
|
1147
|
-
const sidebar = sidebarLinks(componentNames, null, data.options.basePath);
|
|
1295
|
+
const sidebar = sidebarLinks(data, null);
|
|
1148
1296
|
const onThisPage = `<a href="#top">Overview</a>
|
|
1149
1297
|
<a href="#complexity">Complexity</a>
|
|
1150
1298
|
<a href="#top-props">Top by Props</a>
|