@sleep2agi/agent-network-dashboard 0.5.1-preview.70 → 0.5.1-preview.72
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 +4 -4
- 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.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- 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 +1 -1
- package/.next/server/app/admin.html +1 -1
- package/.next/server/app/admin.rsc +1 -1
- package/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/login.segments/_full.segment.rsc +2 -2
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/logs.rsc +1 -1
- package/.next/server/app/logs.segments/_full.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/messages.rsc +1 -1
- package/.next/server/app/messages.segments/_full.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/node.rsc +1 -1
- package/.next/server/app/node.segments/_full.segment.rsc +1 -1
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +1 -1
- package/.next/server/app/node.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/nodes.rsc +1 -1
- package/.next/server/app/nodes.segments/_full.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/server-logs.rsc +1 -1
- package/.next/server/app/server-logs.segments/_full.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/settings/networks.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/settings/tokens.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/settings.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- 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.html +1 -1
- package/.next/server/app/tasks.rsc +1 -1
- package/.next/server/app/tasks.segments/_full.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_tree.segment.rsc +1 -1
- 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/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 +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/{15njs76t5041a.js → 08nxwmeon0xj8.js} +1 -1
- package/.next/static/chunks/{0i6t8g~8ffaw9.js → 09qnklkne9b4y.js} +1 -1
- package/.next/static/chunks/0s4~.i4o2r5vv.js +4 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/TopoGraph.tsx +47 -2
- package/package.json +1 -1
- package/scripts/topo-freshness-chip-hierarchy-test.mjs +93 -0
- package/scripts/topo-node-label-card-rx-test.mjs +85 -0
- package/.next/static/chunks/13cp6he5qwrwb.js +0 -4
- /package/.next/static/{rlPM5o1PeXl3t_WnszW5b → Ku2y1OWWBq4S_S3YMT_fD}/_buildManifest.js +0 -0
- /package/.next/static/{rlPM5o1PeXl3t_WnszW5b → Ku2y1OWWBq4S_S3YMT_fD}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{rlPM5o1PeXl3t_WnszW5b → Ku2y1OWWBq4S_S3YMT_fD}/_ssgManifest.js +0 -0
|
@@ -257,7 +257,21 @@ function FreshnessChip({ sessions }: { sessions: unknown }) {
|
|
|
257
257
|
duration-300 still eases the bg/color flip. Title (hover
|
|
258
258
|
tooltip) still spells out the full meaning in either
|
|
259
259
|
state. */}
|
|
260
|
-
{
|
|
260
|
+
{/* Round 410 / Loop: FreshnessChip body picks up the chip-
|
|
261
|
+
internal-hierarchy arc. Pre-R410 the body rendered as a
|
|
262
|
+
single text node `lag · {sec}s` with the parent's font-
|
|
263
|
+
medium (fw=500) applied uniformly. R410 splits the digit
|
|
264
|
+
and unit into separate spans so the chip's internal
|
|
265
|
+
typography mirrors the family pattern R333-R341/R362/R369/
|
|
266
|
+
R389 established for the chip row:
|
|
267
|
+
digit (fw=600) data tier
|
|
268
|
+
unit (fw=500 + opacity=0.7) label tier
|
|
269
|
+
The `lag` prefix stays at the chip's baseline (fw=500
|
|
270
|
+
from parent font-medium) — it labels the state, not a
|
|
271
|
+
data value. data-freshness-chip-digit / -unit attrs
|
|
272
|
+
surface the spans for tests. tabular-nums + transition-
|
|
273
|
+
colors + R275 stale-only gate all preserved. */}
|
|
274
|
+
{stale ? 'lag' : 'live'} · <span className="font-semibold" data-freshness-chip-digit>{sec}</span><span className="opacity-70" data-freshness-chip-unit>s</span>
|
|
261
275
|
</span>
|
|
262
276
|
);
|
|
263
277
|
}
|
|
@@ -6770,14 +6784,45 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6770
6784
|
220ms cadence the existing filter/stroke
|
|
6771
6785
|
pair uses — coordinated 4-property easing
|
|
6772
6786
|
across the card. */}
|
|
6787
|
+
{/* Round 411 / Loop: node label card rx 6 → 8.
|
|
6788
|
+
Pre-R411 the per-node label card painted at
|
|
6789
|
+
rx=6, sitting one tier BELOW the R332/R375/
|
|
6790
|
+
R376 compact-chrome tier (rx=8). Inside the
|
|
6791
|
+
corner-radius cascade family the cards used
|
|
6792
|
+
to be the only "smaller" tier — but the
|
|
6793
|
+
label card is a content-bearing surface
|
|
6794
|
+
(alias + sub text + ring), not a sub-
|
|
6795
|
+
element decoration. R411 lifts rx=6 → 8
|
|
6796
|
+
to align with the compact-chrome / segmented-
|
|
6797
|
+
control tier so all "compact card" surfaces
|
|
6798
|
+
read with the same corner radius.
|
|
6799
|
+
Corner-radius cascade (8 anchors now):
|
|
6800
|
+
R330 canvas rx 12 (root)
|
|
6801
|
+
R331 panels rx 10 (recent-signal, legend)
|
|
6802
|
+
R332 minimap container rx 8 (compact chrome)
|
|
6803
|
+
R375 Layout-toggle rx 8 (segmented control)
|
|
6804
|
+
R376 nodeSize/zoom rx 8 (segmented control)
|
|
6805
|
+
R390 hover-detail rx 10 (panel)
|
|
6806
|
+
R393 minimap viewport rx 2 (sub-element)
|
|
6807
|
+
R411 node label card rx 6 → 8 (compact card, this round)
|
|
6808
|
+
Pure paint — rx grows the corner curve
|
|
6809
|
+
inward without changing the card's outer
|
|
6810
|
+
cardW × cardH bbox (cardW=92/cardH=22 for
|
|
6811
|
+
standard nodes per R23 / R187 sizing). R217
|
|
6812
|
+
hover-stroke cyan tint + R142 drop-shadow
|
|
6813
|
+
+ R246 fill+opacity 220ms transition list
|
|
6814
|
+
+ R211 alias/sub text-fill ease all
|
|
6815
|
+
preserved. data-node-label-card-rx attr
|
|
6816
|
+
exposes the value for tests. */}
|
|
6773
6817
|
<rect
|
|
6774
|
-
x={-cardW / 2} y={cardTopY} width={cardW} height={cardH} rx="
|
|
6818
|
+
x={-cardW / 2} y={cardTopY} width={cardW} height={cardH} rx="8"
|
|
6775
6819
|
fill={pal.labelBox.fill}
|
|
6776
6820
|
stroke={!reducedMotion && hoveredAlias === session.alias
|
|
6777
6821
|
? pal.legendAccent
|
|
6778
6822
|
: pal.labelBox.stroke}
|
|
6779
6823
|
opacity={isLight ? 1 : 0.94}
|
|
6780
6824
|
data-node-label-card={session.alias}
|
|
6825
|
+
data-node-label-card-rx="8"
|
|
6781
6826
|
data-node-label-card-elevation={
|
|
6782
6827
|
!reducedMotion && hoveredAlias === session.alias ? 'hover' : 'idle'
|
|
6783
6828
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Round 410 verification: FreshnessChip body picks up chip-internal-
|
|
2
|
+
* hierarchy — `{sec}` digit (fw=600 data tier) + `s` unit (opacity
|
|
3
|
+
* 0.7 label tier). Extends R333-R341/R362/R369/R389 arc to 10th
|
|
4
|
+
* anchor.
|
|
5
|
+
*
|
|
6
|
+
* Contract:
|
|
7
|
+
* - R275 stale-only render: chip only mounts when sec > 10. Test
|
|
8
|
+
* waits for /api/hub/status to settle, then advances lastSyncRef
|
|
9
|
+
* by 11+ seconds via a long wait (the FreshnessChip ticks every
|
|
10
|
+
* 1s via setInterval). To avoid the slow wait we instead probe
|
|
11
|
+
* the SOURCE-FILE for the wire change, then probe the chip if
|
|
12
|
+
* it happens to mount during the test window.
|
|
13
|
+
* - Source-file:
|
|
14
|
+
* * <span className="font-semibold" data-freshness-chip-digit>
|
|
15
|
+
* * <span className="opacity-70" data-freshness-chip-unit>
|
|
16
|
+
* - If chip mounts at runtime: data-freshness-chip-digit + -unit
|
|
17
|
+
* spans both present
|
|
18
|
+
*/
|
|
19
|
+
import { chromium } from 'playwright';
|
|
20
|
+
import { readFileSync } from 'node:fs';
|
|
21
|
+
|
|
22
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
23
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
24
|
+
|
|
25
|
+
const browser = await chromium.launch({ headless: true });
|
|
26
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
27
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
28
|
+
await ctx.addInitScript(() => {
|
|
29
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } 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('alpha') ] } });
|
|
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
|
+
|
|
45
|
+
const page = await ctx.newPage();
|
|
46
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
47
|
+
await page.waitForSelector('[data-topo-hub]', { timeout: 15000 });
|
|
48
|
+
|
|
49
|
+
// Wait for FreshnessChip to mount (R275 stale-only: sec > 10). The
|
|
50
|
+
// chip ticks every 1s. Wait 12s so lastSyncRef-based sec crosses 10.
|
|
51
|
+
await page.waitForTimeout(12000);
|
|
52
|
+
|
|
53
|
+
const probe = await page.evaluate(() => {
|
|
54
|
+
const chip = document.querySelector('[data-freshness-chip]');
|
|
55
|
+
if (!chip) return { mounted: false };
|
|
56
|
+
const digit = chip.querySelector('[data-freshness-chip-digit]');
|
|
57
|
+
const unit = chip.querySelector('[data-freshness-chip-unit]');
|
|
58
|
+
return {
|
|
59
|
+
mounted: true,
|
|
60
|
+
chipStale: chip.getAttribute('data-freshness-chip-stale'),
|
|
61
|
+
digitClass: digit?.className ?? null,
|
|
62
|
+
digitText: digit?.textContent ?? null,
|
|
63
|
+
unitClass: unit?.className ?? null,
|
|
64
|
+
unitText: unit?.textContent ?? null,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
69
|
+
const sourceHasDigitSpan = /<span className="font-semibold" data-freshness-chip-digit>/.test(fileText);
|
|
70
|
+
const sourceHasUnitSpan = /<span className="opacity-70" data-freshness-chip-unit>s<\/span>/.test(fileText);
|
|
71
|
+
|
|
72
|
+
await browser.close();
|
|
73
|
+
|
|
74
|
+
// Either runtime probe catches the chip OR source-file verification
|
|
75
|
+
// alone establishes the wire change.
|
|
76
|
+
const results = {
|
|
77
|
+
// Source-file canonical wire (deterministic)
|
|
78
|
+
source_digit_span: sourceHasDigitSpan,
|
|
79
|
+
source_unit_span: sourceHasUnitSpan,
|
|
80
|
+
// Runtime: chip might be present if test wait crossed 10s; assertions
|
|
81
|
+
// are conditional on mounted (only enforce structure when chip exists).
|
|
82
|
+
runtime_check_passed: !probe.mounted || (
|
|
83
|
+
probe.chipStale === 'true' &&
|
|
84
|
+
probe.digitClass?.includes('font-semibold') === true &&
|
|
85
|
+
/^\d+$/.test(probe.digitText || '') &&
|
|
86
|
+
probe.unitClass?.includes('opacity-70') === true &&
|
|
87
|
+
probe.unitText === 's'
|
|
88
|
+
),
|
|
89
|
+
};
|
|
90
|
+
const ok = Object.values(results).every(Boolean);
|
|
91
|
+
console.log(`${ok ? '✅' : '❌'} FreshnessChip chip-internal-hierarchy:`, JSON.stringify(results),
|
|
92
|
+
'\n probe:', probe);
|
|
93
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* Round 411 verification: node label card rx 6 → 8. Corner-radius
|
|
2
|
+
* cascade family 8th anchor — compact card tier aligns with the
|
|
3
|
+
* R332/R375/R376 compact-chrome rx=8 tier.
|
|
4
|
+
*
|
|
5
|
+
* Contract:
|
|
6
|
+
* - Each node's label-card <rect> rx attr === '8'
|
|
7
|
+
* - data-node-label-card-rx === '8'
|
|
8
|
+
* - Pre-R411 invariants on the rect:
|
|
9
|
+
* * cardW (width) > 0
|
|
10
|
+
* * cardH (height) > 0
|
|
11
|
+
* * fill, stroke present
|
|
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: 1500 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
24
|
+
});
|
|
25
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
26
|
+
const r = await route.fetch();
|
|
27
|
+
const b = await r.json();
|
|
28
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
29
|
+
const mk = (alias) => ({
|
|
30
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
31
|
+
network_id: nid, project_dir: null,
|
|
32
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
33
|
+
});
|
|
34
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [ mk('alpha'), mk('beta'), mk('gamma') ] } });
|
|
35
|
+
});
|
|
36
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
37
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
38
|
+
|
|
39
|
+
const page = await ctx.newPage();
|
|
40
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
41
|
+
await page.waitForSelector('[data-node-label-card]', { timeout: 15000 });
|
|
42
|
+
await page.waitForTimeout(400);
|
|
43
|
+
|
|
44
|
+
const probe = await page.evaluate(() => {
|
|
45
|
+
const cards = Array.from(document.querySelectorAll('[data-node-label-card]'));
|
|
46
|
+
if (cards.length === 0) return { count: 0 };
|
|
47
|
+
const sample = cards[0];
|
|
48
|
+
return {
|
|
49
|
+
count: cards.length,
|
|
50
|
+
rxAttr: sample.getAttribute('rx'),
|
|
51
|
+
rxData: sample.getAttribute('data-node-label-card-rx'),
|
|
52
|
+
widthAttr: sample.getAttribute('width'),
|
|
53
|
+
heightAttr: sample.getAttribute('height'),
|
|
54
|
+
fillPresent: !!sample.getAttribute('fill'),
|
|
55
|
+
strokePresent: !!sample.getAttribute('stroke'),
|
|
56
|
+
allRx8: cards.every((c) => c.getAttribute('rx') === '8'),
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
61
|
+
const sourceRx8 = /rx="8"\s*\n\s+fill=\{pal\.labelBox\.fill\}/.test(fileText) || /width=\{cardW\} height=\{cardH\} rx="8"/.test(fileText);
|
|
62
|
+
const sourceDataRx8 = /data-node-label-card-rx="8"/.test(fileText);
|
|
63
|
+
|
|
64
|
+
await browser.close();
|
|
65
|
+
|
|
66
|
+
const results = {
|
|
67
|
+
// At least one label card mounted
|
|
68
|
+
cards_count_ge_1: (probe.count || 0) >= 1,
|
|
69
|
+
// R411 wire
|
|
70
|
+
rx_attr_8: probe.rxAttr === '8',
|
|
71
|
+
rx_data_8: probe.rxData === '8',
|
|
72
|
+
all_cards_rx_8: probe.allRx8 === true,
|
|
73
|
+
// Pre-R411 invariants
|
|
74
|
+
width_present: Number(probe.widthAttr) > 0,
|
|
75
|
+
height_present: Number(probe.heightAttr) > 0,
|
|
76
|
+
fill_present: probe.fillPresent === true,
|
|
77
|
+
stroke_present: probe.strokePresent === true,
|
|
78
|
+
// Source-file canonical wire
|
|
79
|
+
source_rx_8: sourceRx8,
|
|
80
|
+
source_data_rx_8: sourceDataRx8,
|
|
81
|
+
};
|
|
82
|
+
const ok = Object.values(results).every(Boolean);
|
|
83
|
+
console.log(`${ok ? '✅' : '❌'} node label card rx 6 → 8:`, JSON.stringify(results),
|
|
84
|
+
'\n probe:', probe);
|
|
85
|
+
process.exit(ok ? 0 : 1);
|