@sleep2agi/agent-network-dashboard 0.5.2-preview.8 → 0.5.2
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.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/[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 +3 -3
- 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/{0kakzr~7pmm6f.js → 0f8e_np0z2f~m.js} +1 -1
- package/.next/static/chunks/0u-~k4hsu~8wq.js +4 -0
- package/.next/static/chunks/13ro4cw~e4_99.js +1 -0
- package/.next/static/chunks/14c.ui5lbvctz.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/TopoGraph.tsx +274 -30
- package/package.json +1 -1
- package/screenshots/v0.10.4-150-orphans/after.png +0 -0
- package/scripts/p150-orphan-layout-screenshot.mjs +82 -0
- package/scripts/topo-edge-badge-hot-glow-test.mjs +101 -0
- package/scripts/topo-edge-particle-opacity-lift-test.mjs +109 -0
- package/scripts/topo-group-label-glow-test.mjs +104 -0
- package/scripts/topo-legend-panel-title-fw-test.mjs +95 -0
- package/scripts/topo-minimap-dot-lift-test.mjs +115 -0
- package/scripts/topo-minimap-zoom-glow-test.mjs +86 -0
- package/scripts/topo-orphan-band-test.mjs +106 -0
- package/scripts/topo-recent-panel-title-fw-test.mjs +106 -0
- package/scripts/topo-recent-row-freshness-glow-test.mjs +100 -0
- package/scripts/topo-recent-row-ts-lift-test.mjs +97 -0
- package/.next/static/chunks/06ypqia1-atbo.js +0 -1
- package/.next/static/chunks/11s-p36ef7hy0.js +0 -4
- package/.next/static/chunks/17y6nangmpg~u.js +0 -1
- /package/.next/static/{wJxl4oP18MvCP4fry5nN7 → p5R7hozl9ewrkvLpgzAoX}/_buildManifest.js +0 -0
- /package/.next/static/{wJxl4oP18MvCP4fry5nN7 → p5R7hozl9ewrkvLpgzAoX}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{wJxl4oP18MvCP4fry5nN7 → p5R7hozl9ewrkvLpgzAoX}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* Round 482 verification: recent-signal panel title "recent signal"
|
|
2
|
+
* gains fontWeight 700 → 800 on activeEdgeKey (any row hover or pin).
|
|
3
|
+
* Extends the "data tightens under attention" pattern to the panel-
|
|
4
|
+
* title scope alongside R345's existing letter-spacing tween on
|
|
5
|
+
* panel-chrome hover.
|
|
6
|
+
*
|
|
7
|
+
* Contract:
|
|
8
|
+
* - at rest (no row hover/pin): data-recent-panel-title-fw='700'
|
|
9
|
+
* + data-recent-panel-title-active='false'
|
|
10
|
+
* - click a recent-signal row hitbox to pin: title fw flips to '800'
|
|
11
|
+
* + active='true'
|
|
12
|
+
* - click again to unpin: title returns to fw='700'
|
|
13
|
+
* - source-file conditional wired
|
|
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 nowIso = () => new Date().toISOString();
|
|
20
|
+
const sessionFresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
21
|
+
|
|
22
|
+
const browser = await chromium.launch({ headless: true });
|
|
23
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript(() => {
|
|
26
|
+
try {
|
|
27
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
28
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
29
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
30
|
+
} catch {}
|
|
31
|
+
});
|
|
32
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
33
|
+
const r = await route.fetch();
|
|
34
|
+
const b = await r.json();
|
|
35
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
36
|
+
const mk = (alias, status) => ({
|
|
37
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
38
|
+
network_id: nid, project_dir: null,
|
|
39
|
+
created_at: sessionFresh, updated_at: sessionFresh, last_seen_at: sessionFresh,
|
|
40
|
+
});
|
|
41
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
42
|
+
mk('a·1', 'working'), mk('a·2', 'idle'), mk('b·1', 'working'),
|
|
43
|
+
] } });
|
|
44
|
+
});
|
|
45
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: {
|
|
46
|
+
messages: [
|
|
47
|
+
{ id: 'm1', from_alias: 'a·1', to_alias: 'a·2', content: 'ping', created_at: nowIso() },
|
|
48
|
+
{ id: 'm2', from_alias: 'b·1', to_alias: 'a·1', content: 'pong', created_at: nowIso() },
|
|
49
|
+
],
|
|
50
|
+
} }));
|
|
51
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
52
|
+
|
|
53
|
+
const page = await ctx.newPage();
|
|
54
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
55
|
+
await page.waitForSelector('[data-recent-panel-title]', { timeout: 15000 });
|
|
56
|
+
await page.waitForTimeout(800);
|
|
57
|
+
|
|
58
|
+
const readTitle = () => page.evaluate(() => {
|
|
59
|
+
const t = document.querySelector('[data-recent-panel-title]');
|
|
60
|
+
if (!t) return null;
|
|
61
|
+
return {
|
|
62
|
+
fw: t.getAttribute('data-recent-panel-title-fw'),
|
|
63
|
+
active: t.getAttribute('data-recent-panel-title-active'),
|
|
64
|
+
liveFW: t.getAttribute('font-weight'),
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const rest = await readTitle();
|
|
69
|
+
// Click first recent-row to pin
|
|
70
|
+
await page.click('[data-recent-row]');
|
|
71
|
+
await page.waitForTimeout(400);
|
|
72
|
+
const pinned = await readTitle();
|
|
73
|
+
// Click again to unpin (toggles pinnedEdgeKey).
|
|
74
|
+
// After the click, move pointer off the row — otherwise
|
|
75
|
+
// hoveredEdgeKey still holds even after pin clears
|
|
76
|
+
// (activeEdgeKey = hoveredEdgeKey ?? pinnedEdgeKey).
|
|
77
|
+
await page.click('[data-recent-row]');
|
|
78
|
+
await page.mouse.move(50, 50); // off the recent-signal panel
|
|
79
|
+
await page.waitForTimeout(400);
|
|
80
|
+
const restAgain = await readTitle();
|
|
81
|
+
|
|
82
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
83
|
+
const sourceFwConditional = /fontWeight=\{activeEdgeKey \? '800' : '700'\}/.test(src);
|
|
84
|
+
const sourceFwTween = /font-weight 200ms ease-out/.test(src);
|
|
85
|
+
const sourceDataAttr = /data-recent-panel-title-fw=\{activeEdgeKey \?/.test(src);
|
|
86
|
+
|
|
87
|
+
await browser.close();
|
|
88
|
+
|
|
89
|
+
const restIs700 = rest?.fw === '700' && rest?.active === 'false' && rest?.liveFW === '700';
|
|
90
|
+
const pinIs800 = pinned?.fw === '800' && pinned?.active === 'true' && pinned?.liveFW === '800';
|
|
91
|
+
const restAgainIs700 = restAgain?.fw === '700' && restAgain?.active === 'false' && restAgain?.liveFW === '700';
|
|
92
|
+
|
|
93
|
+
const results = {
|
|
94
|
+
rest_is_700_inactive: restIs700,
|
|
95
|
+
pin_flips_to_800_active: pinIs800,
|
|
96
|
+
unpin_back_to_700: restAgainIs700,
|
|
97
|
+
source_fw_conditional: sourceFwConditional,
|
|
98
|
+
source_fw_tween: sourceFwTween,
|
|
99
|
+
source_data_attr: sourceDataAttr,
|
|
100
|
+
};
|
|
101
|
+
const ok = Object.values(results).every(Boolean);
|
|
102
|
+
console.log(`${ok ? '✅' : '❌'} recent-panel title fw 700→800:`, JSON.stringify(results),
|
|
103
|
+
'\n rest:', JSON.stringify(rest),
|
|
104
|
+
'\n pinned:', JSON.stringify(pinned),
|
|
105
|
+
'\n rest again:', JSON.stringify(restAgain));
|
|
106
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Round 478 verification: recent-row freshness pip gains filter:
|
|
2
|
+
* drop-shadow glow when alpha > 0.7 (just-fired flow within ~30s).
|
|
3
|
+
* Freshness-gated (not pin/hover-gated), so the glow reads as
|
|
4
|
+
* "this signal is live" — natural breathing feel that tracks
|
|
5
|
+
* actual data freshness.
|
|
6
|
+
*
|
|
7
|
+
* Contract:
|
|
8
|
+
* - fresh (created_at = now): alpha=1.0, data-recent-row-freshness-
|
|
9
|
+
* glow='true', computed filter starts with 'drop-shadow'
|
|
10
|
+
* - stale (created_at = 5min ago): alpha→0.30, glow='false',
|
|
11
|
+
* filter === 'none'
|
|
12
|
+
* - source-file conditional wired
|
|
13
|
+
*/
|
|
14
|
+
import { chromium } from 'playwright';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
18
|
+
const nowIso = () => new Date().toISOString();
|
|
19
|
+
const sessionFresh = 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, status) => ({
|
|
36
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
37
|
+
network_id: nid, project_dir: null,
|
|
38
|
+
created_at: sessionFresh, updated_at: sessionFresh, last_seen_at: sessionFresh,
|
|
39
|
+
});
|
|
40
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
41
|
+
mk('a·1', 'working'), mk('a·2', 'idle'), mk('b·1', 'working'),
|
|
42
|
+
] } });
|
|
43
|
+
});
|
|
44
|
+
// Mix fresh + stale messages so we get rows in both freshness tiers.
|
|
45
|
+
// Fresh: created NOW → alpha = 1.0 (within 30s gate)
|
|
46
|
+
// Stale: created 5min ago → alpha = 0.30 (R10 stale floor)
|
|
47
|
+
const fiveMinAgo = new Date(Date.now() - 5 * 60 * 1000).toISOString();
|
|
48
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: {
|
|
49
|
+
messages: [
|
|
50
|
+
{ id: 'm1', from_alias: 'a·1', to_alias: 'a·2', content: 'live', created_at: nowIso() },
|
|
51
|
+
{ id: 'm2', from_alias: 'b·1', to_alias: 'a·1', content: 'stale', created_at: fiveMinAgo },
|
|
52
|
+
],
|
|
53
|
+
} }));
|
|
54
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
55
|
+
|
|
56
|
+
const page = await ctx.newPage();
|
|
57
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
58
|
+
await page.waitForSelector('[data-recent-row-freshness]', { timeout: 15000 });
|
|
59
|
+
await page.waitForTimeout(800);
|
|
60
|
+
|
|
61
|
+
const probe = await page.evaluate(() => {
|
|
62
|
+
const pips = [...document.querySelectorAll('[data-recent-row-freshness]')];
|
|
63
|
+
return pips.map(p => {
|
|
64
|
+
const cs = getComputedStyle(p);
|
|
65
|
+
return {
|
|
66
|
+
key: p.getAttribute('data-recent-row-freshness'),
|
|
67
|
+
alpha: parseFloat(p.getAttribute('data-recent-row-freshness-alpha') || '0'),
|
|
68
|
+
glow: p.getAttribute('data-recent-row-freshness-glow'),
|
|
69
|
+
filter: cs.filter,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
75
|
+
const sourceGlowAttr = /data-recent-row-freshness-glow=\{alpha > 0\.7/.test(src);
|
|
76
|
+
const sourceDropShadow = /drop-shadow\(0 0 3px \$\{pal\.legendAccent\}80\)/.test(src);
|
|
77
|
+
const sourceFilterTween = /filter 200ms ease-out/.test(src);
|
|
78
|
+
|
|
79
|
+
await browser.close();
|
|
80
|
+
|
|
81
|
+
const fresh = probe.find(p => p.alpha > 0.7);
|
|
82
|
+
const stale = probe.find(p => p.alpha < 0.5);
|
|
83
|
+
|
|
84
|
+
const results = {
|
|
85
|
+
pips_count_ge_2: probe.length >= 2,
|
|
86
|
+
fresh_pip_found: !!fresh,
|
|
87
|
+
fresh_glow_true: fresh?.glow === 'true',
|
|
88
|
+
fresh_filter_has_drop: fresh && /drop-shadow/.test(fresh.filter),
|
|
89
|
+
stale_pip_found: !!stale,
|
|
90
|
+
stale_glow_false: stale?.glow === 'false',
|
|
91
|
+
stale_filter_none: stale?.filter === 'none',
|
|
92
|
+
source_glow_attr: sourceGlowAttr,
|
|
93
|
+
source_drop_shadow: sourceDropShadow,
|
|
94
|
+
source_filter_tween: sourceFilterTween,
|
|
95
|
+
};
|
|
96
|
+
const ok = Object.values(results).every(Boolean);
|
|
97
|
+
console.log(`${ok ? '✅' : '❌'} recent-row freshness pip drop-shadow:`, JSON.stringify(results),
|
|
98
|
+
'\n fresh pip:', JSON.stringify(fresh),
|
|
99
|
+
'\n stale pip:', JSON.stringify(stale));
|
|
100
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/* Round 484 verification: recent-row timestamp opacity lifts to
|
|
2
|
+
* 1.0 when isRowHovered || isRowPinned, overriding the R191
|
|
3
|
+
* freshness-decay tsAlpha. Inspection state shows full freshness
|
|
4
|
+
* regardless of decay.
|
|
5
|
+
*
|
|
6
|
+
* Contract:
|
|
7
|
+
* - stale row (5min ago): tsAlpha ≈ 0.30, ts-lifted='false',
|
|
8
|
+
* live opacity matches tsAlpha
|
|
9
|
+
* - click stale row to pin: ts-lifted='true', live opacity='1'
|
|
10
|
+
* - source-file conditional wired
|
|
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 sessionFresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
17
|
+
const fiveMinAgo = new Date(Date.now() - 5 * 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: sessionFresh, updated_at: sessionFresh, last_seen_at: sessionFresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
39
|
+
mk('a·1', 'working'), mk('a·2', 'idle'),
|
|
40
|
+
] } });
|
|
41
|
+
});
|
|
42
|
+
// One stale message — its freshness alpha decays to ~0.30 at 5min
|
|
43
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: {
|
|
44
|
+
messages: [
|
|
45
|
+
{ id: 'm1', from_alias: 'a·1', to_alias: 'a·2', content: 'old', created_at: fiveMinAgo },
|
|
46
|
+
],
|
|
47
|
+
} }));
|
|
48
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
49
|
+
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
52
|
+
await page.waitForSelector('[data-recent-row-ts]', { timeout: 15000 });
|
|
53
|
+
await page.waitForTimeout(500);
|
|
54
|
+
|
|
55
|
+
const readTs = () => page.evaluate(() => {
|
|
56
|
+
const t = document.querySelector('[data-recent-row-ts]');
|
|
57
|
+
if (!t) return null;
|
|
58
|
+
return {
|
|
59
|
+
alpha: parseFloat(t.getAttribute('data-recent-row-ts-alpha') || '0'),
|
|
60
|
+
lifted: t.getAttribute('data-recent-row-ts-lifted'),
|
|
61
|
+
opacity: t.getAttribute('opacity'),
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const rest = await readTs();
|
|
66
|
+
// Click recent-row to pin
|
|
67
|
+
await page.click('[data-recent-row]');
|
|
68
|
+
await page.waitForTimeout(400);
|
|
69
|
+
const pinned = await readTs();
|
|
70
|
+
|
|
71
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
72
|
+
const sourceLiftConditional = /opacity=\{\(isRowHovered \|\| isRowPinned\) \? 1 : tsAlpha\}/.test(src);
|
|
73
|
+
const sourceLiftedAttr = /data-recent-row-ts-lifted=/.test(src);
|
|
74
|
+
|
|
75
|
+
await browser.close();
|
|
76
|
+
|
|
77
|
+
// Rest: alpha < 0.7 (stale) + lifted='false' + opacity matches alpha
|
|
78
|
+
const restValid = rest?.lifted === 'false' && rest?.alpha < 0.7 &&
|
|
79
|
+
Math.abs(parseFloat(rest?.opacity || '0') - rest?.alpha) < 0.01;
|
|
80
|
+
// Pinned: lifted='true' + opacity=1 (overrides stale alpha)
|
|
81
|
+
const pinValid = pinned?.lifted === 'true' && pinned?.opacity === '1';
|
|
82
|
+
|
|
83
|
+
const results = {
|
|
84
|
+
ts_present: !!rest,
|
|
85
|
+
rest_lifted_false: rest?.lifted === 'false',
|
|
86
|
+
rest_alpha_stale: rest?.alpha < 0.7,
|
|
87
|
+
rest_opacity_matches_alpha: restValid,
|
|
88
|
+
pin_lifted_true: pinned?.lifted === 'true',
|
|
89
|
+
pin_opacity_is_1: pinned?.opacity === '1',
|
|
90
|
+
source_lift_conditional: sourceLiftConditional,
|
|
91
|
+
source_lifted_attr: sourceLiftedAttr,
|
|
92
|
+
};
|
|
93
|
+
const ok = Object.values(results).every(Boolean);
|
|
94
|
+
console.log(`${ok ? '✅' : '❌'} recent-row ts opacity lift on active:`, JSON.stringify(results),
|
|
95
|
+
'\n rest:', JSON.stringify(rest),
|
|
96
|
+
'\n pinned:', JSON.stringify(pinned));
|
|
97
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,70286,e=>{"use strict";e.s(["DASHBOARD_VERSION",0,"0.5.2-preview.8"],70286)},48941,e=>{"use strict";var t=e.i(22381),r=e.i(23910),a=e.i(70286);e.s(["default",0,function(){let[e,s]=(0,r.useState)("login"),[n,o]=(0,r.useState)(""),[i,l]=(0,r.useState)(""),[c,d]=(0,r.useState)(!1),[x,g]=(0,r.useState)(""),[h,m]=(0,r.useState)(!1),u=async t=>{t.preventDefault(),m(!0),g("");try{let t=await fetch("/api/auth/v3",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:e,username:n,password:i})}),r=await t.json();if(r.ok){r.token&&sessionStorage.setItem("anet_v3_auth",JSON.stringify({user:r.user,token:r.token,networks:r.networks||[],currentNetwork:r.network_id||r.networks?.[0]?.network_id||""})),window.location.assign("/");return}g(r.error||"Login failed")}catch{g("Connection failed")}m(!1)};return(0,t.jsxs)("main",{className:"min-h-screen bg-[#0a0a1a] text-gray-100 font-mono flex items-center justify-center relative overflow-hidden px-4 py-10 sm:py-16",children:[(0,t.jsx)("div",{className:"absolute inset-0 pointer-events-none anet-login-bg","aria-hidden":!0}),(0,t.jsxs)("div",{className:"relative w-full max-w-sm",children:[(0,t.jsxs)("div",{className:"text-center mb-7",children:[(0,t.jsx)("div",{className:"inline-flex items-center justify-center w-16 h-16 mb-4 rounded-2xl bg-[#111128] border border-[#2a2a4a] anet-login-mark",children:(0,t.jsxs)("svg",{className:"w-9 h-9",viewBox:"0 0 32 32","aria-hidden":!0,children:[(0,t.jsx)("circle",{cx:"16",cy:"16",r:"10",fill:"none",stroke:"currentColor",strokeWidth:"1.5",opacity:"0.25",className:"text-cyan-400 anet-login-mark-ring"}),(0,t.jsx)("line",{x1:"16",y1:"10",x2:"10",y2:"20",stroke:"currentColor",strokeWidth:"1",opacity:"0.5",className:"text-cyan-400 anet-login-mark-edge"}),(0,t.jsx)("line",{x1:"16",y1:"10",x2:"22",y2:"20",stroke:"currentColor",strokeWidth:"1",opacity:"0.5",className:"text-cyan-400 anet-login-mark-edge"}),(0,t.jsx)("line",{x1:"10",y1:"20",x2:"22",y2:"20",stroke:"currentColor",strokeWidth:"1",opacity:"0.5",className:"text-cyan-400 anet-login-mark-edge"}),(0,t.jsx)("circle",{cx:"16",cy:"10",r:"3",fill:"currentColor",className:"text-cyan-400 anet-login-mark-node-a"}),(0,t.jsx)("circle",{cx:"10",cy:"20",r:"3",fill:"currentColor",className:"text-green-400 anet-login-mark-node-b"}),(0,t.jsx)("circle",{cx:"22",cy:"20",r:"3",fill:"currentColor",className:"text-violet-400 anet-login-mark-node-c"})]})}),(0,t.jsx)("h1",{className:"text-[22px] sm:text-2xl font-semibold text-white tracking-tight",children:"Agent Network"}),(0,t.jsx)("p",{className:"text-[13px] text-gray-500 mt-1.5 leading-snug",children:"login"===e?(0,t.jsxs)(t.Fragment,{children:["Welcome back · ",(0,t.jsx)("span",{className:"text-gray-600",children:"Tasks · Mesh · Messages"})]}):(0,t.jsxs)(t.Fragment,{children:["Create your account · ",(0,t.jsx)("span",{className:"text-gray-600",children:"Free preview · no credit card"})]})})]}),(0,t.jsx)("div",{className:"flex rounded-lg border border-[#2a2a4a] bg-[#111128] p-1 mb-4",children:["login","register"].map(r=>(0,t.jsx)("button",{type:"button",onClick:()=>{s(r),g("")},className:`flex-1 rounded-md px-3 py-2 text-sm transition-colors ${e===r?"bg-cyan-500/10 text-cyan-300":"text-gray-500 hover:text-gray-200"}`,children:"login"===r?"Sign in":"Register"},r))}),(0,t.jsxs)("form",{onSubmit:u,className:"border border-[#2a2a4a] bg-[#111128]/80 backdrop-blur-sm rounded-xl p-6 shadow-2xl shadow-black/30",children:[(0,t.jsx)("label",{htmlFor:"username",className:"block text-xs text-gray-500 mb-2 uppercase tracking-wider",children:"Username"}),(0,t.jsx)("input",{id:"username",type:"text",value:n,onChange:e=>o(e.target.value),autoFocus:!0,placeholder:"Enter username",className:"w-full bg-[#0a0a15] border border-[#2a2a4a] rounded-lg px-4 py-3 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/20 focus:outline-none transition-all mb-4"}),(0,t.jsx)("label",{htmlFor:"password",className:"block text-xs text-gray-500 mb-2 uppercase tracking-wider",children:"Password"}),(0,t.jsxs)("div",{className:"relative",children:[(0,t.jsx)("input",{id:"password",type:c?"text":"password",value:i,onChange:e=>l(e.target.value),placeholder:"Enter password",className:"w-full bg-[#0a0a15] border border-[#2a2a4a] rounded-lg px-4 pr-11 py-3 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/20 focus:outline-none transition-all"}),(0,t.jsx)("button",{type:"button",onClick:()=>d(e=>!e),tabIndex:-1,"aria-label":c?"Hide password":"Show password",className:"absolute inset-y-0 right-0 flex items-center px-3 text-gray-600 hover:text-gray-300 transition-colors",children:c?(0,t.jsxs)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"}),(0,t.jsx)("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]}):(0,t.jsxs)("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,t.jsx)("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),(0,t.jsx)("circle",{cx:"12",cy:"12",r:"3"})]})})]}),x&&(0,t.jsx)("div",{className:"mt-3 text-sm text-red-300 bg-red-500/5 border border-red-500/10 rounded-lg px-3 py-2",children:x}),(0,t.jsxs)("button",{type:"submit",disabled:h||!i||!n.trim(),className:"mt-5 w-full flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 disabled:from-gray-800 disabled:to-gray-800 disabled:text-gray-600 text-white text-sm font-medium rounded-lg transition-all shadow-lg shadow-cyan-500/10 hover:shadow-cyan-500/20 disabled:shadow-none",children:[h&&(0,t.jsxs)("svg",{"aria-hidden":!0,className:"w-4 h-4 animate-spin",viewBox:"0 0 24 24",fill:"none",children:[(0,t.jsx)("circle",{cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"3",opacity:"0.25"}),(0,t.jsx)("path",{d:"M4 12a8 8 0 018-8",stroke:"currentColor",strokeWidth:"3",strokeLinecap:"round"})]}),(0,t.jsx)("span",{children:h?"login"===e?"Signing in…":"Registering…":"login"===e?"Sign in":"Create account"})]})]}),(0,t.jsxs)("p",{className:"text-center text-[11px] text-gray-700 mt-6",children:["Sleep2AGI · Apache-2.0 · ",(0,t.jsx)("a",{href:"https://anet.sh",className:"hover:text-gray-500 transition-colors",children:"anet.sh"}),(0,t.jsx)("span",{className:"mx-1 text-gray-800",children:"·"}),(0,t.jsxs)("span",{className:"font-mono",title:"@sleep2agi/agent-network-dashboard",children:["v",a.DASHBOARD_VERSION]})]})]})]})}])}]);
|