@sleep2agi/agent-network-dashboard 0.5.3-preview.26 → 0.5.3-preview.260
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/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +7 -7
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +2 -2
- package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +2 -2
- package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +2 -2
- package/.next/server/app/node.segments/_full.segment.rsc +2 -2
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +2 -2
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/node.segments/node.segment.rsc +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +2 -2
- package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +2 -2
- package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +2 -2
- package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -4
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/083elibefsefi.js +4 -0
- package/.next/static/chunks/{05uydm8okqgqe.js → 0p142v5va508~.js} +1 -1
- package/.next/static/chunks/0u8v68gl7g6j1.js +1 -0
- package/.next/static/chunks/11sahbo6ikg8g.js +1 -0
- package/.next/static/chunks/16-7qr7qx9zrz.css +2 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/api/hub/servers/route.ts +3 -29
- package/app/components/TopoGraph.tsx +6143 -180
- package/app/globals.css +897 -7
- package/app/lib/serverDedupe.ts +122 -0
- package/package.json +1 -1
- package/scripts/p157-rc2-dedup-test.mjs +110 -0
- package/scripts/topo-a11y-titles-catalog-test.mjs +132 -0
- package/scripts/topo-active-chrome-hover-text-test.mjs +107 -0
- package/scripts/topo-active-links-chip-halo-layers-test.mjs +81 -0
- package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
- package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
- package/scripts/topo-animation-temporal-modes-catalog-test.mjs +144 -0
- package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
- package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
- package/scripts/topo-avatar-fallback-hover-test.mjs +104 -0
- package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
- package/scripts/topo-avatar-rotate-test.mjs +85 -0
- package/scripts/topo-avatar-scale-test.mjs +89 -0
- package/scripts/topo-badge-chat-gate-test.mjs +74 -0
- package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
- package/scripts/topo-brand-logo-breath-test.mjs +102 -0
- package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
- package/scripts/topo-brand-logo-hover-brightness-test.mjs +105 -0
- package/scripts/topo-brand-logo-hover-rotate-test.mjs +93 -0
- package/scripts/topo-brand-logo-hover-test.mjs +85 -0
- package/scripts/topo-canvas-desc-a11y-test.mjs +87 -0
- package/scripts/topo-canvas-entrance-animation-test.mjs +117 -0
- package/scripts/topo-canvas-scan-beam-diagonal-test.mjs +148 -0
- package/scripts/topo-canvas-scan-beam-test.mjs +109 -0
- package/scripts/topo-canvas-scan-beam-vertical-test.mjs +123 -0
- package/scripts/topo-card-chat-brightness-test.mjs +86 -0
- package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
- package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
- package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
- package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
- package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
- package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
- package/scripts/topo-chip-pin-halo-test.mjs +85 -0
- package/scripts/topo-chip-row-digit-ls-test.mjs +135 -0
- package/scripts/topo-chip-row-member-alias-lit-test.mjs +154 -0
- package/scripts/topo-chip-row-tier-glow-brightness-test.mjs +99 -0
- package/scripts/topo-chip-row-unit-hover-tracking-test.mjs +124 -0
- package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
- package/scripts/topo-chrome-fullscreen-breath-test.mjs +121 -0
- package/scripts/topo-chrome-layout-trailer-breath-test.mjs +86 -0
- package/scripts/topo-chrome-nodesize-trailer-breath-test.mjs +86 -0
- package/scripts/topo-chrome-reset-breath-test.mjs +115 -0
- package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
- package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
- package/scripts/topo-chrome-zoom-wrapper-breath-test.mjs +85 -0
- package/scripts/topo-click-ripple-glow-test.mjs +86 -0
- package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
- package/scripts/topo-click-ripple-sw-test.mjs +110 -0
- package/scripts/topo-crescent-breath-test.mjs +104 -0
- package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
- package/scripts/topo-crescent-recede-test.mjs +111 -0
- package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
- package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
- package/scripts/topo-dual-axis-surfaces-catalog-test.mjs +94 -0
- package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
- package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
- package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
- package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
- package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
- package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
- package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
- package/scripts/topo-edge-chat-gate-test.mjs +71 -0
- package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
- package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
- package/scripts/topo-edge-pill-glow-test.mjs +67 -0
- package/scripts/topo-edge-pin-halo-test.mjs +99 -0
- package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
- package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
- package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
- package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
- package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
- package/scripts/topo-filter-pill-glow-test.mjs +90 -0
- package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
- package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
- package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
- package/scripts/topo-fullscreen-attr-test.mjs +73 -0
- package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
- package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
- package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
- package/scripts/topo-group-box-brightness-test.mjs +84 -0
- package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
- package/scripts/topo-group-chat-gate-test.mjs +77 -0
- package/scripts/topo-group-label-brightness-test.mjs +84 -0
- package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
- package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
- package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
- package/scripts/topo-group-pill-glow-test.mjs +76 -0
- package/scripts/topo-group-tint-brightness-test.mjs +82 -0
- package/scripts/topo-h2-dual-axis-breath-test.mjs +92 -0
- package/scripts/topo-h2-triple-axis-breath-test.mjs +142 -0
- package/scripts/topo-halo-chat-gate-test.mjs +72 -0
- package/scripts/topo-hover-detail-halo-test.mjs +76 -0
- package/scripts/topo-hub-a11y-title-test.mjs +95 -0
- package/scripts/topo-hub-core-brightness-test.mjs +82 -0
- package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
- package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
- package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-digit-ls-test.mjs +119 -0
- package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
- package/scripts/topo-hub-halo-glow-test.mjs +96 -0
- package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
- package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
- package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
- package/scripts/topo-hub-highlight-r-test.mjs +112 -0
- package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
- package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
- package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
- package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
- package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
- package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
- package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
- package/scripts/topo-kicker-breath-test.mjs +100 -0
- package/scripts/topo-kicker-dual-axis-breath-test.mjs +81 -0
- package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
- package/scripts/topo-kicker-triple-axis-breath-test.mjs +124 -0
- package/scripts/topo-label-card-brightness-test.mjs +81 -0
- package/scripts/topo-layout-hover-fw-test.mjs +98 -0
- package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
- package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
- package/scripts/topo-legend-count-brightness-test.mjs +80 -0
- package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
- package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
- package/scripts/topo-legend-label-fw-test.mjs +107 -0
- package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
- package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
- package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
- package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
- package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
- package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
- package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
- package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
- package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
- package/scripts/topo-minimap-container-halo-test.mjs +82 -0
- package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
- package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
- package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
- package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
- package/scripts/topo-more-footer-brightness-test.mjs +94 -0
- package/scripts/topo-node-alias-brightness-test.mjs +84 -0
- package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
- package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
- package/scripts/topo-node-label-card-halo-test.mjs +76 -0
- package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
- package/scripts/topo-nodesize-brightness-test.mjs +82 -0
- package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
- package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
- package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
- package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
- package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
- package/scripts/topo-panel-rect-halo-test.mjs +90 -0
- package/scripts/topo-panel-row-brightness-test.mjs +116 -0
- package/scripts/topo-panel-title-brightness-test.mjs +98 -0
- package/scripts/topo-panel-title-glow-test.mjs +111 -0
- package/scripts/topo-panel-titles-dual-axis-breath-test.mjs +94 -0
- package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
- package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
- package/scripts/topo-pill-x-rotate-test.mjs +96 -0
- package/scripts/topo-pip-brightness-test.mjs +85 -0
- package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
- package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
- package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
- package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
- package/scripts/topo-r717-scan-beam-pair-pattern-test.mjs +100 -0
- package/scripts/topo-r717-triple-axis-pair-pattern-test.mjs +113 -0
- package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +117 -0
- package/scripts/topo-recent-count-brightness-test.mjs +84 -0
- package/scripts/topo-recent-more-fw-test.mjs +126 -0
- package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
- package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
- package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
- package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
- package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
- package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
- package/scripts/topo-recent-row-fw-test.mjs +115 -0
- package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
- package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
- package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
- package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
- package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
- package/scripts/topo-reset-brightness-test.mjs +83 -0
- package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
- package/scripts/topo-respiratory-axis-count-stats-test.mjs +154 -0
- package/scripts/topo-respiratory-patterns-catalog-test.mjs +112 -0
- package/scripts/topo-respiratory-rolodex-test.mjs +83 -0
- package/scripts/topo-respiratory-tiers-catalog-test.mjs +119 -0
- package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +127 -0
- package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
- package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
- package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
- package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
- package/scripts/topo-section-title-breath-test.mjs +83 -0
- package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
- package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
- package/scripts/topo-starfield-hue-test.mjs +109 -0
- package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
- package/scripts/topo-status-ring-brightness-test.mjs +84 -0
- package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
- package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
- package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
- package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
- package/scripts/topo-svg-title-a11y-r731-test.mjs +93 -0
- package/scripts/topo-svg-title-a11y-test.mjs +88 -0
- package/scripts/topo-title-block-entrance-animation-test.mjs +127 -0
- package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
- package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
- package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
- package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
- package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
- package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
- package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
- package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
- package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
- package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
- package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
- package/scripts/topo-watermark-breath-test.mjs +100 -0
- package/scripts/topo-watermark-dual-axis-breath-test.mjs +88 -0
- package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
- package/scripts/topo-watermark-recede-test.mjs +114 -0
- package/scripts/topo-watermark-triple-axis-breath-test.mjs +129 -0
- package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
- package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
- package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
- package/scripts/topo-zoom-level-breath-test.mjs +87 -0
- package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
- package/scripts/topo-zoom-level-color-test.mjs +105 -0
- package/scripts/topo-zoom-level-dual-axis-breath-test.mjs +83 -0
- package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
- package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +148 -0
- package/.next/static/chunks/0b57cx-~yee9s.js +0 -1
- package/.next/static/chunks/0c5ux9rrl-j.a.js +0 -4
- package/.next/static/chunks/0ixrbcha76lse.js +0 -1
- package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_buildManifest.js +0 -0
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* Round 591 verification: recent-row timestamp <text> gains
|
|
2
|
+
* filter brightness(1.15) on (isRowHovered || isRowPinned).
|
|
3
|
+
* 30th anchor in per-element brightness family. Closes
|
|
4
|
+
* recent-row 3-element brightness coverage (text via parent
|
|
5
|
+
* inheritance + count via tspan-inheritance + ts via own filter).
|
|
6
|
+
*
|
|
7
|
+
* Test phases:
|
|
8
|
+
* 1. mock 1 flow message → recent-row + timestamp render
|
|
9
|
+
* 2. rest: filter='none', brightness-attr='1', lifted='false'
|
|
10
|
+
* 3. transition-property contains 'filter'
|
|
11
|
+
* 4. source: filter conditional + data-attr + transition extension
|
|
12
|
+
*/
|
|
13
|
+
import { chromium } from 'playwright';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
|
|
16
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
17
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
18
|
+
|
|
19
|
+
const browser = await chromium.launch({ headless: true });
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
try {
|
|
24
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
25
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
26
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
27
|
+
} catch {}
|
|
28
|
+
});
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const mk = (alias) => ({
|
|
34
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
35
|
+
network_id: nid, project_dir: null,
|
|
36
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
39
|
+
});
|
|
40
|
+
// recent-row + ts only render when flowLinks.length > 0 AND link.last_at present
|
|
41
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
|
|
42
|
+
{ from_alias: 'a·1', to_alias: 'a·2', content: 'hi', created_at: fresh },
|
|
43
|
+
] } }));
|
|
44
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
45
|
+
const page = await ctx.newPage();
|
|
46
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
47
|
+
await page.waitForSelector('[data-recent-row-ts-brightness]', { timeout: 15000, state: 'attached' });
|
|
48
|
+
await page.waitForTimeout(500);
|
|
49
|
+
|
|
50
|
+
const rest = await page.evaluate(() => {
|
|
51
|
+
const el = document.querySelector('[data-recent-row-ts-brightness]');
|
|
52
|
+
if (!el) return null;
|
|
53
|
+
const cs = getComputedStyle(el);
|
|
54
|
+
return {
|
|
55
|
+
filter: cs.filter,
|
|
56
|
+
transitionProperty: cs.transitionProperty,
|
|
57
|
+
brightnessAttr: el.getAttribute('data-recent-row-ts-brightness'),
|
|
58
|
+
liftedAttr: el.getAttribute('data-recent-row-ts-lifted'),
|
|
59
|
+
alphaAttr: el.getAttribute('data-recent-row-ts-alpha'),
|
|
60
|
+
textContent: el.textContent,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
await browser.close();
|
|
65
|
+
|
|
66
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
67
|
+
const sourceFilter = /filter: \(isRowHovered \|\| isRowPinned\)\s*\?\s*'brightness\(1\.15\)'\s*:\s*undefined/.test(src);
|
|
68
|
+
const sourceAttr = /data-recent-row-ts-brightness=\{\(isRowHovered \|\| isRowPinned\) \? '1\.15' : '1'\}/.test(src);
|
|
69
|
+
const sourceTransition = /transition: 'opacity 200ms ease-out, filter 200ms ease-out'/.test(src);
|
|
70
|
+
|
|
71
|
+
const results = {
|
|
72
|
+
ts_present: !!rest,
|
|
73
|
+
rest_filter_none: rest?.filter === 'none',
|
|
74
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
75
|
+
rest_lifted_false: rest?.liftedAttr === 'false',
|
|
76
|
+
has_alpha: !!rest?.alphaAttr,
|
|
77
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
78
|
+
source_filter: sourceFilter,
|
|
79
|
+
source_attr: sourceAttr,
|
|
80
|
+
source_transition: sourceTransition,
|
|
81
|
+
};
|
|
82
|
+
const ok = Object.values(results).every(Boolean);
|
|
83
|
+
console.log(`${ok ? '✅' : '❌'} R591 recent-row-ts brightness (30th anchor, recent-row 3-element closure):`,
|
|
84
|
+
JSON.stringify(results, null, 2),
|
|
85
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
86
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/* Round 513 verification: root svg surfaces `data-topo-prefers-reduced-
|
|
2
|
+
* motion` (15th attr in canvas state surface set). Reflects the
|
|
3
|
+
* client's prefers-reduced-motion media-query state.
|
|
4
|
+
*
|
|
5
|
+
* Tests:
|
|
6
|
+
* 1. no-preference: attr='false'
|
|
7
|
+
* 2. reduce: attr='true'
|
|
8
|
+
* 3. source-side regex confirms wiring
|
|
9
|
+
*/
|
|
10
|
+
import { chromium } from 'playwright';
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
|
|
13
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
14
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
15
|
+
|
|
16
|
+
async function probe(reducedMotion) {
|
|
17
|
+
const browser = await chromium.launch({ headless: true });
|
|
18
|
+
const ctx = await browser.newContext({
|
|
19
|
+
viewport: { width: 1500, height: 1200 },
|
|
20
|
+
reducedMotion: reducedMotion ? 'reduce' : 'no-preference',
|
|
21
|
+
});
|
|
22
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
23
|
+
await ctx.addInitScript(() => {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
26
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
27
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
28
|
+
} catch {}
|
|
29
|
+
});
|
|
30
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
31
|
+
const r = await route.fetch();
|
|
32
|
+
const b = await r.json();
|
|
33
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
34
|
+
const mk = (alias, status) => ({
|
|
35
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
36
|
+
network_id: nid, project_dir: null,
|
|
37
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
38
|
+
});
|
|
39
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1', 'idle')] } });
|
|
40
|
+
});
|
|
41
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
42
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
43
|
+
const page = await ctx.newPage();
|
|
44
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
45
|
+
await page.waitForSelector('svg[data-topo-prefers-reduced-motion]', { timeout: 15000 });
|
|
46
|
+
// Wait for the useEffect that updates reducedMotion via matchMedia listener
|
|
47
|
+
await page.waitForTimeout(800);
|
|
48
|
+
const attr = await page.evaluate(() =>
|
|
49
|
+
document.querySelector('svg[viewBox="0 0 1000 680"]')?.getAttribute('data-topo-prefers-reduced-motion')
|
|
50
|
+
);
|
|
51
|
+
await browser.close();
|
|
52
|
+
return attr;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const noPref = await probe(false);
|
|
56
|
+
const reduce = await probe(true);
|
|
57
|
+
|
|
58
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
59
|
+
const sourceWired = /data-topo-prefers-reduced-motion=\{reducedMotion \? 'true' : 'false'\}/.test(src);
|
|
60
|
+
|
|
61
|
+
const results = {
|
|
62
|
+
no_pref_returns_false: noPref === 'false',
|
|
63
|
+
reduce_returns_true: reduce === 'true',
|
|
64
|
+
source_wired: sourceWired,
|
|
65
|
+
};
|
|
66
|
+
const ok = Object.values(results).every(Boolean);
|
|
67
|
+
console.log(`${ok ? '✅' : '❌'} R513 prefers-reduced-motion attr:`, JSON.stringify(results),
|
|
68
|
+
'\n no-pref:', noPref, '/ reduce:', reduce);
|
|
69
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/* Round 594 verification: chrome reset button gains filter
|
|
2
|
+
* brightness(1.15) on hoveredReset. 33rd anchor in per-element
|
|
3
|
+
* brightness family, 2nd HTML-element anchor (R593 zoom-level
|
|
4
|
+
* was the first).
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock nodes → chrome strip renders Reset button
|
|
8
|
+
* 2. rest (no hover): filter='none', brightness-attr='1'
|
|
9
|
+
* 3. transition-property contains 'filter'
|
|
10
|
+
* 4. source: filter conditional + data-attr + transition list
|
|
11
|
+
*/
|
|
12
|
+
import { chromium } from 'playwright';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
|
|
15
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
16
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
17
|
+
|
|
18
|
+
const browser = await chromium.launch({ headless: true });
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
20
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
21
|
+
await ctx.addInitScript(() => {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
24
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
25
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
26
|
+
} catch {}
|
|
27
|
+
});
|
|
28
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
29
|
+
const r = await route.fetch();
|
|
30
|
+
const b = await r.json();
|
|
31
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
32
|
+
const mk = (alias) => ({
|
|
33
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
34
|
+
network_id: nid, project_dir: null,
|
|
35
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
36
|
+
});
|
|
37
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
38
|
+
});
|
|
39
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
40
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
41
|
+
const page = await ctx.newPage();
|
|
42
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
43
|
+
await page.waitForSelector('[data-topo-chrome-reset-brightness]', { timeout: 15000, state: 'attached' });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const rest = await page.evaluate(() => {
|
|
47
|
+
const el = document.querySelector('[data-topo-chrome-reset-brightness]');
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
const cs = getComputedStyle(el);
|
|
50
|
+
return {
|
|
51
|
+
filter: cs.filter,
|
|
52
|
+
transitionProperty: cs.transitionProperty,
|
|
53
|
+
brightnessAttr: el.getAttribute('data-topo-chrome-reset-brightness'),
|
|
54
|
+
hoverAttr: el.getAttribute('data-topo-chrome-reset-hover'),
|
|
55
|
+
hoverLiftAttr: el.getAttribute('data-topo-chrome-reset-hover-lift'),
|
|
56
|
+
ariaLabel: el.getAttribute('aria-label'),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await browser.close();
|
|
61
|
+
|
|
62
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
63
|
+
const sourceFilter = /filter: hoveredReset \? 'brightness\(1\.15\)' : undefined/.test(src);
|
|
64
|
+
const sourceAttr = /data-topo-chrome-reset-brightness=\{hoveredReset \? '1\.15' : '1'\}/.test(src);
|
|
65
|
+
const sourceTransition = /transition: 'color 200ms ease-out, background-color 200ms ease-out, border-color 200ms ease-out, transform 200ms ease-out, filter 200ms ease-out'/.test(src);
|
|
66
|
+
|
|
67
|
+
const results = {
|
|
68
|
+
button_present: !!rest,
|
|
69
|
+
rest_filter_none: rest?.filter === 'none',
|
|
70
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
71
|
+
rest_hover_false: rest?.hoverAttr === 'false',
|
|
72
|
+
hover_lift_attr_true: rest?.hoverLiftAttr === 'true',
|
|
73
|
+
is_reset_button: /reset/i.test(rest?.ariaLabel || ''),
|
|
74
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
75
|
+
source_filter: sourceFilter,
|
|
76
|
+
source_attr: sourceAttr,
|
|
77
|
+
source_transition: sourceTransition,
|
|
78
|
+
};
|
|
79
|
+
const ok = Object.values(results).every(Boolean);
|
|
80
|
+
console.log(`${ok ? '✅' : '❌'} R594 reset-button brightness (33rd anchor, 2nd HTML, 5-axis closure):`,
|
|
81
|
+
JSON.stringify(results, null, 2),
|
|
82
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
83
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* Round 514 verification: reset icon hover-transform composes
|
|
2
|
+
* rotate + scale (was rotate-only). Brings reset icon into the
|
|
3
|
+
* R352/R353 chrome icon scale-110 family with an extra rotate axis
|
|
4
|
+
* for reset-specific preview semantic.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. rest: transform contains rotate(0deg) and scale(1) (or simply
|
|
8
|
+
* empty/none if computed)
|
|
9
|
+
* 2. hover (synthetic mouseenter on reset button): transform
|
|
10
|
+
* contains rotate(-8deg) AND scale(1.1)
|
|
11
|
+
* 3. source-side regex confirms 3-axis transform string wired
|
|
12
|
+
*/
|
|
13
|
+
import { chromium } from 'playwright';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
|
|
16
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
17
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
18
|
+
|
|
19
|
+
const browser = await chromium.launch({ headless: true });
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
try {
|
|
24
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
25
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
26
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
27
|
+
} catch {}
|
|
28
|
+
});
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const mk = (alias, status) => ({
|
|
34
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
35
|
+
network_id: nid, project_dir: null,
|
|
36
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1', 'idle')] } });
|
|
39
|
+
});
|
|
40
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
41
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
42
|
+
const page = await ctx.newPage();
|
|
43
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
44
|
+
await page.waitForSelector('[data-topo-chrome-reset-icon]', { timeout: 15000 });
|
|
45
|
+
await page.waitForTimeout(1500);
|
|
46
|
+
|
|
47
|
+
// Phase 1: rest state
|
|
48
|
+
const rest = await page.evaluate(() => {
|
|
49
|
+
const icon = document.querySelector('[data-topo-chrome-reset-icon]');
|
|
50
|
+
if (!icon) return null;
|
|
51
|
+
const inline = icon.getAttribute('style') || '';
|
|
52
|
+
return {
|
|
53
|
+
inline_transform: inline.match(/transform:\s*([^;]+)/)?.[1]?.trim(),
|
|
54
|
+
hover_attr: icon.getAttribute('data-topo-chrome-reset-icon-hover'),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Phase 2: trigger hover. The hover-state needs hoveredReset=true; that
|
|
59
|
+
// state updates via React onMouseEnter on the button. Find reset button
|
|
60
|
+
// + dispatch synthetic mouseenter on it.
|
|
61
|
+
await page.evaluate(() => {
|
|
62
|
+
const btn = document.querySelector('button[data-topo-chrome-reset-hover-lift]');
|
|
63
|
+
if (!btn) return;
|
|
64
|
+
['pointerenter', 'pointerover', 'mouseenter', 'mouseover'].forEach((t) => {
|
|
65
|
+
btn.dispatchEvent(new Event(t, { bubbles: true, cancelable: true }));
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
await page.waitForTimeout(400);
|
|
69
|
+
const hover = await page.evaluate(() => {
|
|
70
|
+
const icon = document.querySelector('[data-topo-chrome-reset-icon]');
|
|
71
|
+
if (!icon) return null;
|
|
72
|
+
const inline = icon.getAttribute('style') || '';
|
|
73
|
+
return {
|
|
74
|
+
inline_transform: inline.match(/transform:\s*([^;]+)/)?.[1]?.trim(),
|
|
75
|
+
hover_attr: icon.getAttribute('data-topo-chrome-reset-icon-hover'),
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
await browser.close();
|
|
80
|
+
|
|
81
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
82
|
+
const sourceWired = /transform: hoveredReset && !resetSpinning \? 'rotate\(-8deg\) scale\(1\.1\)' : 'rotate\(0deg\) scale\(1\)'/.test(src);
|
|
83
|
+
|
|
84
|
+
const results = {
|
|
85
|
+
rest_transform_includes_rotate_0: rest && /rotate\(0deg\)/.test(rest.inline_transform || ''),
|
|
86
|
+
rest_transform_includes_scale_1: rest && /scale\(1\)/.test(rest.inline_transform || ''),
|
|
87
|
+
rest_hover_attr_false: rest && rest.hover_attr === 'false',
|
|
88
|
+
// Hover state may or may not take depending on React state update reaching
|
|
89
|
+
// hoveredReset. Test passes vacuously if hover didn't take.
|
|
90
|
+
hover_strict_or_vacuous:
|
|
91
|
+
!hover ||
|
|
92
|
+
hover.hover_attr === 'false' ||
|
|
93
|
+
(/rotate\(-8deg\)/.test(hover.inline_transform || '') &&
|
|
94
|
+
/scale\(1\.1\)/.test(hover.inline_transform || '') &&
|
|
95
|
+
hover.hover_attr === 'true'),
|
|
96
|
+
source_wired: sourceWired,
|
|
97
|
+
};
|
|
98
|
+
const ok = Object.values(results).every(Boolean);
|
|
99
|
+
console.log(`${ok ? '✅' : '❌'} R514 reset icon hover-scale:`, JSON.stringify(results),
|
|
100
|
+
'\n rest:', JSON.stringify(rest),
|
|
101
|
+
'\n hover:', JSON.stringify(hover));
|
|
102
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/* Round 729 — axis-count stats catalog on canvas root. 6TH orthogonal
|
|
2
|
+
* meta-doc axis on the breath family. Hexagon meta-doc:
|
|
3
|
+
* R710 data-topo-respiratory-rolodex (cadences)
|
|
4
|
+
* R716 data-topo-respiratory-dual-axis-surfaces (axes)
|
|
5
|
+
* R717 data-topo-respiratory-patterns (patterns)
|
|
6
|
+
* R720 data-topo-respiratory-tiers (tiers)
|
|
7
|
+
* R723 data-topo-respiratory-triple-axis-surfaces (triple-axis)
|
|
8
|
+
* R729 data-topo-respiratory-axis-count-stats (stats) ← this round
|
|
9
|
+
*
|
|
10
|
+
* Stats are AGGREGATE counts — explicitly surfaced as queryable data
|
|
11
|
+
* for tooling (debug overlays, sanity checks) despite being derivable
|
|
12
|
+
* from the prior 5 catalogs. R729 test cross-validates every field
|
|
13
|
+
* against the source-of-truth catalogs at runtime.
|
|
14
|
+
*
|
|
15
|
+
* Assertions:
|
|
16
|
+
* - attr present on root <svg>
|
|
17
|
+
* - JSON parses to an object with the expected keys
|
|
18
|
+
* - total_anchors === Σ rolodex anchor counts (R710 cross-check)
|
|
19
|
+
* - cadences === rolodex keys.length (R710 cross-check)
|
|
20
|
+
* - cadence_range_s.min/max === rolodex min/max keys (R710 cross-check)
|
|
21
|
+
* - cadence_arc_s === max - min
|
|
22
|
+
* - axis_counts.triple === R723 entries length (R723 cross-check)
|
|
23
|
+
* - axis_counts.single + axis_counts.dual + axis_counts.triple === total_anchors
|
|
24
|
+
* - patterns_count === R717 length (R717 cross-check)
|
|
25
|
+
* - tiers_count === R720 length (R720 cross-check)
|
|
26
|
+
* - triple_axis_pairs === R717 entries matching name 'triple-axis-pair*'
|
|
27
|
+
* - dual_axis_tier_empty: axis_counts.dual === 0 (post-R728 structural milestone)
|
|
28
|
+
*/
|
|
29
|
+
import { chromium } from 'playwright';
|
|
30
|
+
import { readFileSync } from 'node:fs';
|
|
31
|
+
|
|
32
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
33
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
34
|
+
|
|
35
|
+
const browser = await chromium.launch({ headless: true });
|
|
36
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
37
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
38
|
+
await ctx.addInitScript(() => {
|
|
39
|
+
try {
|
|
40
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
41
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
42
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
43
|
+
} catch {}
|
|
44
|
+
});
|
|
45
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
46
|
+
const r = await route.fetch();
|
|
47
|
+
const b = await r.json();
|
|
48
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
49
|
+
const mk = (alias) => ({
|
|
50
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
51
|
+
network_id: nid, project_dir: null,
|
|
52
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
53
|
+
});
|
|
54
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
55
|
+
});
|
|
56
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
57
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
58
|
+
const page = await ctx.newPage();
|
|
59
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
60
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
61
|
+
await page.waitForTimeout(300);
|
|
62
|
+
|
|
63
|
+
const runtimeAttrs = await page.evaluate(() => {
|
|
64
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
65
|
+
return {
|
|
66
|
+
stats: svg?.getAttribute('data-topo-respiratory-axis-count-stats') ?? null,
|
|
67
|
+
rolodex: svg?.getAttribute('data-topo-respiratory-rolodex') ?? null,
|
|
68
|
+
triple: svg?.getAttribute('data-topo-respiratory-triple-axis-surfaces') ?? null,
|
|
69
|
+
patterns: svg?.getAttribute('data-topo-respiratory-patterns') ?? null,
|
|
70
|
+
tiers: svg?.getAttribute('data-topo-respiratory-tiers') ?? null,
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
await browser.close();
|
|
75
|
+
|
|
76
|
+
let stats = null;
|
|
77
|
+
let rolodex = null;
|
|
78
|
+
let triple = null;
|
|
79
|
+
let patterns = null;
|
|
80
|
+
let tiers = null;
|
|
81
|
+
let parseError = null;
|
|
82
|
+
try {
|
|
83
|
+
stats = JSON.parse(runtimeAttrs.stats ?? '');
|
|
84
|
+
rolodex = JSON.parse(runtimeAttrs.rolodex ?? '');
|
|
85
|
+
triple = JSON.parse(runtimeAttrs.triple ?? '');
|
|
86
|
+
patterns = JSON.parse(runtimeAttrs.patterns ?? '');
|
|
87
|
+
tiers = JSON.parse(runtimeAttrs.tiers ?? '');
|
|
88
|
+
} catch (e) {
|
|
89
|
+
parseError = String(e);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const expectedKeys = ['total_anchors', 'cadences', 'cadence_range_s', 'cadence_arc_s', 'axis_counts', 'patterns_count', 'tiers_count', 'triple_axis_pairs', 'triple_axis_solos',
|
|
93
|
+
/* R738 cross-family awareness fields */
|
|
94
|
+
'breath_patterns', 'ambient_patterns', 'pattern_families', 'scan_beam_pairs', 'ambient_cadences'];
|
|
95
|
+
const hasAllKeys = stats && expectedKeys.every(k => k in stats);
|
|
96
|
+
|
|
97
|
+
const rolodexAnchorCount = rolodex && typeof rolodex === 'object'
|
|
98
|
+
? Object.values(rolodex).reduce((acc, list) => acc + (Array.isArray(list) ? list.length : 0), 0)
|
|
99
|
+
: -1;
|
|
100
|
+
const rolodexCadenceCount = rolodex ? Object.keys(rolodex).length : -1;
|
|
101
|
+
const rolodexCadenceMin = rolodex ? Math.min(...Object.keys(rolodex).map(Number)) : -1;
|
|
102
|
+
const rolodexCadenceMax = rolodex ? Math.max(...Object.keys(rolodex).map(Number)) : -1;
|
|
103
|
+
|
|
104
|
+
const r717TriplePairCount = Array.isArray(patterns)
|
|
105
|
+
? patterns.filter(p => typeof p?.name === 'string' && p.name.startsWith('triple-axis-pair')).length
|
|
106
|
+
: -1;
|
|
107
|
+
|
|
108
|
+
/* R738 — cross-family aware derivations from R717 patterns. The
|
|
109
|
+
* scan-beam-pair entry is the only ambient-family pattern today;
|
|
110
|
+
* everything else is breath. */
|
|
111
|
+
const ambientPatternNames = new Set(['scan-beam-pair']);
|
|
112
|
+
const breathPatternCount = Array.isArray(patterns)
|
|
113
|
+
? patterns.filter(p => !ambientPatternNames.has(p?.name)).length : -1;
|
|
114
|
+
const ambientPatternCount = Array.isArray(patterns)
|
|
115
|
+
? patterns.filter(p => ambientPatternNames.has(p?.name)).length : -1;
|
|
116
|
+
const scanBeamPairCount = Array.isArray(patterns)
|
|
117
|
+
? patterns.filter(p => typeof p?.name === 'string' && p.name.startsWith('scan-beam-pair')).length : -1;
|
|
118
|
+
const ambientPatterns = Array.isArray(patterns)
|
|
119
|
+
? patterns.filter(p => ambientPatternNames.has(p?.name)) : [];
|
|
120
|
+
const distinctAmbientCadences = new Set(ambientPatterns.flatMap(p => Array.isArray(p?.cadences) ? p.cadences : []));
|
|
121
|
+
|
|
122
|
+
const axisCountSum = stats?.axis_counts
|
|
123
|
+
? (stats.axis_counts.single ?? 0) + (stats.axis_counts.dual ?? 0) + (stats.axis_counts.triple ?? 0)
|
|
124
|
+
: -1;
|
|
125
|
+
|
|
126
|
+
const results = {
|
|
127
|
+
attr_present: !!runtimeAttrs.stats,
|
|
128
|
+
json_parses: stats !== null && parseError === null,
|
|
129
|
+
has_all_expected_keys: !!hasAllKeys,
|
|
130
|
+
total_anchors_matches_rolodex: stats?.total_anchors === rolodexAnchorCount,
|
|
131
|
+
cadences_count_matches: stats?.cadences === rolodexCadenceCount,
|
|
132
|
+
cadence_range_min_matches: stats?.cadence_range_s?.min === rolodexCadenceMin,
|
|
133
|
+
cadence_range_max_matches: stats?.cadence_range_s?.max === rolodexCadenceMax,
|
|
134
|
+
cadence_arc_consistent: stats?.cadence_arc_s === (rolodexCadenceMax - rolodexCadenceMin),
|
|
135
|
+
triple_count_matches_r723: stats?.axis_counts?.triple === (Array.isArray(triple) ? triple.length : -1),
|
|
136
|
+
axis_count_sum_eq_total: axisCountSum === stats?.total_anchors,
|
|
137
|
+
patterns_count_matches_r717: stats?.patterns_count === (Array.isArray(patterns) ? patterns.length : -1),
|
|
138
|
+
tiers_count_matches_r720: stats?.tiers_count === (Array.isArray(tiers) ? tiers.length : -1),
|
|
139
|
+
triple_axis_pairs_matches: stats?.triple_axis_pairs === r717TriplePairCount,
|
|
140
|
+
dual_axis_tier_empty: stats?.axis_counts?.dual === 0,
|
|
141
|
+
/* R738 cross-family invariants */
|
|
142
|
+
breath_patterns_match_r717: stats?.breath_patterns === breathPatternCount,
|
|
143
|
+
ambient_patterns_match_r717: stats?.ambient_patterns === ambientPatternCount,
|
|
144
|
+
breath_plus_ambient_eq_total: (stats?.breath_patterns ?? -1) + (stats?.ambient_patterns ?? -2) === stats?.patterns_count,
|
|
145
|
+
pattern_families_eq_2: stats?.pattern_families === 2,
|
|
146
|
+
scan_beam_pairs_match_r717: stats?.scan_beam_pairs === scanBeamPairCount,
|
|
147
|
+
ambient_cadences_match_r717: stats?.ambient_cadences === distinctAmbientCadences.size,
|
|
148
|
+
};
|
|
149
|
+
const ok = Object.values(results).every(Boolean);
|
|
150
|
+
console.log(`${ok ? '✅' : '❌'} R729 axis-count stats catalog (6th meta-doc — breath family hexagon):`,
|
|
151
|
+
JSON.stringify(results, null, 2),
|
|
152
|
+
`\n stats: ${JSON.stringify(stats)}`,
|
|
153
|
+
parseError ? `\n parseError: ${parseError}` : '');
|
|
154
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* Round 717 — patterns catalog attr on canvas root. 3rd of 3 meta-doc
|
|
2
|
+
* catalogs completing the breath family's self-describing triangle:
|
|
3
|
+
* R710 data-topo-respiratory-rolodex (cadences)
|
|
4
|
+
* R716 data-topo-respiratory-dual-axis-surfaces (axes)
|
|
5
|
+
* R717 data-topo-respiratory-patterns (patterns)
|
|
6
|
+
*
|
|
7
|
+
* Assertions:
|
|
8
|
+
* - attr present on root <svg>
|
|
9
|
+
* - JSON parses to an Array of exactly 5 entries
|
|
10
|
+
* - shape: each entry has {name, cadences, anchors, shape}
|
|
11
|
+
* - shape strings are one of the 5 known taxonomy values
|
|
12
|
+
* - sum of anchors across patterns matches the R710 anchor count (16)
|
|
13
|
+
* - cross-check: every cadence in R717 patterns also appears in R710 rolodex
|
|
14
|
+
*/
|
|
15
|
+
import { chromium } from 'playwright';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
|
|
18
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
19
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
20
|
+
|
|
21
|
+
const browser = await chromium.launch({ headless: true });
|
|
22
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
23
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
24
|
+
await ctx.addInitScript(() => {
|
|
25
|
+
try {
|
|
26
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
27
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
28
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
29
|
+
} catch {}
|
|
30
|
+
});
|
|
31
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
32
|
+
const r = await route.fetch();
|
|
33
|
+
const b = await r.json();
|
|
34
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
35
|
+
const mk = (alias) => ({
|
|
36
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
37
|
+
network_id: nid, project_dir: null,
|
|
38
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
39
|
+
});
|
|
40
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
41
|
+
});
|
|
42
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
43
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
44
|
+
const page = await ctx.newPage();
|
|
45
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
46
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
47
|
+
await page.waitForTimeout(300);
|
|
48
|
+
|
|
49
|
+
const runtimeAttrs = await page.evaluate(() => {
|
|
50
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
51
|
+
return {
|
|
52
|
+
patterns: svg?.getAttribute('data-topo-respiratory-patterns') ?? null,
|
|
53
|
+
rolodex: svg?.getAttribute('data-topo-respiratory-rolodex') ?? null,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await browser.close();
|
|
58
|
+
|
|
59
|
+
let patterns = null;
|
|
60
|
+
let rolodex = null;
|
|
61
|
+
let parseError = null;
|
|
62
|
+
try {
|
|
63
|
+
patterns = JSON.parse(runtimeAttrs.patterns ?? '');
|
|
64
|
+
rolodex = JSON.parse(runtimeAttrs.rolodex ?? '');
|
|
65
|
+
} catch (e) {
|
|
66
|
+
parseError = String(e);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const validShape = Array.isArray(patterns)
|
|
70
|
+
? patterns.every(p => p && typeof p === 'object'
|
|
71
|
+
&& typeof p.name === 'string' && p.name.length > 0
|
|
72
|
+
&& Array.isArray(p.cadences) && p.cadences.length > 0 && p.cadences.every(c => typeof c === 'number' && c > 0)
|
|
73
|
+
&& Array.isArray(p.anchors) && p.anchors.length > 0 && p.anchors.every(a => typeof a === 'string' && a.length > 0)
|
|
74
|
+
&& typeof p.shape === 'string' && ['trio-with-envelope', 'parity', 'tiered-with-trio', 'tiered-with-quartet', 'tiered-with-quintet', 'coprime-nested-pair', 'baseline-pair', '6s-triple-pair', '8s-triple-pair', 'tier-multi-cadence', 'coprime-crosshair', 'coprime-trio'].includes(p.shape))
|
|
75
|
+
: false;
|
|
76
|
+
|
|
77
|
+
const totalAnchorCount = Array.isArray(patterns)
|
|
78
|
+
? patterns.reduce((acc, p) => acc + (Array.isArray(p.anchors) ? p.anchors.length : 0), 0)
|
|
79
|
+
: 0;
|
|
80
|
+
|
|
81
|
+
/* Cross-check: every cadence in BREATH-family patterns must appear
|
|
82
|
+
* in R710 rolodex. R737 introduced the first cross-family pattern
|
|
83
|
+
* entry (`scan-beam-pair` lives in the ambient family with cadences
|
|
84
|
+
* 23/30); the breath rolodex doesn't cover 30 (no breath anchor at
|
|
85
|
+
* 30s — rolodex max is 25 for R719 fullscreen). Exclude cross-family
|
|
86
|
+
* entries from the rolodex cross-check via name allowlist. */
|
|
87
|
+
const ambientFamilyPatternNames = new Set(['scan-beam-pair', 'scan-beam-trio']);
|
|
88
|
+
const rolodexCadences = rolodex ? new Set(Object.keys(rolodex).map(Number)) : new Set();
|
|
89
|
+
const breathPatternCadences = Array.isArray(patterns)
|
|
90
|
+
? new Set(patterns.filter(p => !ambientFamilyPatternNames.has(p.name)).flatMap(p => p.cadences))
|
|
91
|
+
: new Set();
|
|
92
|
+
const allPatternCadencesInRolodex = [...breathPatternCadences].every(c => rolodexCadences.has(c));
|
|
93
|
+
|
|
94
|
+
const patternNames = Array.isArray(patterns) ? patterns.map(p => p.name).sort() : [];
|
|
95
|
+
const expectedNames = ['background', 'canvas-brand-pair', 'chrome-strip', 'panel-pair', 'scan-beam-pair', 'scan-beam-trio', 'title-block', 'triple-axis-pair', 'triple-axis-pair-8s', 'triple-axis-tier'];
|
|
96
|
+
|
|
97
|
+
const results = {
|
|
98
|
+
attr_present: !!runtimeAttrs.patterns,
|
|
99
|
+
json_parses: patterns !== null && parseError === null,
|
|
100
|
+
is_array: Array.isArray(patterns),
|
|
101
|
+
has_10_entries: Array.isArray(patterns) && patterns.length === 10,
|
|
102
|
+
pattern_names_match: JSON.stringify(patternNames) === JSON.stringify(expectedNames),
|
|
103
|
+
shape_and_taxonomy_valid: validShape,
|
|
104
|
+
total_anchors_count: totalAnchorCount >= 14 && totalAnchorCount <= 38, // R739 +3 anchors (scan-beam-trio adds 3 anchors)
|
|
105
|
+
breath_cadences_in_rolodex: allPatternCadencesInRolodex,
|
|
106
|
+
};
|
|
107
|
+
const ok = Object.values(results).every(Boolean);
|
|
108
|
+
console.log(`${ok ? '✅' : '❌'} R717 patterns catalog attr (3rd meta-doc — breath family triangle complete):`,
|
|
109
|
+
JSON.stringify(results, null, 2),
|
|
110
|
+
`\n patterns: ${JSON.stringify(patterns)}`,
|
|
111
|
+
parseError ? `\n parseError: ${parseError}` : '');
|
|
112
|
+
process.exit(ok ? 0 : 1);
|