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