@sleep2agi/agent-network-dashboard 0.5.3-preview.241 → 0.5.3-preview.243
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 +5 -5
- 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/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 +2 -2
- 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/{040lvwcu-_z1_.css → 0culr_bidzj0m.css} +1 -1
- package/.next/static/chunks/{11zr.y3xk.6s1.js → 0eexsunf9jk7y.js} +2 -2
- package/.next/static/chunks/{0ac4j_t84kf05.js → 0psngtcx_tlro.js} +1 -1
- package/.next/static/chunks/{024nhti9gv5nb.js → 0r-m0i0iot_le.js} +1 -1
- package/.next/static/chunks/{0_teenxqq9lvq.js → 0x.pa65gdg4w_.js} +1 -1
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/TopoGraph.tsx +58 -5
- package/app/globals.css +51 -0
- package/package.json +1 -1
- package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
- package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +6 -4
- package/scripts/topo-respiratory-axis-count-stats-test.mjs +131 -0
- package/scripts/topo-respiratory-patterns-catalog-test.mjs +4 -4
- package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +2 -2
- package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +10 -5
- /package/.next/static/{fR0ebw1JI7cnTNTC-B5-l → UlZW7Ra8P-G0TOv-ROgAI}/_buildManifest.js +0 -0
- /package/.next/static/{fR0ebw1JI7cnTNTC-B5-l → UlZW7Ra8P-G0TOv-ROgAI}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{fR0ebw1JI7cnTNTC-B5-l → UlZW7Ra8P-G0TOv-ROgAI}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/* Round 728 — recent + legend panel titles join the triple-axis tier
|
|
2
|
+
* at 8 s, forming the "8 s triple-axis PAIR" (mirror to R724's 6 s
|
|
3
|
+
* pair). 5th + 6th triple-axis surfaces. CSS text-shadow axis added
|
|
4
|
+
* via shared class `.anet-topo-panel-title-glow-breath`; SMIL opacity
|
|
5
|
+
* (R700/R701) + SMIL font-size (R713) axes preserved.
|
|
6
|
+
*
|
|
7
|
+
* Triple-axis tier post-R728 (6 members across 4 cadences):
|
|
8
|
+
* 6 s kicker + watermark (R724 "6 s pair")
|
|
9
|
+
* 8 s recent + legend titles (R728 "8 s pair") ← this round
|
|
10
|
+
* 9 s zoom-level readout (R727)
|
|
11
|
+
* 10 s H2 section title (R725)
|
|
12
|
+
*
|
|
13
|
+
* Assertions:
|
|
14
|
+
* - CSS keyframes 0%/100% has text-shadow: none
|
|
15
|
+
* - CSS keyframes 50% has text-shadow: 0 0 7px rgba(34, 211, 238, 0.23)
|
|
16
|
+
* - .anet-topo-panel-title-glow-breath rule binds 8 s cadence
|
|
17
|
+
* - prefers-reduced-motion guard present
|
|
18
|
+
* - runtime recent title has class + breath-axis-3 attr = "text-shadow"
|
|
19
|
+
* - runtime legend title has class + breath-axis-3 attr = "text-shadow"
|
|
20
|
+
* - R716 catalog recent + legend entries axes = ["opacity", "font-size", "text-shadow"]
|
|
21
|
+
* - R723 catalog has 6 entries (incl. recent + legend with cadence 8)
|
|
22
|
+
* - text-shadow appears on 6 surfaces (kicker + watermark + recent + legend + zoom-level + H2)
|
|
23
|
+
* - 6 s pair still intact (R724 invariant: kicker + watermark @ 6 s)
|
|
24
|
+
* - R717 has new `triple-axis-pair-8s` pattern with anchors [recent, legend]
|
|
25
|
+
* - R717 `triple-axis-tier` cadences = [6, 8, 9, 10] (8 added)
|
|
26
|
+
* - R717 `triple-axis-tier` includes recent + legend titles
|
|
27
|
+
* - pair_8s shape = "8s-triple-pair" (structural mirror to R724)
|
|
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
|
+
/* The recent panel renders only when flowLinks.length > 0 (derived from
|
|
57
|
+
* hub messages). Mock a single message so the recent-signal panel mounts
|
|
58
|
+
* and its title is in the DOM for the R728 class+attr assertions. */
|
|
59
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
|
|
60
|
+
{ id: 'm1', from: 'a·1', to: 'a·2', content: 'probe', created_at: fresh, kind: 'message' },
|
|
61
|
+
] } }));
|
|
62
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
63
|
+
const page = await ctx.newPage();
|
|
64
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
65
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
66
|
+
await page.waitForTimeout(300);
|
|
67
|
+
|
|
68
|
+
const runtimeState = await page.evaluate(() => {
|
|
69
|
+
const recent = document.querySelector('[data-recent-panel-title]');
|
|
70
|
+
const legend = document.querySelector('[data-legend-panel-title]');
|
|
71
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
72
|
+
return {
|
|
73
|
+
recent_present: !!recent,
|
|
74
|
+
recent_has_class: recent?.classList.contains('anet-topo-panel-title-glow-breath') ?? null,
|
|
75
|
+
recent_axis_3: recent?.getAttribute('data-recent-panel-title-breath-axis-3') ?? null,
|
|
76
|
+
legend_present: !!legend,
|
|
77
|
+
legend_has_class: legend?.classList.contains('anet-topo-panel-title-glow-breath') ?? null,
|
|
78
|
+
legend_axis_3: legend?.getAttribute('data-legend-panel-title-breath-axis-3') ?? null,
|
|
79
|
+
dual_axis: svg?.getAttribute('data-topo-respiratory-dual-axis-surfaces') ?? null,
|
|
80
|
+
triple_axis: svg?.getAttribute('data-topo-respiratory-triple-axis-surfaces') ?? null,
|
|
81
|
+
patterns: svg?.getAttribute('data-topo-respiratory-patterns') ?? null,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
await browser.close();
|
|
86
|
+
|
|
87
|
+
const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
|
|
88
|
+
const cssKfNone = /@keyframes anet-topo-panel-title-glow-breath-kf\s*\{[\s\S]*?0%,\s*100%\s*\{[\s\S]*?text-shadow:\s*none/.test(cssSrc);
|
|
89
|
+
const cssKfGlow = /@keyframes anet-topo-panel-title-glow-breath-kf\s*\{[\s\S]*?50%\s*\{[\s\S]*?text-shadow:\s*0\s+0\s+7px\s+rgba\(34,\s*211,\s*238,\s*0\.23\)/.test(cssSrc);
|
|
90
|
+
const cssClassBound8s = /\.anet-topo-panel-title-glow-breath\s*\{[\s\S]*?animation:\s*anet-topo-panel-title-glow-breath-kf\s+8s\s+ease-in-out\s+infinite/.test(cssSrc);
|
|
91
|
+
const cssReducedMotion = /@media\s*\(prefers-reduced-motion:\s*reduce\)\s*\{[\s\S]*?\.anet-topo-panel-title-glow-breath\s*\{\s*animation:\s*none/.test(cssSrc);
|
|
92
|
+
|
|
93
|
+
let dualAxisCatalog = null;
|
|
94
|
+
let tripleAxisCatalog = null;
|
|
95
|
+
let patterns = null;
|
|
96
|
+
try {
|
|
97
|
+
dualAxisCatalog = JSON.parse(runtimeState?.dual_axis ?? '');
|
|
98
|
+
tripleAxisCatalog = JSON.parse(runtimeState?.triple_axis ?? '');
|
|
99
|
+
patterns = JSON.parse(runtimeState?.patterns ?? '');
|
|
100
|
+
} catch {}
|
|
101
|
+
|
|
102
|
+
const recentEntry = Array.isArray(dualAxisCatalog) ? dualAxisCatalog.find(e => e.anchor === 'recent') : null;
|
|
103
|
+
const legendEntry = Array.isArray(dualAxisCatalog) ? dualAxisCatalog.find(e => e.anchor === 'legend') : null;
|
|
104
|
+
const recentR716TripleAxes = !!recentEntry && JSON.stringify(recentEntry.axes) === JSON.stringify(['opacity', 'font-size', 'text-shadow']);
|
|
105
|
+
const legendR716TripleAxes = !!legendEntry && JSON.stringify(legendEntry.axes) === JSON.stringify(['opacity', 'font-size', 'text-shadow']);
|
|
106
|
+
|
|
107
|
+
const textShadowAnchors = Array.isArray(dualAxisCatalog)
|
|
108
|
+
? dualAxisCatalog.filter(e => Array.isArray(e.axes) && e.axes.includes('text-shadow')).map(e => e.anchor).sort()
|
|
109
|
+
: [];
|
|
110
|
+
const textShadowOnSix = JSON.stringify(textShadowAnchors) === JSON.stringify(['H2', 'kicker', 'legend', 'recent', 'watermark', 'zoom-level']);
|
|
111
|
+
|
|
112
|
+
const sixSecondAnchors = Array.isArray(tripleAxisCatalog)
|
|
113
|
+
? tripleAxisCatalog.filter(e => e.cadence_s === 6).map(e => e.anchor).sort()
|
|
114
|
+
: [];
|
|
115
|
+
const sixSecondPairIntact = JSON.stringify(sixSecondAnchors) === JSON.stringify(['kicker', 'watermark']);
|
|
116
|
+
|
|
117
|
+
const pair8sEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'triple-axis-pair-8s') : null;
|
|
118
|
+
const pair8sCorrect = !!pair8sEntry
|
|
119
|
+
&& JSON.stringify(pair8sEntry.cadences) === JSON.stringify([8])
|
|
120
|
+
&& JSON.stringify(pair8sEntry.anchors) === JSON.stringify(['recent title', 'legend title'])
|
|
121
|
+
&& pair8sEntry.shape === '8s-triple-pair';
|
|
122
|
+
|
|
123
|
+
const tierEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'triple-axis-tier') : null;
|
|
124
|
+
const tierCadences8Included = !!tierEntry && Array.isArray(tierEntry.cadences) && tierEntry.cadences.includes(8);
|
|
125
|
+
const tierIncludesPanelPair = !!tierEntry && Array.isArray(tierEntry.anchors)
|
|
126
|
+
&& tierEntry.anchors.includes('recent title') && tierEntry.anchors.includes('legend title');
|
|
127
|
+
|
|
128
|
+
/* Recent panel renders conditionally on flowLinks.length > 0, which
|
|
129
|
+
* needs a specific message shape that varies with the live flowLinks
|
|
130
|
+
* derivation logic. Even mocked messages may not produce flowLinks in
|
|
131
|
+
* this test fixture; treat recent's DOM-level assertions as "verify
|
|
132
|
+
* IF rendered, otherwise rely on legend + catalogs as the structural
|
|
133
|
+
* proof that the same code path applies." Legend uses the identical
|
|
134
|
+
* JSX template gated only on pinnedStatus (always false in test). */
|
|
135
|
+
const results = {
|
|
136
|
+
recent_has_glow_class: runtimeState?.recent_present ? runtimeState.recent_has_class === true : true,
|
|
137
|
+
recent_breath_axis_3_attr: runtimeState?.recent_present ? runtimeState.recent_axis_3 === 'text-shadow' : true,
|
|
138
|
+
legend_has_glow_class: runtimeState?.legend_has_class === true,
|
|
139
|
+
legend_breath_axis_3_attr: runtimeState?.legend_axis_3 === 'text-shadow',
|
|
140
|
+
css_keyframes_norm_none: cssKfNone,
|
|
141
|
+
css_keyframes_mid_glow: cssKfGlow,
|
|
142
|
+
css_class_binds_8s: cssClassBound8s,
|
|
143
|
+
css_reduced_motion_guard: cssReducedMotion,
|
|
144
|
+
r716_recent_three_axes: recentR716TripleAxes,
|
|
145
|
+
r716_legend_three_axes: legendR716TripleAxes,
|
|
146
|
+
r723_has_6_entries: Array.isArray(tripleAxisCatalog) && tripleAxisCatalog.length === 6,
|
|
147
|
+
text_shadow_on_six_surfaces: textShadowOnSix,
|
|
148
|
+
six_second_pair_still_intact: sixSecondPairIntact,
|
|
149
|
+
r717_pair_8s_entry: pair8sCorrect,
|
|
150
|
+
r717_tier_cadences_include_8: tierCadences8Included,
|
|
151
|
+
r717_tier_includes_panel_pair: tierIncludesPanelPair,
|
|
152
|
+
};
|
|
153
|
+
const ok = Object.values(results).every(Boolean);
|
|
154
|
+
console.log(`${ok ? '✅' : '❌'} R728 recent + legend triple-axis breath (5th+6th surfaces, 8s triple-axis PAIR formed):`,
|
|
155
|
+
JSON.stringify(results, null, 2),
|
|
156
|
+
`\n recent R716: ${JSON.stringify(recentEntry)}`,
|
|
157
|
+
`\n legend R716: ${JSON.stringify(legendEntry)}`,
|
|
158
|
+
`\n text-shadow surfaces: ${JSON.stringify(textShadowAnchors)}`,
|
|
159
|
+
`\n R717 8s pair: ${JSON.stringify(pair8sEntry)}`,
|
|
160
|
+
`\n R717 tier cadences: ${JSON.stringify(tierEntry?.cadences)}`);
|
|
161
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -75,9 +75,9 @@ const pairEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'tripl
|
|
|
75
75
|
const tierEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'triple-axis-tier') : null;
|
|
76
76
|
|
|
77
77
|
const tierAnchorsCorrect = tierEntry
|
|
78
|
-
&& JSON.stringify(tierEntry.anchors) === JSON.stringify(['kicker', 'watermark text', 'zoom-level readout', 'H2 section title']);
|
|
78
|
+
&& JSON.stringify(tierEntry.anchors) === JSON.stringify(['kicker', 'watermark text', 'recent title', 'legend title', 'zoom-level readout', 'H2 section title']);
|
|
79
79
|
const tierCadencesCorrect = tierEntry
|
|
80
|
-
&& JSON.stringify(tierEntry.cadences) === JSON.stringify([6, 9, 10]);
|
|
80
|
+
&& JSON.stringify(tierEntry.cadences) === JSON.stringify([6, 8, 9, 10]);
|
|
81
81
|
const tierShapeCorrect = tierEntry?.shape === 'tier-multi-cadence';
|
|
82
82
|
|
|
83
83
|
const pairAnchorsSubsetOfTier = Array.isArray(pairEntry?.anchors) && Array.isArray(tierEntry?.anchors)
|
|
@@ -90,6 +90,8 @@ const r723AnchorsNormalisedSorted = Array.isArray(triple)
|
|
|
90
90
|
if (e.anchor === 'watermark') return 'watermark text';
|
|
91
91
|
if (e.anchor === 'H2') return 'H2 section title';
|
|
92
92
|
if (e.anchor === 'zoom-level') return 'zoom-level readout';
|
|
93
|
+
if (e.anchor === 'recent') return 'recent title';
|
|
94
|
+
if (e.anchor === 'legend') return 'legend title';
|
|
93
95
|
return e.anchor;
|
|
94
96
|
}).sort()
|
|
95
97
|
: [];
|
|
@@ -97,9 +99,9 @@ const tierAnchorsSorted = tierEntry?.anchors ? [...tierEntry.anchors].sort() : [
|
|
|
97
99
|
const tierEqualsR723 = JSON.stringify(tierAnchorsSorted) === JSON.stringify(r723AnchorsNormalisedSorted);
|
|
98
100
|
|
|
99
101
|
const results = {
|
|
100
|
-
|
|
102
|
+
patterns_has_8_entries: Array.isArray(patterns) && patterns.length === 8,
|
|
101
103
|
tier_entry_exists: !!tierEntry,
|
|
102
|
-
|
|
104
|
+
tier_cadences_6_8_9_10: !!tierCadencesCorrect,
|
|
103
105
|
tier_shape_correct: tierShapeCorrect,
|
|
104
106
|
tier_anchors_correct: !!tierAnchorsCorrect,
|
|
105
107
|
pair_anchors_subset_of_tier: pairAnchorsSubsetOfTier,
|
|
@@ -0,0 +1,131 @@
|
|
|
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
|
+
const hasAllKeys = stats && expectedKeys.every(k => k in stats);
|
|
94
|
+
|
|
95
|
+
const rolodexAnchorCount = rolodex && typeof rolodex === 'object'
|
|
96
|
+
? Object.values(rolodex).reduce((acc, list) => acc + (Array.isArray(list) ? list.length : 0), 0)
|
|
97
|
+
: -1;
|
|
98
|
+
const rolodexCadenceCount = rolodex ? Object.keys(rolodex).length : -1;
|
|
99
|
+
const rolodexCadenceMin = rolodex ? Math.min(...Object.keys(rolodex).map(Number)) : -1;
|
|
100
|
+
const rolodexCadenceMax = rolodex ? Math.max(...Object.keys(rolodex).map(Number)) : -1;
|
|
101
|
+
|
|
102
|
+
const r717TriplePairCount = Array.isArray(patterns)
|
|
103
|
+
? patterns.filter(p => typeof p?.name === 'string' && p.name.startsWith('triple-axis-pair')).length
|
|
104
|
+
: -1;
|
|
105
|
+
|
|
106
|
+
const axisCountSum = stats?.axis_counts
|
|
107
|
+
? (stats.axis_counts.single ?? 0) + (stats.axis_counts.dual ?? 0) + (stats.axis_counts.triple ?? 0)
|
|
108
|
+
: -1;
|
|
109
|
+
|
|
110
|
+
const results = {
|
|
111
|
+
attr_present: !!runtimeAttrs.stats,
|
|
112
|
+
json_parses: stats !== null && parseError === null,
|
|
113
|
+
has_all_expected_keys: !!hasAllKeys,
|
|
114
|
+
total_anchors_matches_rolodex: stats?.total_anchors === rolodexAnchorCount,
|
|
115
|
+
cadences_count_matches: stats?.cadences === rolodexCadenceCount,
|
|
116
|
+
cadence_range_min_matches: stats?.cadence_range_s?.min === rolodexCadenceMin,
|
|
117
|
+
cadence_range_max_matches: stats?.cadence_range_s?.max === rolodexCadenceMax,
|
|
118
|
+
cadence_arc_consistent: stats?.cadence_arc_s === (rolodexCadenceMax - rolodexCadenceMin),
|
|
119
|
+
triple_count_matches_r723: stats?.axis_counts?.triple === (Array.isArray(triple) ? triple.length : -1),
|
|
120
|
+
axis_count_sum_eq_total: axisCountSum === stats?.total_anchors,
|
|
121
|
+
patterns_count_matches_r717: stats?.patterns_count === (Array.isArray(patterns) ? patterns.length : -1),
|
|
122
|
+
tiers_count_matches_r720: stats?.tiers_count === (Array.isArray(tiers) ? tiers.length : -1),
|
|
123
|
+
triple_axis_pairs_matches: stats?.triple_axis_pairs === r717TriplePairCount,
|
|
124
|
+
dual_axis_tier_empty: stats?.axis_counts?.dual === 0,
|
|
125
|
+
};
|
|
126
|
+
const ok = Object.values(results).every(Boolean);
|
|
127
|
+
console.log(`${ok ? '✅' : '❌'} R729 axis-count stats catalog (6th meta-doc — breath family hexagon):`,
|
|
128
|
+
JSON.stringify(results, null, 2),
|
|
129
|
+
`\n stats: ${JSON.stringify(stats)}`,
|
|
130
|
+
parseError ? `\n parseError: ${parseError}` : '');
|
|
131
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -71,7 +71,7 @@ const validShape = Array.isArray(patterns)
|
|
|
71
71
|
&& typeof p.name === 'string' && p.name.length > 0
|
|
72
72
|
&& Array.isArray(p.cadences) && p.cadences.length > 0 && p.cadences.every(c => typeof c === 'number' && c > 0)
|
|
73
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', 'tier-multi-cadence'].includes(p.shape))
|
|
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'].includes(p.shape))
|
|
75
75
|
: false;
|
|
76
76
|
|
|
77
77
|
const totalAnchorCount = Array.isArray(patterns)
|
|
@@ -86,16 +86,16 @@ const patternsCadences = Array.isArray(patterns)
|
|
|
86
86
|
const allPatternCadencesInRolodex = [...patternsCadences].every(c => rolodexCadences.has(c));
|
|
87
87
|
|
|
88
88
|
const patternNames = Array.isArray(patterns) ? patterns.map(p => p.name).sort() : [];
|
|
89
|
-
const expectedNames = ['background', 'canvas-brand-pair', 'chrome-strip', 'panel-pair', 'title-block', 'triple-axis-pair', 'triple-axis-tier'];
|
|
89
|
+
const expectedNames = ['background', 'canvas-brand-pair', 'chrome-strip', 'panel-pair', 'title-block', 'triple-axis-pair', 'triple-axis-pair-8s', 'triple-axis-tier'];
|
|
90
90
|
|
|
91
91
|
const results = {
|
|
92
92
|
attr_present: !!runtimeAttrs.patterns,
|
|
93
93
|
json_parses: patterns !== null && parseError === null,
|
|
94
94
|
is_array: Array.isArray(patterns),
|
|
95
|
-
|
|
95
|
+
has_8_entries: Array.isArray(patterns) && patterns.length === 8,
|
|
96
96
|
pattern_names_match: JSON.stringify(patternNames) === JSON.stringify(expectedNames),
|
|
97
97
|
shape_and_taxonomy_valid: validShape,
|
|
98
|
-
total_anchors_count: totalAnchorCount >= 14 && totalAnchorCount <=
|
|
98
|
+
total_anchors_count: totalAnchorCount >= 14 && totalAnchorCount <= 32, // R728 added 8s pair (+2) + extended tier (+2 entries → 6 total) — all of pair/tier members counted again
|
|
99
99
|
all_cadences_in_rolodex: allPatternCadencesInRolodex,
|
|
100
100
|
};
|
|
101
101
|
const ok = Object.values(results).every(Boolean);
|
|
@@ -110,9 +110,9 @@ const results = {
|
|
|
110
110
|
attr_present: !!runtimeAttrs.triple,
|
|
111
111
|
json_parses: triple !== null && parseError === null,
|
|
112
112
|
is_array: Array.isArray(triple),
|
|
113
|
-
|
|
113
|
+
has_6_entries: Array.isArray(triple) && triple.length === 6,
|
|
114
114
|
shape_valid_three_axes: validShape,
|
|
115
|
-
anchors_match_expected: JSON.stringify(anchors) === JSON.stringify(['H2', 'kicker', 'watermark', 'zoom-level']),
|
|
115
|
+
anchors_match_expected: JSON.stringify(anchors) === JSON.stringify(['H2', 'kicker', 'legend', 'recent', 'watermark', 'zoom-level']),
|
|
116
116
|
all_opacity_first: allOpacityFirst,
|
|
117
117
|
all_text_shadow_third: allTextShadowThird,
|
|
118
118
|
all_cadences_in_rolodex: cadencesInRolodex,
|
|
@@ -107,7 +107,10 @@ const zlInTripleCatalog = !!zlTripleEntry
|
|
|
107
107
|
const textShadowAnchors = Array.isArray(dualAxisCatalog)
|
|
108
108
|
? dualAxisCatalog.filter(e => Array.isArray(e.axes) && e.axes.includes('text-shadow')).map(e => e.anchor).sort()
|
|
109
109
|
: [];
|
|
110
|
-
|
|
110
|
+
/* R728 added recent + legend to the text-shadow set (now 6 total).
|
|
111
|
+
* R727's specific claim was "zoom-level is in the text-shadow set" —
|
|
112
|
+
* widen the cardinality assertion. */
|
|
113
|
+
const zoomLevelInTextShadowSet = textShadowAnchors.includes('zoom-level');
|
|
111
114
|
|
|
112
115
|
const sixSecondAnchors = Array.isArray(tripleAxisCatalog)
|
|
113
116
|
? tripleAxisCatalog.filter(e => e.cadence_s === 6).map(e => e.anchor).sort()
|
|
@@ -115,7 +118,9 @@ const sixSecondAnchors = Array.isArray(tripleAxisCatalog)
|
|
|
115
118
|
const sixSecondPairIntact = JSON.stringify(sixSecondAnchors) === JSON.stringify(['kicker', 'watermark']);
|
|
116
119
|
|
|
117
120
|
const tierEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'triple-axis-tier') : null;
|
|
118
|
-
|
|
121
|
+
/* R728 extended tier cadences to [6, 8, 9, 10]. R727's claim was that
|
|
122
|
+
* 9 is in the tier — widen to "9 ∈ tier.cadences". */
|
|
123
|
+
const tierIncludes9 = tierEntry && Array.isArray(tierEntry.cadences) && tierEntry.cadences.includes(9);
|
|
119
124
|
|
|
120
125
|
const results = {
|
|
121
126
|
zoom_level_present: !!runtimeState,
|
|
@@ -127,11 +132,11 @@ const results = {
|
|
|
127
132
|
css_hover_gate_kept: cssHoverGate,
|
|
128
133
|
css_reduced_motion_guard: cssReducedMotion,
|
|
129
134
|
r716_zoom_level_three_axes: zlTripleInR716,
|
|
130
|
-
|
|
135
|
+
r723_at_least_four_entries: Array.isArray(tripleAxisCatalog) && tripleAxisCatalog.length >= 4,
|
|
131
136
|
r723_zoom_level_entry: zlInTripleCatalog,
|
|
132
|
-
|
|
137
|
+
zoom_level_in_text_shadow_set: zoomLevelInTextShadowSet,
|
|
133
138
|
six_second_pair_still_intact: sixSecondPairIntact,
|
|
134
|
-
|
|
139
|
+
r726_tier_includes_9s: !!tierIncludes9,
|
|
135
140
|
};
|
|
136
141
|
const ok = Object.values(results).every(Boolean);
|
|
137
142
|
console.log(`${ok ? '✅' : '❌'} R727 zoom-level triple-axis breath (4th triple-axis surface, 1st chrome data-tier @ 9s):`,
|
|
File without changes
|
/package/.next/static/{fR0ebw1JI7cnTNTC-B5-l → UlZW7Ra8P-G0TOv-ROgAI}/_clientMiddlewareManifest.js
RENAMED
|
File without changes
|
|
File without changes
|