@sleep2agi/agent-network-dashboard 0.5.1-preview.9 → 0.5.1-preview.91

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.
Files changed (236) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/diagnostics/route-bundle-stats.json +6 -6
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/server/app/_global-error.html +1 -1
  6. package/.next/server/app/_global-error.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_not-found.html +2 -2
  14. package/.next/server/app/_not-found.rsc +2 -2
  15. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  16. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  18. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  22. package/.next/server/app/admin.html +2 -2
  23. package/.next/server/app/admin.rsc +2 -2
  24. package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
  25. package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  26. package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
  27. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  28. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
  29. package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
  30. package/.next/server/app/index.html +2 -2
  31. package/.next/server/app/index.rsc +3 -3
  32. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  33. package/.next/server/app/index.segments/_full.segment.rsc +3 -3
  34. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  35. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  36. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  37. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/login.html +2 -2
  39. package/.next/server/app/login.rsc +3 -3
  40. package/.next/server/app/login.segments/_full.segment.rsc +3 -3
  41. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  42. package/.next/server/app/login.segments/_index.segment.rsc +2 -2
  43. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  44. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  45. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  46. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  47. package/.next/server/app/logs.html +2 -2
  48. package/.next/server/app/logs.rsc +2 -2
  49. package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
  50. package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
  51. package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
  52. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  53. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
  54. package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
  55. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  56. package/.next/server/app/messages.html +2 -2
  57. package/.next/server/app/messages.rsc +2 -2
  58. package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
  59. package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
  60. package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
  61. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  62. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
  63. package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
  64. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app/node.html +2 -2
  66. package/.next/server/app/node.rsc +2 -2
  67. package/.next/server/app/node.segments/_full.segment.rsc +2 -2
  68. package/.next/server/app/node.segments/_head.segment.rsc +1 -1
  69. package/.next/server/app/node.segments/_index.segment.rsc +2 -2
  70. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  71. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
  72. package/.next/server/app/node.segments/node.segment.rsc +1 -1
  73. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  74. package/.next/server/app/nodes.html +2 -2
  75. package/.next/server/app/nodes.rsc +2 -2
  76. package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
  77. package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
  78. package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
  79. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  80. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
  81. package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
  82. package/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  84. package/.next/server/app/server-logs.html +2 -2
  85. package/.next/server/app/server-logs.rsc +2 -2
  86. package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
  87. package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
  88. package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
  89. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  90. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
  91. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
  92. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  93. package/.next/server/app/settings/networks.html +2 -2
  94. package/.next/server/app/settings/networks.rsc +2 -2
  95. package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
  96. package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
  97. package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
  98. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  99. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
  100. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
  101. package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
  102. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  103. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/settings/tokens.html +2 -2
  105. package/.next/server/app/settings/tokens.rsc +2 -2
  106. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
  107. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
  108. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
  109. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  110. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
  111. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
  112. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
  113. package/.next/server/app/settings.html +2 -2
  114. package/.next/server/app/settings.rsc +3 -3
  115. package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
  116. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  117. package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  118. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  119. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
  120. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  121. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  122. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/tasks.html +2 -2
  124. package/.next/server/app/tasks.rsc +2 -2
  125. package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
  126. package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
  127. package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
  128. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  129. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
  130. package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
  131. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
  132. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  133. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  134. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  135. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  136. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  137. package/.next/server/middleware-build-manifest.js +3 -3
  138. package/.next/server/pages/404.html +2 -2
  139. package/.next/server/pages/500.html +1 -1
  140. package/.next/static/chunks/017hq2-5l~_98.css +2 -0
  141. package/.next/static/chunks/07t9_p5h7da1u.js +1 -0
  142. package/.next/static/chunks/0ahff_xzbgbg4.js +4 -0
  143. package/.next/static/chunks/10qa7z9iocn6t.js +1 -0
  144. package/.next/trace +2 -2
  145. package/.next/trace-build +1 -1
  146. package/app/components/TopoGraph.tsx +1777 -111
  147. package/package.json +1 -1
  148. package/scripts/topo-active-links-chip-hover-lift-test.mjs +93 -0
  149. package/scripts/topo-chip-digit-fontweight-test.mjs +105 -0
  150. package/scripts/topo-chip-digit-hover-bold-test.mjs +94 -0
  151. package/scripts/topo-chip-row-group-hover-brighten-test.mjs +107 -0
  152. package/scripts/topo-chip-row-hover-lift-test.mjs +95 -0
  153. package/scripts/topo-chrome-button-hover-lift-test.mjs +94 -0
  154. package/scripts/topo-chrome-segmented-radius-test.mjs +100 -0
  155. package/scripts/topo-click-ripple-opacity-test.mjs +99 -0
  156. package/scripts/topo-edge-badge-digit-fw-test.mjs +103 -0
  157. package/scripts/topo-edge-badge-fontsize-test.mjs +90 -0
  158. package/scripts/topo-edge-badge-hover-opacity-test.mjs +94 -0
  159. package/scripts/topo-edge-badge-hover-stroke-test.mjs +92 -0
  160. package/scripts/topo-edge-badge-opacity-test.mjs +80 -0
  161. package/scripts/topo-edge-badge-pin-opacity-test.mjs +86 -0
  162. package/scripts/topo-edge-badge-stroke-test.mjs +92 -0
  163. package/scripts/topo-edge-freshness-floor-test.mjs +99 -0
  164. package/scripts/topo-edge-particle-radius-test.mjs +76 -0
  165. package/scripts/topo-edge-visible-linecap-test.mjs +89 -0
  166. package/scripts/topo-filter-pill-hover-lift-test.mjs +101 -0
  167. package/scripts/topo-filter-pill-hover-opacity-test.mjs +110 -0
  168. package/scripts/topo-filter-pill-value-fw-test.mjs +88 -0
  169. package/scripts/topo-filter-pill-x-hover-scale-test.mjs +99 -0
  170. package/scripts/topo-flow-rail-linecap-test.mjs +79 -0
  171. package/scripts/topo-freshness-chip-hierarchy-test.mjs +93 -0
  172. package/scripts/topo-freshness-chip-tabular-test.mjs +41 -0
  173. package/scripts/topo-freshness-floor-lift-test.mjs +92 -0
  174. package/scripts/topo-freshness-suffix-tabular-test.mjs +88 -0
  175. package/scripts/topo-fullscreen-icon-hover-scale-test.mjs +91 -0
  176. package/scripts/topo-group-box-stroke-test.mjs +105 -0
  177. package/scripts/topo-group-label-count-fontweight-test.mjs +108 -0
  178. package/scripts/topo-hover-detail-body-fw-test.mjs +101 -0
  179. package/scripts/topo-hover-detail-model-fw-test.mjs +98 -0
  180. package/scripts/topo-hover-detail-opacity-test.mjs +98 -0
  181. package/scripts/topo-hover-detail-rx-test.mjs +81 -0
  182. package/scripts/topo-hub-digit-fontsize-test.mjs +86 -0
  183. package/scripts/topo-hub-digit-fw-hover-test.mjs +102 -0
  184. package/scripts/topo-hub-halo-light-trough-test.mjs +88 -0
  185. package/scripts/topo-hub-halo-radius-test.mjs +86 -0
  186. package/scripts/topo-hub-halo-trough-test.mjs +83 -0
  187. package/scripts/topo-hub-highlight-opacity-test.mjs +88 -0
  188. package/scripts/topo-hub-highlight-radius-test.mjs +90 -0
  189. package/scripts/topo-hub-hover-ring-opacity-test.mjs +96 -0
  190. package/scripts/topo-hub-hover-ring-stroke-test.mjs +86 -0
  191. package/scripts/topo-hub-spoke-hover-opacity-test.mjs +119 -0
  192. package/scripts/topo-hub-spoke-linecap-test.mjs +80 -0
  193. package/scripts/topo-label-card-opacity-hover-test.mjs +99 -0
  194. package/scripts/topo-layout-toggle-hover-tracking-test.mjs +109 -0
  195. package/scripts/topo-layout-toggle-radius-test.mjs +87 -0
  196. package/scripts/topo-legend-label-fontweight-test.mjs +94 -0
  197. package/scripts/topo-legend-pin-ring-stroke-test.mjs +101 -0
  198. package/scripts/topo-minimap-offline-opacity-test.mjs +90 -0
  199. package/scripts/topo-minimap-online-hover-opacity-test.mjs +92 -0
  200. package/scripts/topo-minimap-online-opacity-test.mjs +93 -0
  201. package/scripts/topo-minimap-online-radius-test.mjs +85 -0
  202. package/scripts/topo-minimap-viewport-linejoin-test.mjs +75 -0
  203. package/scripts/topo-minimap-viewport-rx-test.mjs +85 -0
  204. package/scripts/topo-more-flows-fontweight-test.mjs +103 -0
  205. package/scripts/topo-node-alias-letter-spacing-test.mjs +112 -0
  206. package/scripts/topo-node-halo-offline-opacity-test.mjs +87 -0
  207. package/scripts/topo-node-label-card-rx-test.mjs +85 -0
  208. package/scripts/topo-node-pulse-peak-test.mjs +89 -0
  209. package/scripts/topo-node-pulse-trough-test.mjs +91 -0
  210. package/scripts/topo-node-sub-text-letter-spacing-test.mjs +115 -0
  211. package/scripts/topo-panel-count-fw-hover-test.mjs +105 -0
  212. package/scripts/topo-panel-count-letterspacing-test.mjs +89 -0
  213. package/scripts/topo-panel-stroke-hover-test.mjs +110 -0
  214. package/scripts/topo-pressure-bar-height-test.mjs +92 -0
  215. package/scripts/topo-pressure-kicker-fontweight-test.mjs +76 -0
  216. package/scripts/topo-recent-pip-radius-2-test.mjs +72 -0
  217. package/scripts/topo-recent-pip-radius-test.mjs +76 -0
  218. package/scripts/topo-recent-row-content-opacity-test.mjs +81 -0
  219. package/scripts/topo-recent-row-text-fontweight-test.mjs +90 -0
  220. package/scripts/topo-reset-hover-rotate-test.mjs +102 -0
  221. package/scripts/topo-spoke-active-opacity-test.mjs +104 -0
  222. package/scripts/topo-spoke-active-stroke-test.mjs +95 -0
  223. package/scripts/topo-spoke-idle-opacity-test.mjs +91 -0
  224. package/scripts/topo-vendor-chip-hover-lift-test.mjs +87 -0
  225. package/scripts/topo-vendor-glyph-fontweight-test.mjs +102 -0
  226. package/scripts/topo-vendor-letter-hover-scale-test.mjs +129 -0
  227. package/scripts/topo-vendor-suffix-hover-brighten-test.mjs +87 -0
  228. package/scripts/topo-zoom-icon-hover-scale-test.mjs +114 -0
  229. package/scripts/topo-zoom-level-hover-fw-test.mjs +95 -0
  230. package/.next/static/chunks/08fc_cz1nk7b9.js +0 -1
  231. package/.next/static/chunks/0aauz~36q5n2a.css +0 -2
  232. package/.next/static/chunks/0e0okm.affulg.js +0 -1
  233. package/.next/static/chunks/0s3vtwfo26_t6.js +0 -4
  234. /package/.next/static/{egukPz1ctU--4WnT2FpEU → i0drwZtW8h-M1ML2C5VZF}/_buildManifest.js +0 -0
  235. /package/.next/static/{egukPz1ctU--4WnT2FpEU → i0drwZtW8h-M1ML2C5VZF}/_clientMiddlewareManifest.js +0 -0
  236. /package/.next/static/{egukPz1ctU--4WnT2FpEU → i0drwZtW8h-M1ML2C5VZF}/_ssgManifest.js +0 -0
@@ -0,0 +1,129 @@
1
+ /* Round 354 verification: vendor letter glyph scales 1.0 → 1.1 on
2
+ * hover. R88 already dims OTHER vendors via canvas-wide opacity
3
+ * masking; R202 added a chip-level bg tint (color-mix 12 % alpha) so
4
+ * the chip itself responds. R354 closes the trio with a glyph-level
5
+ * lift: the focused vendor LETTER actively rises (transform scale)
6
+ * rather than the chip merely changing colour.
7
+ *
8
+ * Three layers of positive feedback on the hovered vendor + canvas-
9
+ * wide negative feedback on the others — a clean figure/ground
10
+ * separation.
11
+ *
12
+ * Contract (cyber, fixture with 3 distinct vendors so R281's > 2
13
+ * threshold mounts the chip):
14
+ * - Rest: vendor letter glyph transform === matrix(1, 0, 0, 1, 0, 0)
15
+ * (identity).
16
+ * - Hover one vendor chip: that glyph transform === matrix(1.1, 0,
17
+ * 0, 1.1, 0, 0).
18
+ * - data-vendor-letter-glyph-hover toggles false → true on
19
+ * hovered chip only; sibling glyphs stay 'false'.
20
+ * - Inline transition contains 'transform'.
21
+ * - Pre-R354 invariants: R202 bg color-mix on hover still applies,
22
+ * data-vendor-letter-count-suffix span (R333) still present.
23
+ */
24
+ import { chromium } from 'playwright';
25
+ import { readFileSync } from 'node:fs';
26
+
27
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
28
+ const browser = await chromium.launch({ headless: true });
29
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
30
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
31
+ await ctx.addInitScript(() => {
32
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
33
+ });
34
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
35
+ await ctx.route('**/api/hub/status*', async (route) => {
36
+ const r = await route.fetch();
37
+ const b = await r.json();
38
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
39
+ // R281 vendor-dist threshold is > 2 distinct vendors — provide 3.
40
+ const mk = (alias, model) => ({
41
+ alias, status: 'working', model, runtime: 'claude-code-cli',
42
+ network_id: nid, project_dir: null,
43
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
44
+ });
45
+ await route.fulfill({ response: r, json: { ...b, sessions: [
46
+ mk('a1', 'claude-opus-4'),
47
+ mk('a2', 'claude-opus-4'),
48
+ mk('b1', 'gpt-4o'),
49
+ mk('b2', 'gpt-4o'),
50
+ mk('c1', 'internlm/internlm2'),
51
+ ] } });
52
+ });
53
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
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: 'domcontentloaded' });
58
+ await page.waitForSelector('[data-vendor-letter-glyph]', { timeout: 15000 });
59
+ await page.waitForTimeout(300);
60
+
61
+ // Read all vendor letters present.
62
+ const inventory = await page.evaluate(() => {
63
+ const glyphs = Array.from(document.querySelectorAll('[data-vendor-letter-glyph]'));
64
+ return glyphs.map(el => el.getAttribute('data-vendor-letter-glyph'));
65
+ });
66
+
67
+ // Pick the first vendor letter for the hover test.
68
+ const target = inventory[0];
69
+
70
+ const restProbe = await page.evaluate((tgt) => {
71
+ const glyph = document.querySelector(`[data-vendor-letter-glyph="${tgt}"]`);
72
+ const cs = glyph ? getComputedStyle(glyph) : null;
73
+ const chip = glyph ? glyph.closest('[data-vendor-letter]') : null;
74
+ const suffix = chip ? chip.querySelector('[data-vendor-letter-count-suffix]') : null;
75
+ return {
76
+ transform: cs?.transform ?? null,
77
+ transition: cs?.transition ?? null,
78
+ hoverAttr: glyph?.getAttribute('data-vendor-letter-glyph-hover') ?? null,
79
+ display: cs?.display ?? null,
80
+ suffixPresent: !!suffix,
81
+ };
82
+ }, target);
83
+
84
+ // Hover the target vendor letter's chip.
85
+ await page.hover(`[data-vendor-letter="${target}"]`);
86
+ await page.waitForTimeout(300);
87
+ const hoverProbe = await page.evaluate((tgt) => {
88
+ const glyph = document.querySelector(`[data-vendor-letter-glyph="${tgt}"]`);
89
+ const cs = glyph ? getComputedStyle(glyph) : null;
90
+ // Read all sibling hover attrs to confirm only one is active.
91
+ const all = Array.from(document.querySelectorAll('[data-vendor-letter-glyph]'))
92
+ .map(el => ({ key: el.getAttribute('data-vendor-letter-glyph'),
93
+ hover: el.getAttribute('data-vendor-letter-glyph-hover') }));
94
+ return {
95
+ transform: cs?.transform ?? null,
96
+ hoverAttr: glyph?.getAttribute('data-vendor-letter-glyph-hover') ?? null,
97
+ siblings: all,
98
+ };
99
+ }, target);
100
+
101
+ await browser.close();
102
+
103
+ const isIdentity = (t) => t === 'none' || /matrix\(1, 0, 0, 1, 0, 0\)/.test(t || '');
104
+ const isScale110 = (t) => /matrix\(1\.1, 0, 0, 1\.1, 0, 0\)/.test(t || '');
105
+ const hasTrans = (s, prop) =>
106
+ new RegExp(`${prop}\\s+\\d*\\.?\\d*s|${prop}\\s+\\d+ms`, 'i').test(s || '');
107
+
108
+ const siblingsOnlyOneTrue = hoverProbe.siblings.filter(s => s.hover === 'true').length === 1
109
+ && hoverProbe.siblings.find(s => s.key === target)?.hover === 'true';
110
+
111
+ const results = {
112
+ inventory_has_glyphs: inventory.length >= 3,
113
+ rest_identity: isIdentity(restProbe.transform),
114
+ rest_hover_false: restProbe.hoverAttr === 'false',
115
+ // Flex children get display: block computed (spec blockification),
116
+ // even when declared inline-block — accept either for safety.
117
+ rest_display_block: restProbe.display === 'inline-block' || restProbe.display === 'block',
118
+ trans_has_transform: hasTrans(restProbe.transition, 'transform'),
119
+ suffix_present: restProbe.suffixPresent, // R333 preserved
120
+ hover_scale_110: isScale110(hoverProbe.transform),
121
+ hover_attr_true: hoverProbe.hoverAttr === 'true',
122
+ hover_isolates_target: siblingsOnlyOneTrue,
123
+ };
124
+ const ok = Object.values(results).every(Boolean);
125
+ console.log(`${ok ? '✅' : '❌'} vendor letter glyph hover-scale:`, JSON.stringify(results),
126
+ '\n inventory:', inventory,
127
+ '\n rest: ', restProbe,
128
+ '\n hover: ', hoverProbe);
129
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,87 @@
1
+ /* Round 417 verification: vendor letter chip count suffix gains
2
+ * inner-span hover-brighten. Extends the family (3rd anchor)
3
+ * after R355 filter pill prefix/suffix + R414 chip-row unit.
4
+ *
5
+ * Contract:
6
+ * - Vendor chip className includes `group`
7
+ * - Vendor count suffix span className includes:
8
+ * * opacity-70 (rest)
9
+ * * group-hover:opacity-100
10
+ * * transition-opacity duration-200
11
+ * * text-gray-400 (label-tier color preserved)
12
+ * * tabular-nums (R333 invariant)
13
+ * - Pre-R417 invariants preserved:
14
+ * * R401 hover:-translate-y-px on chip parent
15
+ * * data-vendor-letter-count-suffix attr present
16
+ */
17
+ import { chromium } from 'playwright';
18
+ import { readFileSync } from 'node:fs';
19
+
20
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
21
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
22
+
23
+ const browser = await chromium.launch({ headless: true });
24
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
25
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
26
+ await ctx.addInitScript(() => {
27
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } 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, model) => ({
34
+ alias, status: 'idle', model, runtime: 'claude-code-cli',
35
+ network_id: nid, project_dir: null,
36
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
37
+ });
38
+ // R281 vendor chip threshold > 2 distinct vendors — need at least 3
39
+ await route.fulfill({ response: r, json: { ...b, sessions: [
40
+ mk('alpha', 'claude-opus-4'),
41
+ mk('beta', 'gpt-5'),
42
+ mk('gamma', 'gemini-2.0-pro'),
43
+ ] } });
44
+ });
45
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
46
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
47
+
48
+ const page = await ctx.newPage();
49
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
50
+ await page.waitForSelector('[data-vendor-letter-count-suffix]', { timeout: 15000 });
51
+ await page.waitForTimeout(400);
52
+
53
+ const probe = await page.evaluate(() => {
54
+ const suffix = document.querySelector('[data-vendor-letter-count-suffix]');
55
+ if (!suffix) return null;
56
+ const chip = suffix.closest('[data-vendor-letter]');
57
+ return {
58
+ chipClass: chip?.className ?? null,
59
+ suffixClass: suffix.className,
60
+ suffixText: suffix.textContent,
61
+ };
62
+ });
63
+
64
+ await browser.close();
65
+
66
+ const cc = probe?.chipClass || '';
67
+ const sc = probe?.suffixClass || '';
68
+ const results = {
69
+ // R417 chip parent gains `group`
70
+ chip_has_group: cc.includes('group') === true,
71
+ // R417 suffix gets opacity-70 + group-hover:opacity-100 + transition-opacity
72
+ suffix_opacity_70: sc.includes('opacity-70') === true,
73
+ suffix_group_hover_brighten: sc.includes('group-hover:opacity-100') === true,
74
+ suffix_transition_opacity: sc.includes('transition-opacity') === true,
75
+ // Pre-R417 invariants
76
+ suffix_text_gray_400: sc.includes('text-gray-400') === true,
77
+ suffix_tabular_nums: sc.includes('tabular-nums') === true,
78
+ suffix_text_format: /^:\d+$/.test(probe?.suffixText || ''),
79
+ chip_hover_translate: cc.includes('hover:-translate-y-px') === true,
80
+ chip_tabular_nums: cc.includes('tabular-nums') === true,
81
+ };
82
+ const ok = Object.values(results).every(Boolean);
83
+ console.log(`${ok ? '✅' : '❌'} vendor letter chip suffix group-hover-brighten:`, JSON.stringify(results),
84
+ '\n chipClass: ', cc,
85
+ '\n suffixClass:', sc,
86
+ '\n suffixText: ', probe?.suffixText);
87
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,114 @@
1
+ /* Round 352 verification: zoom-out + zoom-in icons gain group-hover:
2
+ * scale-110 — sibling to R350 reset hover-rotate. Pre-R352 hovering
3
+ * the zoom buttons only changed the bg (white/5); the icons stayed
4
+ * still. R352 lifts each icon 10 % on hover for a tactile "this
5
+ * button does something" cue. Pure-CSS via Tailwind `group` parent +
6
+ * `group-hover:scale-110` on the svg + `transition-transform
7
+ * duration-200 ease-out`. CSS-animation precedence keeps R186
8
+ * anet-chrome-pop owning transform during the 220 ms click pop;
9
+ * group-hover scale-110 picks up smoothly afterward.
10
+ *
11
+ * Contract:
12
+ * - Rest: both zoom icons computed transform 'matrix(1, 0, 0, 1, 0, 0)'
13
+ * (or 'none').
14
+ * - Hover zoom-out button: zoom-out icon transform matrix(1.1, 0, 0,
15
+ * 1.1, 0, 0).
16
+ * - Hover zoom-in button: zoom-in icon transform matrix(1.1, 0, 0,
17
+ * 1.1, 0, 0).
18
+ * - Inline transition on both icons contains 'transform'.
19
+ * - Pre-R352 invariants: data-topo-chrome-zoom-{out,in}-icon attrs
20
+ * intact, R288 strokeWidth=2.5 preserved, anet-chrome-pop class
21
+ * absent at rest.
22
+ */
23
+ import { chromium } from 'playwright';
24
+ import { readFileSync } from 'node:fs';
25
+
26
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
27
+ const browser = await chromium.launch({ headless: true });
28
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
29
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
30
+ await ctx.addInitScript(() => {
31
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
32
+ });
33
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
34
+ await ctx.route('**/api/hub/status*', async (route) => {
35
+ const r = await route.fetch();
36
+ const b = await r.json();
37
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
38
+ const mk = (alias) => ({
39
+ alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
40
+ network_id: nid, project_dir: null,
41
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
42
+ });
43
+ await route.fulfill({ response: r, json: { ...b, sessions: [ mk('a'), mk('b'), mk('c') ] } });
44
+ });
45
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
46
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
47
+
48
+ const page = await ctx.newPage();
49
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
50
+ await page.waitForSelector('[data-topo-chrome-zoom-out-icon]', { timeout: 15000 });
51
+ await page.waitForSelector('[data-topo-chrome-zoom-in-icon]', { timeout: 5000 });
52
+ await page.waitForTimeout(300);
53
+
54
+ // Tailwind 4 compiles scale-110 to the modern CSS `scale` property
55
+ // (not legacy `transform: scale()`), so we probe both — `transform`
56
+ // stays at identity matrix and `scale` carries the 1.1 value.
57
+ const restProbe = await page.evaluate(() => {
58
+ const oico = document.querySelector('[data-topo-chrome-zoom-out-icon]');
59
+ const iico = document.querySelector('[data-topo-chrome-zoom-in-icon]');
60
+ const ocs = oico ? getComputedStyle(oico) : null;
61
+ const ics = iico ? getComputedStyle(iico) : null;
62
+ return {
63
+ outScale: ocs?.scale ?? null,
64
+ outTransition: ocs?.transition ?? null,
65
+ outStrokeW: oico?.getAttribute('stroke-width') ?? null,
66
+ outClass: oico?.getAttribute('class') ?? null,
67
+ inScale: ics?.scale ?? null,
68
+ inTransition: ics?.transition ?? null,
69
+ inStrokeW: iico?.getAttribute('stroke-width') ?? null,
70
+ inClass: iico?.getAttribute('class') ?? null,
71
+ };
72
+ });
73
+
74
+ // Hover zoom-out button.
75
+ await page.hover('[data-topo-chrome-zoom-out]');
76
+ await page.waitForTimeout(300);
77
+ const zoomOutHover = await page.evaluate(() => {
78
+ const ico = document.querySelector('[data-topo-chrome-zoom-out-icon]');
79
+ return { scale: ico ? getComputedStyle(ico).scale : null };
80
+ });
81
+
82
+ // Hover zoom-in button.
83
+ await page.hover('[data-topo-chrome-zoom-in]');
84
+ await page.waitForTimeout(300);
85
+ const zoomInHover = await page.evaluate(() => {
86
+ const ico = document.querySelector('[data-topo-chrome-zoom-in-icon]');
87
+ return { scale: ico ? getComputedStyle(ico).scale : null };
88
+ });
89
+
90
+ await browser.close();
91
+
92
+ const isRestScale = (s) => s === 'none' || s === '1' || s === '1 1' || s === null;
93
+ const isHoverScale110 = (s) => s === '1.1' || s === '1.1 1.1';
94
+ const hasTrans = (s, prop) =>
95
+ new RegExp(`${prop}\\s+\\d*\\.?\\d*s|${prop}\\s+\\d+ms`, 'i').test(s || '');
96
+
97
+ const results = {
98
+ rest_out_scale_1: isRestScale(restProbe.outScale),
99
+ rest_in_scale_1: isRestScale(restProbe.inScale),
100
+ out_trans_has_scale: hasTrans(restProbe.outTransition, 'scale') || hasTrans(restProbe.outTransition, 'transform'),
101
+ in_trans_has_scale: hasTrans(restProbe.inTransition, 'scale') || hasTrans(restProbe.inTransition, 'transform'),
102
+ out_strokew_2_5: restProbe.outStrokeW === '2.5',
103
+ in_strokew_2_5: restProbe.inStrokeW === '2.5',
104
+ out_no_pop: !/anet-chrome-pop/.test(restProbe.outClass || ''),
105
+ in_no_pop: !/anet-chrome-pop/.test(restProbe.inClass || ''),
106
+ hover_out_scale_110: isHoverScale110(zoomOutHover.scale),
107
+ hover_in_scale_110: isHoverScale110(zoomInHover.scale),
108
+ };
109
+ const ok = Object.values(results).every(Boolean);
110
+ console.log(`${ok ? '✅' : '❌'} zoom icons hover-scale:`, JSON.stringify(results),
111
+ '\n rest: ', restProbe,
112
+ '\n hover zoom-out: ', zoomOutHover,
113
+ '\n hover zoom-in: ', zoomInHover);
114
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,95 @@
1
+ /* Round 420 verification: chrome zoom-level readout gains hover
2
+ * fontWeight 500 → 600 — sibling to R347 hover letter-spacing
3
+ * on the same element. Two-axis hover signature on the chrome
4
+ * strip's only data display.
5
+ *
6
+ * Contract:
7
+ * - At rest: computed fontWeight === '500'
8
+ * - On hover: computed fontWeight === '600' AND letterSpacing > 0
9
+ * (R347 invariant)
10
+ * - Pre-R420 invariants preserved:
11
+ * * className includes 'tabular-nums' + 'font-medium' + 'border-x'
12
+ * * inline style transition list includes 'font-weight'
13
+ * * data-topo-chrome-zoom-level-hover toggles 'false' → 'true'
14
+ */
15
+ import { chromium } from 'playwright';
16
+ import { readFileSync } from 'node:fs';
17
+
18
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
19
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
20
+
21
+ const browser = await chromium.launch({ headless: true });
22
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
23
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
24
+ await ctx.addInitScript(() => {
25
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
26
+ });
27
+ await ctx.route('**/api/hub/status*', async (route) => {
28
+ const r = await route.fetch();
29
+ const b = await r.json();
30
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
31
+ const mk = (alias) => ({
32
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
33
+ network_id: nid, project_dir: null,
34
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
35
+ });
36
+ await route.fulfill({ response: r, json: { ...b, sessions: [ mk('alpha'), mk('beta') ] } });
37
+ });
38
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
39
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
40
+
41
+ const page = await ctx.newPage();
42
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
43
+ await page.waitForSelector('[data-topo-chrome-zoom-level]', { timeout: 15000 });
44
+ await page.waitForTimeout(400);
45
+
46
+ const restProbe = await page.evaluate(() => {
47
+ const el = document.querySelector('[data-topo-chrome-zoom-level]');
48
+ if (!el) return null;
49
+ const cs = getComputedStyle(el);
50
+ return {
51
+ className: el.className,
52
+ fwComputed: cs.fontWeight,
53
+ lsComputed: cs.letterSpacing,
54
+ hoverAttr: el.getAttribute('data-topo-chrome-zoom-level-hover'),
55
+ transition: el.getAttribute('style') || '',
56
+ };
57
+ });
58
+
59
+ // Hover the zoom-level via DOM dispatch — onMouseEnter sets hoveredZoomLevel
60
+ await page.hover('[data-topo-chrome-zoom-level]');
61
+ await page.waitForTimeout(400);
62
+
63
+ const hoverProbe = await page.evaluate(() => {
64
+ const el = document.querySelector('[data-topo-chrome-zoom-level]');
65
+ if (!el) return null;
66
+ const cs = getComputedStyle(el);
67
+ return {
68
+ fwComputed: cs.fontWeight,
69
+ lsComputed: cs.letterSpacing,
70
+ hoverAttr: el.getAttribute('data-topo-chrome-zoom-level-hover'),
71
+ };
72
+ });
73
+
74
+ await browser.close();
75
+
76
+ const results = {
77
+ // Rest state
78
+ rest_fw_500: restProbe?.fwComputed === '500',
79
+ rest_ls_zero: restProbe?.lsComputed === 'normal' || restProbe?.lsComputed === '0px',
80
+ rest_hover_attr_false: restProbe?.hoverAttr === 'false',
81
+ rest_has_tabular_nums: restProbe?.className.includes('tabular-nums') === true,
82
+ rest_has_font_medium: restProbe?.className.includes('font-medium') === true,
83
+ rest_has_border_x: restProbe?.className.includes('border-x') === true,
84
+ // R420 transition includes font-weight
85
+ rest_transition_font_weight: restProbe?.transition.includes('font-weight') === true,
86
+ // Hover state: fw 600 + letterSpacing > 0
87
+ hover_fw_600: hoverProbe?.fwComputed === '600',
88
+ hover_ls_lifted: hoverProbe?.lsComputed === '0.5px',
89
+ hover_attr_true: hoverProbe?.hoverAttr === 'true',
90
+ };
91
+ const ok = Object.values(results).every(Boolean);
92
+ console.log(`${ok ? '✅' : '❌'} chrome zoom-level hover fw 500 → 600:`, JSON.stringify(results),
93
+ '\n rest: ', restProbe,
94
+ '\n hover:', hoverProbe);
95
+ 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.1-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]})]})]})]})}])}]);