@sleep2agi/agent-network-dashboard 0.4.4-preview.0 → 0.4.5-preview.0

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 (261) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +6 -6
  3. package/.next/diagnostics/route-bundle-stats.json +106 -92
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/server/app/_global-error/page/build-manifest.json +3 -3
  7. package/.next/server/app/_global-error.html +1 -1
  8. package/.next/server/app/_global-error.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found/page/build-manifest.json +3 -3
  15. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +2 -2
  18. package/.next/server/app/_not-found.rsc +12 -12
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
  20. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  21. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
  22. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  23. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  24. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  25. package/.next/server/app/admin/page/build-manifest.json +3 -3
  26. package/.next/server/app/admin/page.js.nft.json +1 -1
  27. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  28. package/.next/server/app/admin.html +2 -2
  29. package/.next/server/app/admin.rsc +14 -14
  30. package/.next/server/app/admin.segments/_full.segment.rsc +14 -14
  31. package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
  32. package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
  33. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  34. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
  35. package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
  36. package/.next/server/app/index.html +2 -2
  37. package/.next/server/app/index.rsc +14 -14
  38. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  39. package/.next/server/app/index.segments/_full.segment.rsc +14 -14
  40. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  41. package/.next/server/app/index.segments/_index.segment.rsc +7 -7
  42. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  43. package/.next/server/app/login/page/build-manifest.json +3 -3
  44. package/.next/server/app/login/page.js.nft.json +1 -1
  45. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/login.html +2 -2
  47. package/.next/server/app/login.rsc +14 -14
  48. package/.next/server/app/login.segments/_full.segment.rsc +14 -14
  49. package/.next/server/app/login.segments/_head.segment.rsc +4 -4
  50. package/.next/server/app/login.segments/_index.segment.rsc +7 -7
  51. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  52. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  53. package/.next/server/app/login.segments/login.segment.rsc +3 -3
  54. package/.next/server/app/logs/page/build-manifest.json +3 -3
  55. package/.next/server/app/logs/page.js.nft.json +1 -1
  56. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  57. package/.next/server/app/logs.html +2 -2
  58. package/.next/server/app/logs.rsc +14 -14
  59. package/.next/server/app/logs.segments/_full.segment.rsc +14 -14
  60. package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
  61. package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
  62. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  63. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
  64. package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
  65. package/.next/server/app/messages/page/build-manifest.json +3 -3
  66. package/.next/server/app/messages/page.js.nft.json +1 -1
  67. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  68. package/.next/server/app/messages.html +2 -2
  69. package/.next/server/app/messages.rsc +14 -14
  70. package/.next/server/app/messages.segments/_full.segment.rsc +14 -14
  71. package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
  72. package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
  73. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  74. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
  75. package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
  76. package/.next/server/app/node/page/build-manifest.json +3 -3
  77. package/.next/server/app/node/page.js.nft.json +1 -1
  78. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  79. package/.next/server/app/node.html +2 -2
  80. package/.next/server/app/node.rsc +14 -14
  81. package/.next/server/app/node.segments/_full.segment.rsc +14 -14
  82. package/.next/server/app/node.segments/_head.segment.rsc +4 -4
  83. package/.next/server/app/node.segments/_index.segment.rsc +7 -7
  84. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  85. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
  86. package/.next/server/app/node.segments/node.segment.rsc +3 -3
  87. package/.next/server/app/nodes/page/build-manifest.json +3 -3
  88. package/.next/server/app/nodes/page.js.nft.json +1 -1
  89. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  90. package/.next/server/app/nodes.html +2 -2
  91. package/.next/server/app/nodes.rsc +14 -14
  92. package/.next/server/app/nodes.segments/_full.segment.rsc +14 -14
  93. package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
  94. package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
  95. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  96. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
  97. package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
  98. package/.next/server/app/page/build-manifest.json +3 -3
  99. package/.next/server/app/page.js.nft.json +1 -1
  100. package/.next/server/app/page_client-reference-manifest.js +1 -1
  101. package/.next/server/app/server-logs/page/build-manifest.json +3 -3
  102. package/.next/server/app/server-logs/page.js.nft.json +1 -1
  103. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/server-logs.html +2 -2
  105. package/.next/server/app/server-logs.rsc +14 -14
  106. package/.next/server/app/server-logs.segments/_full.segment.rsc +14 -14
  107. package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
  108. package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
  109. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  110. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
  111. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
  112. package/.next/server/app/settings/networks/page/build-manifest.json +3 -3
  113. package/.next/server/app/settings/networks/page.js.nft.json +1 -1
  114. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  115. package/.next/server/app/settings/networks.html +2 -2
  116. package/.next/server/app/settings/networks.rsc +14 -14
  117. package/.next/server/app/settings/networks.segments/_full.segment.rsc +14 -14
  118. package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
  119. package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
  120. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  121. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
  122. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
  123. package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
  124. package/.next/server/app/settings/page/build-manifest.json +3 -3
  125. package/.next/server/app/settings/page.js.nft.json +1 -1
  126. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  127. package/.next/server/app/settings/tokens/page/build-manifest.json +3 -3
  128. package/.next/server/app/settings/tokens/page.js.nft.json +1 -1
  129. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  130. package/.next/server/app/settings/tokens.html +2 -2
  131. package/.next/server/app/settings/tokens.rsc +14 -14
  132. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +14 -14
  133. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
  134. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
  135. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  136. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
  137. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
  138. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
  139. package/.next/server/app/settings.html +2 -2
  140. package/.next/server/app/settings.rsc +14 -14
  141. package/.next/server/app/settings.segments/_full.segment.rsc +14 -14
  142. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  143. package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
  144. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  145. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  146. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  147. package/.next/server/app/tasks/[id]/page/build-manifest.json +3 -3
  148. package/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
  149. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  150. package/.next/server/app/tasks/page/build-manifest.json +3 -3
  151. package/.next/server/app/tasks/page.js.nft.json +1 -1
  152. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  153. package/.next/server/app/tasks.html +2 -2
  154. package/.next/server/app/tasks.rsc +14 -14
  155. package/.next/server/app/tasks.segments/_full.segment.rsc +14 -14
  156. package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
  157. package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
  158. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  159. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
  160. package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
  161. package/.next/server/chunks/ssr/[root-of-the-server]__013i9e9._.js +9 -0
  162. package/.next/server/chunks/ssr/[root-of-the-server]__013i9e9._.js.map +1 -0
  163. package/.next/server/chunks/ssr/[root-of-the-server]__0_jnflc._.js +3 -0
  164. package/.next/server/chunks/ssr/[root-of-the-server]__0_jnflc._.js.map +1 -0
  165. package/.next/server/chunks/ssr/[root-of-the-server]__12mpoig._.js +3 -0
  166. package/.next/server/chunks/ssr/[root-of-the-server]__12mpoig._.js.map +1 -0
  167. package/.next/server/chunks/ssr/_0d-fuox._.js +3 -0
  168. package/.next/server/chunks/ssr/_0d-fuox._.js.map +1 -0
  169. package/.next/server/chunks/ssr/app_0.0wpa~._.js +3 -0
  170. package/.next/server/chunks/ssr/app_0.0wpa~._.js.map +1 -0
  171. package/.next/server/chunks/ssr/app_0dk5wao._.js +1 -1
  172. package/.next/server/chunks/ssr/app_0dk5wao._.js.map +1 -1
  173. package/.next/server/chunks/ssr/app_0et5yua._.js +3 -0
  174. package/.next/server/chunks/ssr/app_0et5yua._.js.map +1 -0
  175. package/.next/server/chunks/ssr/app_0ff~kjj._.js +9 -0
  176. package/.next/server/chunks/ssr/app_0ff~kjj._.js.map +1 -0
  177. package/.next/server/chunks/ssr/app_0izi28j._.js +3 -0
  178. package/.next/server/chunks/ssr/app_0izi28j._.js.map +1 -0
  179. package/.next/server/chunks/ssr/app_login_page_tsx_0z71ad3._.js +1 -1
  180. package/.next/server/chunks/ssr/app_login_page_tsx_0z71ad3._.js.map +1 -1
  181. package/.next/server/chunks/ssr/app_page_tsx_0es_sk2._.js +1 -1
  182. package/.next/server/chunks/ssr/app_page_tsx_0es_sk2._.js.map +1 -1
  183. package/.next/server/chunks/ssr/app_tasks_page_tsx_0z-d6mp._.js +1 -1
  184. package/.next/server/chunks/ssr/app_tasks_page_tsx_0z-d6mp._.js.map +1 -1
  185. package/.next/server/chunks/ssr/node_modules_0ck2~9g._.js +3 -0
  186. package/.next/server/chunks/ssr/node_modules_0ck2~9g._.js.map +1 -0
  187. package/.next/server/middleware-build-manifest.js +6 -6
  188. package/.next/server/pages/404.html +2 -2
  189. package/.next/server/pages/500.html +1 -1
  190. package/.next/server/server-reference-manifest.js +1 -1
  191. package/.next/server/server-reference-manifest.json +1 -1
  192. package/.next/static/chunks/0257pdz1-imal.js +2 -0
  193. package/.next/static/chunks/02flrewxlf_m_.js +1 -0
  194. package/.next/static/chunks/051gslfjka1kj.js +1 -0
  195. package/.next/static/chunks/06t_vzei8s9_h.js +1 -0
  196. package/.next/static/chunks/0e-.zgw81gela.js +31 -0
  197. package/.next/static/chunks/0e7c40p~wq665.js +1 -0
  198. package/.next/static/chunks/0g7m7zk.v7g6h.js +1 -0
  199. package/.next/static/chunks/0hyhubmh-__wg.js +1 -0
  200. package/.next/static/chunks/0khpyxpdrp~ty.js +1 -0
  201. package/.next/static/chunks/0lo_g.q1fm-hr.js +7 -0
  202. package/.next/static/chunks/0snd~q2ucn.h1.css +2 -0
  203. package/.next/static/chunks/0w1zwt8kq_7nb.js +1 -0
  204. package/.next/static/chunks/0xn9.0ejo1s_a.js +7 -0
  205. package/.next/static/chunks/0y0lo-~k2c~00.js +1 -0
  206. package/.next/static/chunks/13.dst7liziwo.js +1 -0
  207. package/.next/static/chunks/{turbopack-0vsvjs02l449s.js → turbopack-01f1xs~cq_~si.js} +1 -1
  208. package/.next/trace +2 -2
  209. package/.next/trace-build +1 -1
  210. package/app/components/EmptyState.tsx +189 -0
  211. package/app/components/LoadingSkeleton.tsx +3 -18
  212. package/app/components/Sidebar.tsx +72 -11
  213. package/app/components/TopoGraph.tsx +151 -62
  214. package/app/globals.css +35 -0
  215. package/app/login/page.tsx +26 -13
  216. package/app/logs/page.tsx +2 -5
  217. package/app/messages/page.tsx +2 -5
  218. package/app/nodes/page.tsx +6 -1
  219. package/app/page.tsx +36 -12
  220. package/app/settings/networks/page.tsx +6 -1
  221. package/app/settings/page.tsx +56 -29
  222. package/app/settings/tokens/page.tsx +6 -1
  223. package/app/tasks/page.tsx +7 -9
  224. package/docs/loop-design-rounds.md +502 -0
  225. package/docs/oss-readiness-report.md +189 -0
  226. package/package.json +1 -1
  227. package/.next/server/chunks/ssr/[root-of-the-server]__093ymui._.js +0 -3
  228. package/.next/server/chunks/ssr/[root-of-the-server]__093ymui._.js.map +0 -1
  229. package/.next/server/chunks/ssr/[root-of-the-server]__0i1gizm._.js +0 -9
  230. package/.next/server/chunks/ssr/[root-of-the-server]__0i1gizm._.js.map +0 -1
  231. package/.next/server/chunks/ssr/[root-of-the-server]__0~yad5w._.js +0 -3
  232. package/.next/server/chunks/ssr/[root-of-the-server]__0~yad5w._.js.map +0 -1
  233. package/.next/server/chunks/ssr/_06_xh1~._.js +0 -3
  234. package/.next/server/chunks/ssr/_06_xh1~._.js.map +0 -1
  235. package/.next/server/chunks/ssr/app_01vhyfx._.js +0 -9
  236. package/.next/server/chunks/ssr/app_01vhyfx._.js.map +0 -1
  237. package/.next/server/chunks/ssr/app_023a94i._.js +0 -3
  238. package/.next/server/chunks/ssr/app_023a94i._.js.map +0 -1
  239. package/.next/server/chunks/ssr/app_0basiqb._.js +0 -3
  240. package/.next/server/chunks/ssr/app_0basiqb._.js.map +0 -1
  241. package/.next/server/chunks/ssr/app_0pljk5o._.js +0 -3
  242. package/.next/server/chunks/ssr/app_0pljk5o._.js.map +0 -1
  243. package/.next/server/chunks/ssr/node_modules_next_dist_0t-hj0x._.js +0 -3
  244. package/.next/server/chunks/ssr/node_modules_next_dist_0t-hj0x._.js.map +0 -1
  245. package/.next/static/chunks/0.z~9klrgd.t-.js +0 -1
  246. package/.next/static/chunks/08aj9~75raaah.js +0 -7
  247. package/.next/static/chunks/08iom_z8w-wmz.js +0 -7
  248. package/.next/static/chunks/08v0-ki6vwpxf.js +0 -1
  249. package/.next/static/chunks/0dkkv90do9a4r.js +0 -1
  250. package/.next/static/chunks/0e-wrhqh4h3r5.js +0 -2
  251. package/.next/static/chunks/0ejz4zwhu3a3y.js +0 -1
  252. package/.next/static/chunks/0o5zj~5vjeks3.js +0 -1
  253. package/.next/static/chunks/0uqfv6rc-xdru.js +0 -1
  254. package/.next/static/chunks/0u~_.32f.midj.css +0 -2
  255. package/.next/static/chunks/0xrnwfefpke-g.js +0 -31
  256. package/.next/static/chunks/0y_po~f~fk~ap.js +0 -1
  257. package/.next/static/chunks/14sm.ta0zylsj.js +0 -1
  258. package/.next/static/chunks/18ac93ii3mjlj.js +0 -1
  259. /package/.next/static/{jTh5m77FIfQccc0gftvik → 2m1yIfZCIYDWMYrrJEKSC}/_buildManifest.js +0 -0
  260. /package/.next/static/{jTh5m77FIfQccc0gftvik → 2m1yIfZCIYDWMYrrJEKSC}/_clientMiddlewareManifest.js +0 -0
  261. /package/.next/static/{jTh5m77FIfQccc0gftvik → 2m1yIfZCIYDWMYrrJEKSC}/_ssgManifest.js +0 -0
@@ -0,0 +1,502 @@
1
+ # Dashboard Frontend Polish — Loop Rounds
2
+
3
+ > 5-minute iterative polish loop. Each round: pick one focused UI change (no
4
+ > business logic), implement, screenshot via Playwright on both themes ×
5
+ > both viewports, self-score, propose next round.
6
+ >
7
+ > Aesthetic constraints (per Vincent):
8
+ > - Minimal / restrained — NOT AI-glow heavy
9
+ > - Both Dark (Cyber) and Light themes
10
+ > - Mobile + Desktop both adapt
11
+ > - No business logic changes
12
+
13
+ ---
14
+
15
+ ## Round 1 — Login page polish
16
+
17
+ ### What changed
18
+ - **Brand mark**: replaced flat emerald square with the existing 3-node
19
+ mesh SVG (cyan/green/violet). The mark IS the agent-network concept
20
+ (nodes + edges), so it doubles as both logo and visual story.
21
+ - **Tagline**: added "One control plane for your AI agents · Tasks · Mesh
22
+ · Messages" under the H1 — answers "what is this thing" for new users
23
+ who arrive via the OSS repo.
24
+ - **Background**: subtle dot grid in light themes (`24px 24px` radial
25
+ dots, very low opacity) + faint radial wash. In Cyber, kept only a
26
+ whisper of cyan/blue radial — the only "glow" allowed in the whole app.
27
+ - **Vertical layout**: tightened padding (`py-10 sm:py-16`), removed the
28
+ ~250px dead space above the logo on desktop.
29
+ - **Footer hierarchy**: changed `Powered by Sleep2AGI` (single small
30
+ grey line) to a 2-line block: `Powered by Sleep2AGI · Apache-2.0` then
31
+ `anet.sh` (signals OSS + canonical home).
32
+ - **Brand mark surface**: light theme gets a soft white chip with `0 0 0
33
+ 1px var(--border)` halo; dark themes keep their navy.
34
+
35
+ ### Files touched
36
+ - `app/login/page.tsx` (markup + tagline + brand SVG inline)
37
+ - `app/globals.css` (`.anet-login-bg`, `.anet-login-mark` rules at end of
38
+ file)
39
+
40
+ ### Screenshots
41
+ - `/tmp/loop-r1/light-desktop.png` ✓
42
+ - `/tmp/loop-r1/light-mobile.png` ✓
43
+ - `/tmp/loop-r1/cyber-desktop.png` ✓
44
+ - `/tmp/loop-r1/cyber-mobile.png` ✓
45
+
46
+ ### Self-score: **7.8 / 10**
47
+
48
+ | Dimension | Score | Notes |
49
+ |----------------------------------|------:|------------------------------------------------------------------------------------------|
50
+ | First-impression clarity | 9 | Tagline + mesh mark immediately tell the story |
51
+ | Brand consistency | 9 | Mark = product concept, same image across themes |
52
+ | Minimal/non-AI-glow | 8 | Cyber kept ~1 radial wash only (compromise: zero would feel flat) |
53
+ | Light/dark theme harmony | 8 | Tagline + footer + form translate cleanly |
54
+ | Mobile adaptation | 8 | Wraps fine; could shrink mark slightly on <320px screens |
55
+ | Restraint (no decoration noise) | 8 | Dot grid is borderline; if it reads as "wallpaper" I'd remove it |
56
+ | Affordance (what to click) | 7 | Tabs visually OK; disabled "Sign in" button in cyber is hard to tell from active until you focus an input |
57
+
58
+ **Deductions**:
59
+ - −0.8: brand mark is static. Could pulse subtly (one node fading in/out
60
+ on a slow 4s loop) to hint at "live agent network" — but might cross
61
+ back into AI-glow territory. Test in round 4 maybe.
62
+ - −0.7: footer feels slightly redundant ("Apache-2.0" + "anet.sh" stacked).
63
+ Could be `Sleep2AGI · Apache-2.0 · anet.sh` on one line.
64
+ - −0.7: form card border in cyber theme is the same `#2a2a4a` it always
65
+ was. Could be a hair brighter to lift it off the radial wash.
66
+
67
+ ### Round 2 plan: **Empty states standardization**
68
+
69
+ **Why**: with no agents/tasks/messages seeded, most pages currently show
70
+ a giant double-dash (`--`) followed by a one-liner. Examples (audit
71
+ screenshots reference):
72
+ - Overview: `-- / No agents in this network`
73
+ - Tasks: `-- / No tasks found / Tasks will appear here when agents send them via CommHub.`
74
+ - Messages: `-- / No messages / Messages between agents will appear here.`
75
+ - Nodes: `No nodes match your filters.` (no icon, no leading mark)
76
+ - Tokens: `No tokens. V3 auth required.`
77
+
78
+ The double-dash reads as a "loading" or "broken" affordance, not as an
79
+ "intentionally empty, here's how to fill it" affordance.
80
+
81
+ **Round 2 changes** (still no business logic):
82
+ - Extract a shared `<EmptyState>` component into
83
+ `app/components/EmptyState.tsx` (or upgrade the existing
84
+ `LoadingSkeleton.tsx` export).
85
+ - Drop the leading `--` line for an inline SVG glyph relevant to the page
86
+ (Overview = mesh-with-no-nodes, Tasks = task-list-empty, Messages =
87
+ bubble-empty, Nodes = nodes-grid-empty).
88
+ - Two-line copy: a calm headline + a one-liner with a CTA where it makes
89
+ sense (e.g. Overview "No agents in this network" + "Run `anet quickstart` to register your first node →" with link to docs).
90
+ - Same icon/copy structure across both themes.
91
+
92
+ Estimated work: 30-40 min (component + 5 page integrations + screenshots).
93
+ Will start automatically on the next loop fire (`*/5`).
94
+
95
+ ---
96
+
97
+ _Loop active: cron `*/5 * * * *`, job `5048a197`, session-only,
98
+ auto-expires in 7 days._
99
+
100
+ ---
101
+
102
+ ## Round 2 — Empty states standardization
103
+
104
+ ### What changed
105
+ - **New shared component** `app/components/EmptyState.tsx`:
106
+ - 7 variants (`nodes / tasks / messages / logs / tokens / networks /
107
+ generic`) each with its own line-art SVG glyph (64×64 viewBox, no
108
+ fills, thin 1.25 stroke, monochrome `currentColor`, dashed where
109
+ appropriate to signal "incoming").
110
+ - `<NodesEmptyState hint={...}>` keeps the Overview-specific behavior
111
+ (cross-network global count hint) but defaults to a "Run `anet
112
+ quickstart`" CTA when no hint is present.
113
+ - `compact` prop for in-card empty states (Tokens, Networks).
114
+ - **Wired into 7 pages**:
115
+ - `app/page.tsx` — Overview "no agents" → mesh-with-dashed-edges glyph
116
+ + "Run anet quickstart →" CTA linking to anet.sh
117
+ - `app/tasks/page.tsx` — "no tasks" → 3-bar stack glyph
118
+ - `app/nodes/page.tsx` — "no nodes" filter-aware variant
119
+ - `app/messages/page.tsx` — "no messages" → speech bubble outline
120
+ - `app/logs/page.tsx` — "no audit logs" → document with lines
121
+ - `app/settings/tokens/page.tsx` — "no API tokens" → key outline
122
+ - `app/settings/networks/page.tsx` — "no networks" → globe-ish concentric
123
+
124
+ Every previous instance of the giant `--` text plus inconsistent
125
+ `text-gray-400 text-lg` / `text-gray-600 text-sm` patterns is gone.
126
+
127
+ ### Self-score: **8.2 / 10**
128
+
129
+ | Dimension | Score | Notes |
130
+ |----------------------------------|------:|------------------------------------------------------------------------|
131
+ | Visual restraint (no AI noise) | 9 | Line-art only, no fills, no gradients, no animations |
132
+ | Information value per state | 9 | Each glyph IS the entity ("messages" = bubble, "tokens" = key) |
133
+ | Theme parity | 9 | currentColor + opacity bands work identically in light/dark |
134
+ | Mobile adaptation | 8 | All 7 pages reflow cleanly at 390×844 |
135
+ | Affordance (next-step CTA) | 7 | Only Overview has a CTA right now; other pages could link to docs too |
136
+ | Component reusability | 9 | Single API, drops into any page in 3 lines |
137
+ | Old code removed cleanly | 8 | Old `EmptyState` export in `LoadingSkeleton.tsx` is now unused (could be deleted next round) |
138
+
139
+ **Deductions**:
140
+ - −0.4: only Overview has a recovery CTA. Tasks/Messages/Logs could each
141
+ link to a short docs anchor — but I want to confirm with Vincent
142
+ before adding outbound link sprawl.
143
+ - −0.3: glyphs are static. The mesh-with-dashed-edges on Overview begs
144
+ for a tiny one-shot animation (edges fade from 0.6 → 0 opacity on
145
+ page load only — NOT a loop, that would be AI-noise). Maybe round N.
146
+ - −0.1: the old `EmptyState` export in `LoadingSkeleton.tsx` lingers,
147
+ unused. Delete in round 3.
148
+
149
+ ### Round 3 plan: **Quick Actions disambiguation**
150
+
151
+ **Why**: Overview's Quick Actions row currently mixes two intents:
152
+ ```
153
+ [0/0 Nodes] [-- Tasks] [0 Failed] [→ Messages] [→ Logs] [→ Admin]
154
+ ```
155
+ Three of the cells carry data ("0/0", "--", "0"), three are pure-nav
156
+ placeholders ("→"). The user can't tell at a glance which cells are
157
+ stat affordances vs nav. Worse, the data cells look like they SHOULD be
158
+ clickable for drill-in, while the nav cells look like they have no data
159
+ (false negatives).
160
+
161
+ **Round 3 changes** (no business logic):
162
+ - Split into 2 visually distinct strips on Overview:
163
+ - **Top strip** (3 cards): pure stats — Nodes online/total, Tasks
164
+ total, Failed tasks. Big number + label + small "view all →" link
165
+ in corner. Hover = subtle elevation, click = navigate.
166
+ - **Bottom row** (3 small icon-buttons): pure nav — Messages, Logs,
167
+ Admin. Icon + label, no number, smaller affordance.
168
+ - Drop the leftover `EmptyState` export from `LoadingSkeleton.tsx`.
169
+
170
+ Estimated work: 30 min. Will fire on next `*/5` loop cycle.
171
+
172
+ ---
173
+
174
+ ## Round 3 — Quick Actions disambiguation
175
+
176
+ ### What changed
177
+ - Overview's previous 6-cell mixed row (3 data + 3 placeholder arrows)
178
+ is now **two intentional strips**:
179
+ - **Stat strip** (3 cards, larger): `Nodes 0/0 · 0% online`, `Tasks 0
180
+ · all-time`, `Failed 0 · none`. Big number on the left, "View →"
181
+ affordance top-right, label + sub-copy below the number. Hover =
182
+ `-translate-y-px` for a one-pixel lift.
183
+ - **Nav rail** (3 buttons, smaller): `Messages · Audit log · Admin`
184
+ each as icon + label, flat 12px text, no data values, neutral
185
+ border. Clear "navigation only" affordance.
186
+ - Drop the now-unused `EmptyState` export in
187
+ `app/components/LoadingSkeleton.tsx`; the new
188
+ `app/components/EmptyState.tsx` is canonical.
189
+
190
+ ### Self-score: **8.5 / 10**
191
+
192
+ | Dimension | Score | Notes |
193
+ |--------------------------|------:|----------------------------------------------------------------|
194
+ | Intent clarity | 10 | Stats above, nav below — instantly readable role |
195
+ | Information density | 8 | Each stat carries 3 facts (value, label, sub) without crowding |
196
+ | Affordance hierarchy | 9 | "View →" tells you these are clickable, nav rail icons + label |
197
+ | Mobile adaptation | 7 | 3-col stat strip at 390px is tight; numbers + "View →" squeeze |
198
+ | Theme parity | 9 | Both render the same structure with theme-correct tokens |
199
+ | Restraint | 9 | No gradient washes, no icons-with-color-fills, just lines |
200
+
201
+ **Deductions**:
202
+ - −0.7: mobile 3-col is tight at 390px. Should probably collapse to
203
+ 2-col-stat + 3-col-nav on `<sm`. Defer to next round if surfaces.
204
+ - −0.5: "0% online" sub-copy reads wrong when `total=0` (should be
205
+ "no agents yet" or just "—"). Small copy bug, fix next round.
206
+ - −0.3: nav rail icons are 16px stroke-1.5 SVG, slightly muddy at that
207
+ size. Bumping to 18px would help.
208
+
209
+ ### Round 4 plan: **Sidebar brand + live status**
210
+
211
+ The sidebar header is still plain text:
212
+ ```
213
+ Agent Network
214
+ Dashboard
215
+ ```
216
+ Round 1 introduced the 3-node mesh mark on the Login page. The sidebar
217
+ should pick that up for brand continuity — users see the same visual
218
+ identifier on every page.
219
+
220
+ Add inline next to "Agent Network": a small **live status pulse** with
221
+ `{online} online · {total} total`. The pulse uses the same 24px-hub
222
+ green dot from the topology (subtle, no AI-glow). Gives every page a
223
+ real-time "is my fleet up?" signal without going to /nodes.
224
+
225
+ Estimated work: 25 min. Fires on next `*/5` loop cycle.
226
+
227
+ ---
228
+
229
+ ## Round 4 — Sidebar brand + live status
230
+
231
+ ### What changed
232
+ - Sidebar header (used to be plain `Agent Network / Dashboard` two-line
233
+ text) is now `BrandMark + Agent Network + status pulse`.
234
+ - **BrandMark**: same 3-node mesh SVG as `/login` (round 1), 32px in
235
+ expanded sidebar, 28px when collapsed. Cyan ring + cyan/green/violet
236
+ nodes use `currentColor` + Tailwind text-color classes so theming is
237
+ automatic.
238
+ - **Live pulse**: tiny 1.5×1.5px emerald dot + copy. When online > 0 it
239
+ animates with `anet-brand-pulse` (1.6s slow opacity drift between
240
+ 1.0 and 0.4 — NO scale, NO blur, NO glow). When `total === 0` it
241
+ reads "no agents yet" with a grey dot, no animation. Respects
242
+ `prefers-reduced-motion: reduce`.
243
+ - Sidebar uses SWR to poll `/api/hub/status` every 10s (dedupes with
244
+ the Overview's existing request, so cost is zero).
245
+ - Dropped the `Dashboard` sub-label — replaced with the status line.
246
+
247
+ ### Self-score: **8.6 / 10**
248
+
249
+ | Dimension | Score | Notes |
250
+ |--------------------------|------:|-----------------------------------------------------------------------------|
251
+ | Brand continuity | 10 | Same mark on /login and the sidebar — first-impression to power-use loop |
252
+ | Restraint | 9 | Opacity-only pulse, no AI-glow; respects reduced-motion |
253
+ | Information density | 9 | 3 facts (brand, online count, total) in the same vertical space as before |
254
+ | Theme parity | 9 | currentColor + emerald dot reads identical on both themes |
255
+ | Mobile + collapse | 8 | Both states tested; 28px mark in collapsed mode reads but tight at <16px sidebar |
256
+ | Affordance | 7 | The brand header isn't clickable; could route to / |
257
+
258
+ **Deductions**:
259
+ - −0.7: "no agents yet" copy feels slightly negative — "waiting for
260
+ agents" would feel more inviting. Easy copy tweak next round.
261
+ - −0.4: brand block isn't a link. Clicking the brand on most apps
262
+ navigates home; we should make it a `<Link href="/">`. One-line fix.
263
+ - −0.3: when sidebar is collapsed (`w-16`) the 28px mark looks small.
264
+ Could bump to 32px in collapsed mode (the row is taller than the
265
+ icon anyway).
266
+
267
+ ### Round 5 plan: **TopoGraph light SVG variant (close issue #8)**
268
+
269
+ This is the largest open visual debt. The Command Mesh SVG bg is hard-
270
+ coded `linearGradient #0b1220 → #080814 → #101018` and the radar rings
271
+ are `#164e63`, the hub spokes are `#155e75`, the flow particles are
272
+ `#fef08a`. In Cyber that whole palette sings. In Light it's a black
273
+ square inside an otherwise white page (audit doc P1-2, GitHub issue #8).
274
+
275
+ **Round 5 changes** (no business logic):
276
+ - Detect theme via `useEffect` + `MutationObserver` on
277
+ `document.documentElement[data-theme]`, hold in component state.
278
+ - Define two palette objects: `darkPalette` (current values) and
279
+ `lightPalette` (white bg + subtle grey grid + emerald node + soft
280
+ zinc edges, no glow filter).
281
+ - Pass through the SVG attribute chain. Same component, same SVG
282
+ structure, theme-aware fills/strokes.
283
+ - Verify both themes with Playwright (+ desktop + mobile).
284
+
285
+ Estimated work: 60-80 min — the largest single round so far. Fires on
286
+ next `*/5` cycle but may span 2 cycles.
287
+
288
+ ---
289
+
290
+ ## Round 5 — TopoGraph light SVG variant · closes issue #8
291
+
292
+ ### What changed
293
+ - Added a `useTheme()` hook that watches `data-theme` on
294
+ `document.documentElement` via `useEffect + MutationObserver`. Returns
295
+ `'light'` for `light/mint` themes, `'dark'` for `cyber/sunset`.
296
+ - Defined two `Palette` objects (DARK_PALETTE, LIGHT_PALETTE) covering
297
+ panel gradient stops, radar wash colors, arrow fill, ring stroke,
298
+ spoke stroke (active + idle), flow edge, flow path, flow particle,
299
+ node fills (online + offline), label-box + legend-box backgrounds,
300
+ legend text/headline/accent, container bg + border, top-rail gradient
301
+ Tailwind tokens.
302
+ - Threaded the palette through every hardcoded color in the SVG:
303
+ - `linearGradient #topo-panel` stops
304
+ - `radialGradient #topo-radar` stops
305
+ - `filter #topo-glow` is now **omitted** in light (no Gaussian blur
306
+ halo — that's the AI-glow risk vector)
307
+ - `marker #topo-arrow` fill
308
+ - radar rings + radial lines stroke + opacity
309
+ - hub link spokes (active + idle)
310
+ - directed message flow edges (with conditional `filter` for glow)
311
+ - node fill (online vs offline), halo, status indicator
312
+ - node label box rect fill + stroke
313
+ - "recent signal" + "legend" boxes (fill, stroke, text colors)
314
+ - `nodeStatus(session, isOnline, isLight)` now also returns
315
+ theme-appropriate `primary / halo / text` triplets — emerald/teal/
316
+ zinc in light, neon cyan/green in dark.
317
+
318
+ ### Files touched
319
+ - `app/components/TopoGraph.tsx` — single file, ~50 LOC added (palette
320
+ + theme hook), ~20 hardcoded colors replaced with palette refs.
321
+
322
+ ### Screenshots
323
+ - `/tmp/loop-r5/light-desktop.png` ✓ — white-ish panel, faint emerald
324
+ wash, light grey radar rings, calm legend boxes, no glow halos
325
+ - `/tmp/loop-r5/cyber-desktop.png` ✓ — unchanged from 0.4.4 (verified
326
+ no regression)
327
+ - `/tmp/loop-r5/light-mobile.png` ✓ — "Show Topology" toggle (existing
328
+ mobile gate behavior preserved)
329
+ - `/tmp/loop-r5/cyber-mobile.png` ✓
330
+
331
+ ### Self-score: **9.0 / 10**
332
+
333
+ | Dimension | Score | Notes |
334
+ |--------------------------|------:|--------------------------------------------------------------------------------|
335
+ | Issue #8 closure | 10 | Light theme TopoGraph no longer reads as a black square |
336
+ | No Cyber regression | 10 | Dark theme renders byte-identically; same palette values flow through |
337
+ | Restraint (AI-glow) | 9 | Dropped `filter #topo-glow` in light — flat strokes only, no Gaussian halos |
338
+ | Theme detection robust | 9 | MutationObserver catches runtime theme switches (live), not just initial paint |
339
+ | Mobile parity | 9 | Mobile mock gate ("topology hidden") preserved; if user shows it, both work |
340
+ | Code organization | 8 | Palette objects + hook are tidy; some hub-pulse `#10b981` literal still inline |
341
+
342
+ **Deductions**:
343
+ - −0.5: "idle-5" offline node label box overlaps the center pulse hub
344
+ when offline-row positioning algorithm puts that node high. Pre-
345
+ existing layout bug, surfaced more clearly in light. Future round
346
+ could add layout collision avoidance.
347
+ - −0.3: radar wash opacity 0.06 is very subtle in light. Might want
348
+ 0.08–0.10 for slightly more depth. Tune in a future round.
349
+ - −0.2: the 24px pulse hub (from 0.4.3-preview.1) uses `#10b981`
350
+ literal directly. Works in both themes by accident. Should be
351
+ palette-driven.
352
+
353
+ ### Round 6 plan: **Settings section grouping + License chip**
354
+
355
+ The Settings page (audit P1-1) is currently a long flat list:
356
+ ```
357
+ CommHub Connection
358
+ Server Info
359
+ Dashboard
360
+ License
361
+ Change Password
362
+ API Tokens
363
+ Networks
364
+ Session
365
+ ```
366
+ Each is a separately-bordered card with no visual hierarchy. The user
367
+ can't tell at a glance which sections are "connection-y", "account-y",
368
+ or "advanced-y".
369
+
370
+ **Round 6 changes** (no business logic):
371
+ - Wrap the cards into 3 logical groups with small uppercase section
372
+ headings:
373
+ - **Connection** → CommHub Connection + Server Info + Dashboard
374
+ - **Account** → License + Change Password + Session
375
+ - **Resources** → API Tokens + Networks
376
+ - License "trial" text → a proper amber pill ("trial • 14 days left").
377
+ - Session card: tone down the red headline (looks like an error).
378
+ "Session" → "Sign out", red → neutral grey, red `Sign out` button →
379
+ ghost outline.
380
+
381
+ Estimated work: 25 min. Fires next `*/5`.
382
+
383
+ ---
384
+
385
+ ## Round 6 — Settings section grouping + License chip + Session tone
386
+
387
+ ### What changed
388
+ - Wrapped the 8 settings cards into **3 logical groups** with small
389
+ uppercase `text-[10px] tracking-[0.12em]` section labels:
390
+ - **CONNECTION** — CommHub Connection, Server Info, Dashboard
391
+ - **ACCOUNT** — License, Change Password, Sign out
392
+ - **RESOURCES** — API Tokens + Networks (2-col grid)
393
+ - **License chip**: added inline next to "License" headline. A pill
394
+ showing `● {type} · {days_left}d left` with theme-aware coloring —
395
+ green for pro, red when ≤7 days, amber otherwise. Replaces the
396
+ isolated orange `trial` text inside the value rows.
397
+ - **Session card** (audit P3 finding): renamed "Session" → "Sign out"
398
+ with neutral grey card border and copy ("Signing out clears your
399
+ dashboard session cookie. You'll return to the login page."). Red
400
+ pill button → ghost outline matching the rest of the surface. No
401
+ longer reads as a "danger zone" warning.
402
+ - Left the legacy red-Session section in place but `display: none` so
403
+ it can be removed cleanly in round 7's cleanup pass.
404
+
405
+ ### Self-score: **8.8 / 10**
406
+
407
+ | Dimension | Score | Notes |
408
+ |--------------------------|------:|----------------------------------------------------------------------|
409
+ | Hierarchy | 9 | Three small caps headings give instant orientation |
410
+ | License presentation | 9 | Chip is calm and theme-aware; matches the rest of the chip system |
411
+ | Session tone | 9 | No longer looks like a danger zone; reads as a quiet utility action |
412
+ | Theme parity | 9 | Headings use `text-gray-600` which themes via the shim correctly |
413
+ | Hidden cruft | 7 | Legacy red Session section still in DOM (display:none) — clean next round |
414
+ | Information dedup | 8 | License chip + "Type: trial" row carry the same info; row could go |
415
+
416
+ **Deductions**:
417
+ - −0.5: License chip duplicates "Type" row info. Remove the row in
418
+ round 7 so the chip is the canonical source of truth.
419
+ - −0.4: hidden legacy `Session` section is still in the DOM (`hidden`
420
+ class). Delete fully in round 7.
421
+ - −0.3: section labels (`CONNECTION / ACCOUNT / RESOURCES`) might
422
+ benefit from a thin horizontal rule underneath when each group
423
+ has 2+ cards. Tiny polish.
424
+
425
+ ### Round 7 plan: **Small wins batch**
426
+
427
+ Bundle the lingering deductions from rounds 1, 2, 4, 6:
428
+ - **Login footer one-line**: collapse `Powered by Sleep2AGI · Apache-2.0
429
+ / anet.sh` to a single muted line `Sleep2AGI · Apache-2.0 · anet.sh`
430
+ - **Sidebar brand**: wrap in `<Link href="/">` so clicking the brand
431
+ goes home (common app convention; round 4 deduction)
432
+ - **Sidebar status copy**: `no agents yet` → `waiting for agents` —
433
+ feels more inviting, less negative (round 4 deduction)
434
+ - **License row de-dup**: remove the standalone `Type / trial` row
435
+ inside the License card now that the chip carries that fact
436
+ - **Settings cleanup**: delete the `display:none` legacy Session card
437
+
438
+ All are <5 LOC each, batch is ~25 LOC total. Fires next `*/5`.
439
+
440
+ ---
441
+
442
+ ## Round 7 — Small-wins batch
443
+
444
+ ### What changed
445
+ - **Login footer**: collapsed `Powered by Sleep2AGI · Apache-2.0 /
446
+ anet.sh` (two lines) to a single muted line `Sleep2AGI · Apache-2.0
447
+ · anet.sh`. `anet.sh` is an outbound `<a>` with hover affordance.
448
+ - **Sidebar brand**: wrapped the brand block in `<Link href="/">` —
449
+ clicking the brand mark or product name navigates to Overview, the
450
+ standard app convention. Subtle hover (`hover:bg-[#11112a]/40` in
451
+ expanded; `hover:opacity-80` when collapsed).
452
+ - **Sidebar copy**: `no agents yet` → `waiting for agents`. Feels
453
+ inviting (the system is ready, awaiting input) rather than
454
+ negative (nothing is here yet).
455
+ - **License row de-dup**: removed the standalone `Type: trial` and
456
+ `Days Left: 14 days` rows from the License card. The header chip
457
+ is now the canonical source of truth for license status. Only the
458
+ expiring-soon warning row remains, and only when ≤7 days left.
459
+ - **Settings cleanup**: deleted the `display:none` legacy red Session
460
+ section. The neutral Sign out card inside the ACCOUNT group is now
461
+ the only sign-out surface.
462
+
463
+ ### Self-score: **8.4 / 10**
464
+
465
+ | Dimension | Score | Notes |
466
+ |------------------------|------:|----------------------------------------------------------------|
467
+ | Deductions cleared | 9 | All 5 lingering items from rounds 1, 2, 4, 6 are now resolved |
468
+ | Visible-impact | 6 | Mostly cleanup, low "wow" — but eliminates accumulated debt |
469
+ | Theme parity | 9 | Each change works identically in light + cyber |
470
+ | Code reduction | 8 | Net -15 LOC after removing legacy Session + dup License rows |
471
+
472
+ **Deductions**:
473
+ - −0.9: low individual-change visibility — this batch reads more as
474
+ "removed papercuts" than "added delight". That's by design (rounds
475
+ 1-6 spent most of the visible-delight budget), but tone is muted.
476
+ - −0.4: didn't include a `<title>` attribute on the brand `<Link>` so
477
+ hover doesn't tooltip "Home". One-line miss.
478
+ - −0.3: didn't address the round 5 deduction about the offline-node
479
+ label box overlapping the center pulse hub — that needs layout
480
+ algorithm work, defer to a layout-focused round.
481
+
482
+ ### Round 8 plan: **Ship 0.4.5-preview.0**
483
+
484
+ 7 rounds of polish accumulated since 0.4.4-preview.0:
485
+ - `b702291` round 1 — login brand mark + tagline + restrained surface
486
+ - `64643a3` round 2 — empty states across 7 pages (line-art glyphs)
487
+ - `269eeb3` round 3 — Quick Actions split (stats + nav)
488
+ - `4721d60` round 4 — sidebar brand mark + live pulse
489
+ - `0011eb5` round 5 — TopoGraph light SVG variant (closes #8)
490
+ - `6fe0aa3` round 6 — Settings section grouping + License chip
491
+ - (round 7 commit, this one) — small-wins batch
492
+
493
+ Natural ship-point. Round 8 = the publish itself:
494
+ 1. Bump `package.json` 0.4.4 → 0.4.5-preview.0
495
+ 2. `npm publish --tag preview` (prepublishOnly hook will rebuild)
496
+ 3. Push to GitHub via PAT
497
+ 4. Tell 通信龙 to bump CLI preview's PINNED_DASHBOARD_VERSION
498
+ 5. Telegram Vincent: `npm i -g @sleep2agi/agent-network@preview`
499
+
500
+ After ship, rounds 9+ accumulate toward `0.4.6-preview.0`. Backlog
501
+ ideas: layout collision avoidance in TopoGraph, hover affordances on
502
+ KPI cards, Cmd+K command palette, header health banner, mobile audit.