auramaxx 0.0.17 → 0.0.19

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 (296) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +70 -70
  3. package/.next/app-path-routes-manifest.json +2 -2
  4. package/.next/build-manifest.json +5 -5
  5. package/.next/prerender-manifest.json +30 -30
  6. package/.next/react-loadable-manifest.json +16 -16
  7. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/_not-found.html +1 -1
  10. package/.next/server/app/_not-found.rsc +5 -5
  11. package/.next/server/app/api/[...doc]/page.js.nft.json +1 -1
  12. package/.next/server/app/api/[...doc]/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/agent-requests/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/apps/install/route.js.nft.json +1 -1
  15. package/.next/server/app/api/apps/install/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/apps/manifests/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/apps/static/[...path]/route_client-reference-manifest.js +1 -1
  18. package/.next/server/app/api/docs/plain/route.js.nft.json +1 -1
  19. package/.next/server/app/api/docs/plain/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/import-from-openclaw/[channel]/route.js.nft.json +1 -1
  22. package/.next/server/app/api/import-from-openclaw/[channel]/route_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/import-from-openclaw/route.js.nft.json +1 -1
  24. package/.next/server/app/api/import-from-openclaw/route_client-reference-manifest.js +1 -1
  25. package/.next/server/app/api/import-from-openclaw/validate/[channel]/route.js.nft.json +1 -1
  26. package/.next/server/app/api/import-from-openclaw/validate/[channel]/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/page.js.nft.json +1 -1
  28. package/.next/server/app/api/page_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/workspace/[id]/apps/[wid]/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/workspace/[id]/apps/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/workspace/[id]/export/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/workspace/[id]/route_client-reference-manifest.js +1 -1
  36. package/.next/server/app/api/workspace/config/route_client-reference-manifest.js +1 -1
  37. package/.next/server/app/api/workspace/import/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/workspace/route_client-reference-manifest.js +1 -1
  39. package/.next/server/app/app-legacy-do-not-use/page.js +3 -3
  40. package/.next/server/app/app-legacy-do-not-use/page.js.nft.json +1 -1
  41. package/.next/server/app/app-legacy-do-not-use/page_client-reference-manifest.js +1 -1
  42. package/.next/server/app/app-legacy-do-not-use.html +1 -1
  43. package/.next/server/app/app-legacy-do-not-use.rsc +6 -6
  44. package/.next/server/app/approve/[actionId]/page.js.nft.json +1 -1
  45. package/.next/server/app/approve/[actionId]/page_client-reference-manifest.js +1 -1
  46. package/.next/server/app/docs/[...doc]/page.js.nft.json +1 -1
  47. package/.next/server/app/docs/[...doc]/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/docs/page.js.nft.json +1 -1
  49. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  50. package/.next/server/app/health/page.js.nft.json +1 -1
  51. package/.next/server/app/health/page_client-reference-manifest.js +1 -1
  52. package/.next/server/app/health.html +1 -1
  53. package/.next/server/app/health.rsc +5 -5
  54. package/.next/server/app/hello/page.js.nft.json +1 -1
  55. package/.next/server/app/hello/page_client-reference-manifest.js +1 -1
  56. package/.next/server/app/hello.html +1 -1
  57. package/.next/server/app/hello.rsc +5 -5
  58. package/.next/server/app/index.html +1 -1
  59. package/.next/server/app/index.rsc +6 -6
  60. package/.next/server/app/page.js +9 -3
  61. package/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/server/app/privacy/page.js.nft.json +1 -1
  64. package/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app/privacy.html +1 -1
  66. package/.next/server/app/privacy.rsc +5 -5
  67. package/.next/server/app/share/[token]/page.js.nft.json +1 -1
  68. package/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  69. package/.next/server/app/terms/page.js.nft.json +1 -1
  70. package/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  71. package/.next/server/app/terms.html +1 -1
  72. package/.next/server/app/terms.rsc +5 -5
  73. package/.next/server/app/yo/page.js +1 -1
  74. package/.next/server/app/yo/page.js.nft.json +1 -1
  75. package/.next/server/app/yo/page_client-reference-manifest.js +1 -1
  76. package/.next/server/app/yo.html +1 -1
  77. package/.next/server/app/yo.rsc +6 -6
  78. package/.next/server/app-paths-manifest.json +2 -2
  79. package/.next/server/chunks/1196.js +1 -1
  80. package/.next/server/chunks/{6415.js → 2123.js} +2 -2
  81. package/.next/server/chunks/2234.js +1 -1
  82. package/.next/server/chunks/4224.js +1 -0
  83. package/.next/server/chunks/4600.js +1 -1
  84. package/.next/server/chunks/5678.js +1 -1
  85. package/.next/server/chunks/5991.js +7 -0
  86. package/.next/server/chunks/6470.js +1 -1
  87. package/.next/server/chunks/7585.js +1 -1
  88. package/.next/server/chunks/7935.js +19 -11
  89. package/.next/server/chunks/8468.js +1 -1
  90. package/.next/server/chunks/{1350.js → 9323.js} +3 -3
  91. package/.next/server/chunks/9971.js +1 -1
  92. package/.next/server/functions-config-manifest.json +1 -1
  93. package/.next/server/middleware-build-manifest.js +1 -1
  94. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  95. package/.next/server/pages/404.html +1 -1
  96. package/.next/server/pages/500.html +1 -1
  97. package/.next/server/server-reference-manifest.json +1 -1
  98. package/.next/static/chunks/{1168.aaac1edbb597fe5a.js → 1168.bb1c93965872e980.js} +1 -1
  99. package/.next/static/chunks/2891-bf010357841c9ce9.js +1 -0
  100. package/.next/static/chunks/{2927.7e00cc878d9a3f52.js → 2927.3976471e61df966e.js} +1 -1
  101. package/.next/static/chunks/{3573-1b41d7b8a000d015.js → 3573-667bc4c8f56afcff.js} +1 -1
  102. package/.next/static/chunks/{3a91511d-ba215c0b5dc21ba9.js → 3a91511d-da2c74cad6c6fc33.js} +2 -2
  103. package/.next/static/chunks/4114-a375178fd94c4d8a.js +1 -0
  104. package/.next/static/chunks/{4256.48407d9abad5ea33.js → 4256.aa831e4d8c3f65bc.js} +1 -1
  105. package/.next/static/chunks/{4919-7e7cdd5efc9f2110.js → 4919-0e698cd95504e355.js} +1 -1
  106. package/.next/static/chunks/{5336-233ec7ab3807267c.js → 5336-b775f449d7433604.js} +1 -1
  107. package/.next/static/chunks/{7338-3ce17a93614f1d77.js → 5362-2e8fcdd0bc6273ca.js} +4 -4
  108. package/.next/static/chunks/67-cb9bbb430499e803.js +1 -0
  109. package/.next/static/chunks/{8273-8e92d34180669ca9.js → 8273-3b9d882c5dd6a9a8.js} +1 -1
  110. package/.next/static/chunks/8291-8f6fb6554e692552.js +1 -0
  111. package/.next/static/chunks/8370-6537b6b27df58b23.js +1 -0
  112. package/.next/static/chunks/app/app-legacy-do-not-use/page-efa348da049c5873.js +1 -0
  113. package/.next/static/chunks/app/{error-63cbe72522239cff.js → error-04a18fd49a89ee17.js} +1 -1
  114. package/.next/static/chunks/app/layout-7093dda0d106f34d.js +1 -0
  115. package/.next/static/chunks/app/page-0ec7cf48550f71e6.js +1 -0
  116. package/.next/static/chunks/app/yo/{page-cf5d6540ea31c31c.js → page-48930746b135037e.js} +1 -1
  117. package/.next/static/chunks/{webpack-79ad58260e9b10b4.js → webpack-15ec0114c9d658c2.js} +1 -1
  118. package/.next/static/css/35991998d1b5eff0.css +3 -0
  119. package/.next/trace +28 -28
  120. package/README.md +2 -2
  121. package/bin/auramaxx.js +87 -3
  122. package/package.json +8 -4
  123. package/prisma/migrations/20260301225214_social_tables/migration.sql +81 -0
  124. package/prisma/migrations/20260302120000_add_notification_hash/migration.sql +8 -0
  125. package/prisma/migrations/20260302160000_add_public_key_hex/migration.sql +5 -0
  126. package/prisma/migrations/20260302170000_add_inbound_author_public_key/migration.sql +5 -0
  127. package/prisma/schema.prisma +272 -177
  128. package/shared/credential-field-schema.ts +10 -0
  129. package/skills/auramaxx/SKILL.md +33 -4
  130. package/skills/auramaxx/docs/AGENT_SETUP.md +7 -2
  131. package/src/app/UnlockPageClient.tsx +448 -43
  132. package/src/app/app-legacy-do-not-use/page.tsx +5 -3
  133. package/src/app/globals.css +1 -1
  134. package/src/components/AgentPicker.tsx +278 -0
  135. package/src/components/CreateAgentModal.tsx +192 -0
  136. package/src/components/NotificationDrawer.tsx +15 -13
  137. package/src/components/agent/AgentSidebar.tsx +2 -19
  138. package/src/components/agent/CredentialAgent.tsx +70 -37
  139. package/src/components/agent/CredentialForm.tsx +32 -7
  140. package/src/components/agent/CredentialList.tsx +149 -72
  141. package/src/components/agents/AgentsView.tsx +1035 -0
  142. package/src/components/design-system/TextAreaInput.tsx +78 -0
  143. package/src/components/design-system/index.ts +1 -0
  144. package/src/components/hub/HubView.tsx +58 -0
  145. package/src/components/layout/LeftRail.tsx +333 -40
  146. package/src/components/layout/ViewShell.tsx +125 -0
  147. package/src/components/layout/index.ts +1 -0
  148. package/src/components/social/PrimaryHubRegistrationGate.tsx +260 -0
  149. package/src/components/social/SocialView.tsx +904 -0
  150. package/src/hooks/useSocialNotifications.ts +123 -0
  151. package/src/lib/events.ts +10 -1
  152. package/src/lib/social-client.ts +319 -0
  153. package/src/lib/view-registry.ts +22 -4
  154. package/src/server/cli/commands/agent.ts +33 -7
  155. package/src/server/cli/commands/create.ts +209 -0
  156. package/src/server/cli/commands/onboard.ts +39 -0
  157. package/src/server/cli/commands/play.ts +68 -0
  158. package/src/server/cli/commands/register-agent.ts +181 -0
  159. package/src/server/cli/commands/social.ts +648 -0
  160. package/src/server/cli/commands/start.ts +4 -3
  161. package/src/server/cron/index.ts +5 -9
  162. package/src/server/cron/jobs/social-inbound.ts +596 -0
  163. package/src/server/cron/jobs/social-outbound.ts +70 -0
  164. package/src/server/index.ts +14 -0
  165. package/src/server/lib/agent-profiles.ts +10 -1
  166. package/src/server/lib/cold.ts +0 -45
  167. package/src/server/lib/credential-import.ts +53 -47
  168. package/src/server/lib/defaults.ts +11 -0
  169. package/src/server/lib/feature-flags.ts +3 -0
  170. package/src/server/lib/hub-auth.ts +159 -0
  171. package/src/server/lib/migrate-agent-profiles.ts +96 -0
  172. package/src/server/lib/notifications.ts +12 -1
  173. package/src/server/lib/permissions.ts +10 -0
  174. package/src/server/lib/project-scope.ts +33 -5
  175. package/src/server/lib/social/create.ts +176 -0
  176. package/src/server/lib/social/global-aura-id.ts +115 -0
  177. package/src/server/lib/social/hub-rpc-client.ts +99 -0
  178. package/src/server/lib/social/hub-session.ts +6 -0
  179. package/src/server/lib/social/public-key.ts +32 -0
  180. package/src/server/lib/social/register.ts +162 -0
  181. package/src/server/lib/social/sign.ts +95 -0
  182. package/src/server/lib/social/sync.ts +301 -0
  183. package/src/server/mcp/server.ts +142 -18
  184. package/src/server/mcp/tools.ts +552 -0
  185. package/src/server/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  186. package/src/server/routes/agent-hub.ts +276 -0
  187. package/src/server/routes/agent-profiles.ts +145 -19
  188. package/src/server/routes/credentials.ts +49 -15
  189. package/src/server/routes/heartbeat.ts +3 -7
  190. package/src/server/routes/passkey.ts +7 -1
  191. package/src/server/routes/social.ts +869 -0
  192. package/src/server/routes/unlock.ts +17 -1
  193. package/src/server/routes/verified-credentials.ts +312 -0
  194. package/src/server/test-data/template.db +0 -0
  195. package/src/server/test-data/worker-1/agent-primary.json +12 -0
  196. package/src/server/test-data/worker-1/auramaxx.db +0 -0
  197. package/src/server/test-data/worker-1/backups/auramaxx.db.20260305_011404.bak +0 -0
  198. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-00ntf5h3.json +24 -0
  199. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-dh8fa9k3.json +24 -0
  200. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-prfhlyow.json +25 -0
  201. package/src/server/test-data/worker-1/backups/credentials.20260305_011404.cred-w26jd6zi.json +22 -0
  202. package/src/server/test-data/worker-1/config.json +33 -0
  203. package/src/server/test-data/worker-1/test.db +0 -0
  204. package/src/server/test-data/worker-10/agent-primary.json +12 -0
  205. package/src/server/test-data/worker-10/config.json +33 -0
  206. package/src/server/test-data/worker-10/test.db +0 -0
  207. package/src/server/test-data/worker-11/agent-primary.json +12 -0
  208. package/src/server/test-data/worker-11/config.json +33 -0
  209. package/src/server/test-data/worker-11/test.db +0 -0
  210. package/src/server/test-data/worker-12/agent-primary.json +12 -0
  211. package/src/server/test-data/worker-12/config.json +33 -0
  212. package/src/server/test-data/worker-12/credentials/cred-hboagned.json +25 -0
  213. package/src/server/test-data/worker-12/credentials/cred-nt14xd9t.json +24 -0
  214. package/src/server/test-data/worker-12/credentials/cred-qn59xefc.json +24 -0
  215. package/src/server/test-data/worker-12/test.db +0 -0
  216. package/src/server/test-data/worker-13/agent-primary.json +12 -0
  217. package/src/server/test-data/worker-13/approval-context.json +56 -0
  218. package/src/server/test-data/worker-13/approval-context.key +1 -0
  219. package/src/server/test-data/worker-13/config.json +33 -0
  220. package/src/server/test-data/worker-13/credentials-recently-deleted/cred-jn9yqy2m.json +20 -0
  221. package/src/server/test-data/worker-13/test.db +0 -0
  222. package/src/server/test-data/worker-14/agent-primary.json +12 -0
  223. package/src/server/test-data/worker-14/config.json +33 -0
  224. package/src/server/test-data/worker-14/test.db +0 -0
  225. package/src/server/test-data/worker-15/agent-primary.json +12 -0
  226. package/src/server/test-data/worker-15/config.json +33 -0
  227. package/src/server/test-data/worker-15/test.db +0 -0
  228. package/src/server/test-data/worker-15/update-check-4b305e76.json +5 -0
  229. package/src/server/test-data/worker-2/agent-primary.json +12 -0
  230. package/src/server/test-data/worker-2/config.json +33 -0
  231. package/src/server/test-data/worker-2/test.db +0 -0
  232. package/src/server/test-data/worker-3/agent-primary.json +12 -0
  233. package/src/server/test-data/worker-3/config.json +33 -0
  234. package/src/server/test-data/worker-3/test.db +0 -0
  235. package/src/server/test-data/worker-4/agent-primary.json +12 -0
  236. package/src/server/test-data/worker-4/config.json +33 -0
  237. package/src/server/test-data/worker-4/credentials/cred-bm6p74u5.json +24 -0
  238. package/src/server/test-data/worker-4/credentials/cred-r8eqb07i.json +25 -0
  239. package/src/server/test-data/worker-4/credentials/cred-ziv49y9h.json +24 -0
  240. package/src/server/test-data/worker-4/test.db +0 -0
  241. package/src/server/test-data/worker-5/agent-primary.json +12 -0
  242. package/src/server/test-data/worker-5/config.json +33 -0
  243. package/src/server/test-data/worker-5/credentials/cred-15gyfeht.json +25 -0
  244. package/src/server/test-data/worker-5/credentials/cred-lp0ocnfc.json +24 -0
  245. package/src/server/test-data/worker-5/credentials/cred-zfbwfxw0.json +24 -0
  246. package/src/server/test-data/worker-5/test.db +0 -0
  247. package/src/server/test-data/worker-6/agent-primary.json +12 -0
  248. package/src/server/test-data/worker-6/config.json +33 -0
  249. package/src/server/test-data/worker-6/credentials/cred-dx8li3ue.json +24 -0
  250. package/src/server/test-data/worker-6/credentials/cred-myeskqky.json +24 -0
  251. package/src/server/test-data/worker-6/credentials/cred-tam01qdt.json +25 -0
  252. package/src/server/test-data/worker-6/credentials/cred-wdh6rslw.json +22 -0
  253. package/src/server/test-data/worker-6/credentials-archive/cred-4wg53v1y.json +25 -0
  254. package/src/server/test-data/worker-6/test.db +0 -0
  255. package/src/server/test-data/worker-7/agent-primary.json +12 -0
  256. package/src/server/test-data/worker-7/config.json +33 -0
  257. package/src/server/test-data/worker-7/credentials/cred-ji7ec57d.json +25 -0
  258. package/src/server/test-data/worker-7/credentials/cred-mmgj0ypo.json +24 -0
  259. package/src/server/test-data/worker-7/credentials/cred-nb0ic93x.json +24 -0
  260. package/src/server/test-data/worker-7/test.db +0 -0
  261. package/src/server/test-data/worker-8/agent-primary.json +12 -0
  262. package/src/server/test-data/worker-8/config.json +33 -0
  263. package/src/server/test-data/worker-8/test.db +0 -0
  264. package/src/server/test-data/worker-9/agent-primary.json +12 -0
  265. package/src/server/test-data/worker-9/test.db +0 -0
  266. package/src/server/tests/cli/bin-entrypoint.test.ts +99 -0
  267. package/src/server/tests/cli/social.test.ts +83 -0
  268. package/src/server/tests/cron/social-inbound-followers.unit.test.ts +164 -0
  269. package/src/server/tests/cron/social-inbound-staleness.test.ts +193 -0
  270. package/src/server/tests/cron/social-outbound.test.ts +252 -0
  271. package/src/server/tests/endpoints/agent.test.ts +0 -16
  272. package/src/server/tests/lib/credential-field-schema.test.ts +448 -0
  273. package/src/server/tests/lib/project-scope.test.ts +49 -0
  274. package/src/server/tests/lib/social/create.test.ts +207 -0
  275. package/src/server/tests/lib/social/sign.test.ts +163 -0
  276. package/src/server/tests/lib/social/sync.test.ts +198 -0
  277. package/src/server/tests/mcp/server.test.ts +1 -3
  278. package/src/server/tests/mcp/tools.test.ts +219 -7
  279. package/src/server/tsconfig.tsbuildinfo +1 -1
  280. package/tsconfig.json +1 -0
  281. package/.next/server/chunks/2460.js +0 -7
  282. package/.next/server/chunks/5246.js +0 -1
  283. package/.next/static/chunks/3667-1db7bd03948e60df.js +0 -1
  284. package/.next/static/chunks/5442-b5bb869e832e8967.js +0 -1
  285. package/.next/static/chunks/6872-a8f1ad5fc35a1c35.js +0 -1
  286. package/.next/static/chunks/7394-4bdb1feefad1a74a.js +0 -1
  287. package/.next/static/chunks/7587-8542eae6e5139d27.js +0 -1
  288. package/.next/static/chunks/app/app-legacy-do-not-use/page-569fed5d1a2bfe79.js +0 -1
  289. package/.next/static/chunks/app/layout-af8d9969c7aeb758.js +0 -1
  290. package/.next/static/chunks/app/page-9bd0ec3ba4aa6cea.js +0 -1
  291. package/.next/static/css/88f92e1578b1e5d9.css +0 -3
  292. package/shared/agent-profile-schema.ts +0 -81
  293. package/src/internal/security/frontend-api-authorization-audit.md +0 -206
  294. package/src/server/lib/agent-profile-records.ts +0 -72
  295. /package/.next/static/{QPzVnl7GToqgYBq14V_iC → yEruVJH_cuht5hu5_1R00}/_buildManifest.js +0 -0
  296. /package/.next/static/{QPzVnl7GToqgYBq14V_iC → yEruVJH_cuht5hu5_1R00}/_ssgManifest.js +0 -0
@@ -0,0 +1,125 @@
1
+ 'use client';
2
+
3
+ import React from 'react';
4
+ import { Search } from 'lucide-react';
5
+ import { TextInput } from '@/components/design-system';
6
+
7
+ // ─── Types ───────────────────────────────────────────────────────────
8
+
9
+ interface ViewShellProps {
10
+ sidebar: React.ReactNode;
11
+ children: React.ReactNode;
12
+ searchValue?: string;
13
+ onSearchChange?: (value: string) => void;
14
+ searchPlaceholder?: string;
15
+ sidebarFooter?: React.ReactNode;
16
+ contentClassName?: string;
17
+ }
18
+
19
+ // ─── ViewShell ───────────────────────────────────────────────────────
20
+
21
+ export function ViewShell({
22
+ sidebar,
23
+ children,
24
+ searchValue,
25
+ onSearchChange,
26
+ searchPlaceholder = 'Search...',
27
+ sidebarFooter,
28
+ contentClassName,
29
+ }: ViewShellProps) {
30
+ const sidebarWidth = 'calc(200px * var(--ui-scale-factor, 1))';
31
+
32
+ return (
33
+ <div className="relative isolate h-full w-full overflow-hidden flex flex-col bg-[var(--color-background,#f4f4f5)]">
34
+ {/* Background — sterile tyvek field */}
35
+ <div className="absolute inset-0 pointer-events-none z-0 overflow-hidden">
36
+ <div className="absolute inset-0 bg-grid-adaptive bg-[size:4rem_4rem] opacity-30" />
37
+ <div className="absolute inset-0 tyvek-texture opacity-40 mix-blend-multiply" />
38
+ <div className="absolute bottom-[5%] right-[5%] opacity-[0.03] select-none">
39
+ <div className="text-[12vw] font-black leading-none text-[var(--color-text,#0a0a0a)] font-mono tracking-tighter text-right">
40
+ AURAMAXX
41
+ </div>
42
+ </div>
43
+ <div className="absolute top-10 left-[200px] w-24 h-24 border-l-4 border-t-4 border-[var(--color-text,#0a0a0a)] opacity-10">
44
+ <div className="absolute top-2 left-2 w-3 h-3 bg-[var(--color-text,#0a0a0a)]" />
45
+ </div>
46
+ <div className="absolute bottom-10 right-10 w-24 h-24 border-r-4 border-b-4 border-[var(--color-text,#0a0a0a)] opacity-10 flex items-end justify-end">
47
+ <div className="absolute bottom-2 right-2 w-3 h-3 bg-[var(--color-text,#0a0a0a)]" />
48
+ </div>
49
+ </div>
50
+
51
+ {/* Main layout */}
52
+ <div className="relative z-10 flex-1 flex overflow-hidden">
53
+ {/* Sidebar */}
54
+ <div
55
+ className="h-full flex flex-col border-r border-[var(--color-border,#d4d4d8)] font-mono relative overflow-hidden shrink-0"
56
+ style={{
57
+ width: sidebarWidth,
58
+ minWidth: sidebarWidth,
59
+ background: 'var(--color-surface, #f4f4f2)',
60
+ fontSize: 'var(--font-size-sm)',
61
+ }}
62
+ >
63
+ {/* Dot texture */}
64
+ <div className="absolute inset-0 opacity-[0.02] pointer-events-none bg-[radial-gradient(var(--color-text,#000)_1px,transparent_1px)] bg-[size:4px_4px]" />
65
+
66
+ {/* Branding header */}
67
+ <div className="flex items-center justify-between border-b border-[var(--color-border,#d4d4d8)] relative z-10 px-3 py-3">
68
+ <div className="flex items-center gap-2">
69
+ <div className="leading-tight">
70
+ <div className="flex items-baseline gap-1">
71
+ <span className="text-[10px] font-bold tracking-tight lowercase text-[var(--color-text,#0a0a0a)]">
72
+ auramaxx
73
+ </span>
74
+ <span className="text-[8px] text-[var(--color-text-muted,#6b7280)] uppercase tracking-widest">
75
+ from
76
+ </span>
77
+ </div>
78
+ <a
79
+ href="https://x.com/nicoletteduclar"
80
+ target="_blank"
81
+ rel="noopener noreferrer"
82
+ className="block text-[8px] text-[var(--color-text-muted,#6b7280)] hover:text-[var(--color-text,#0a0a0a)] transition-colors"
83
+ >
84
+ @nicoletteduclar, with love
85
+ </a>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ {/* Scrollable sidebar content */}
91
+ <div className="flex-1 overflow-y-auto overflow-x-hidden relative z-10">
92
+ {sidebar}
93
+ </div>
94
+
95
+ {/* Footer (e.g. auraId display) */}
96
+ {sidebarFooter && (
97
+ <div className="relative z-30 border-t border-[var(--color-border,#d4d4d8)] overflow-visible">
98
+ {sidebarFooter}
99
+ </div>
100
+ )}
101
+ </div>
102
+
103
+ {/* Main content */}
104
+ <div className={`flex-1 overflow-y-auto relative ${contentClassName || ''}`}>
105
+ {children}
106
+ </div>
107
+ </div>
108
+
109
+ {/* Search dock (bottom) */}
110
+ {onSearchChange && (
111
+ <div className="absolute bottom-0 left-[200px] right-0 z-30 border-t border-[var(--color-border,#d4d4d8)] bg-[var(--color-surface,#ffffff)]/95 backdrop-blur-sm">
112
+ <div className="w-full px-3 py-2.5">
113
+ <TextInput
114
+ compact
115
+ leftElement={<Search size={12} />}
116
+ placeholder={searchPlaceholder}
117
+ value={searchValue ?? ''}
118
+ onChange={(e) => onSearchChange(e.target.value)}
119
+ />
120
+ </div>
121
+ </div>
122
+ )}
123
+ </div>
124
+ );
125
+ }
@@ -4,3 +4,4 @@ export { ContentArea } from './ContentArea';
4
4
  export { AppStoreDrawer } from './AppStoreDrawer';
5
5
  export { LeftRail } from './LeftRail';
6
6
  export { CreateViewModal } from './CreateViewModal';
7
+ export { ViewShell } from './ViewShell';
@@ -0,0 +1,260 @@
1
+ 'use client';
2
+
3
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
4
+ import { Lock, Loader2, User } from 'lucide-react';
5
+ import { api, Api } from '@/lib/api';
6
+ import { Button, TextInput } from '@/components/design-system';
7
+ import { fetchSocialProfile } from '@/lib/social-client';
8
+ import type { AgentProfile } from '@/lib/social-client';
9
+ import { AgentPfp } from '@/components/AgentPicker';
10
+
11
+ const DEFAULT_AGENT_AVATAR = 'https://auramaxx.sh/agent7.png';
12
+ const SPRITE_OPTIONS = Array.from({ length: 10 }, (_, i) => `/agent${i + 1}.png`);
13
+
14
+ interface PrimaryHubStatus {
15
+ agentId: string;
16
+ auraId: number | null;
17
+ registered: boolean;
18
+ hasPublicKey: boolean;
19
+ }
20
+
21
+ interface AgentInfo {
22
+ id: string;
23
+ isPrimary: boolean;
24
+ parentAgentId?: string;
25
+ }
26
+
27
+ interface PrimaryHubRegistrationGateProps {
28
+ children: React.ReactNode;
29
+ }
30
+
31
+ function normalizeHandle(raw: string): string {
32
+ return raw.trim().replace(/^@+/, '').replace(/\s+/g, '');
33
+ }
34
+
35
+ function normalizeSpritePfp(pfp: string | undefined): string {
36
+ const value = (pfp || '').trim();
37
+ if (/\/agent\d+\.png$/.test(value)) return value.startsWith('http') ? value : `https://auramaxx.sh${value}`;
38
+ return DEFAULT_AGENT_AVATAR;
39
+ }
40
+
41
+ export function PrimaryHubRegistrationGate({ children }: PrimaryHubRegistrationGateProps) {
42
+ const [loading, setLoading] = useState(true);
43
+ const [agentId, setAgentId] = useState<string>('');
44
+ const [registered, setRegistered] = useState(false);
45
+ const [statusError, setStatusError] = useState<string | null>(null);
46
+ const [registerError, setRegisterError] = useState<string | null>(null);
47
+ const [registering, setRegistering] = useState(false);
48
+
49
+ const [selectedPfp, setSelectedPfp] = useState<string>(DEFAULT_AGENT_AVATAR);
50
+ const [handle, setHandle] = useState('');
51
+ const [displayName, setDisplayName] = useState('');
52
+
53
+ const loadStatus = useCallback(async () => {
54
+ setLoading(true);
55
+ setStatusError(null);
56
+ try {
57
+ const agentsRes = await api.get<{ agents: AgentInfo[] }>(Api.Wallet, '/agents/credential');
58
+ const agents = agentsRes.agents || [];
59
+ const primary = agents.find((agent) => agent.isPrimary && !agent.parentAgentId)
60
+ ?? agents.find((agent) => agent.isPrimary)
61
+ ?? agents[0];
62
+
63
+ if (!primary?.id) {
64
+ throw new Error('Primary agent not found');
65
+ }
66
+
67
+ setAgentId(primary.id);
68
+
69
+ const [statusRes, profileRes] = await Promise.allSettled([
70
+ api.get<PrimaryHubStatus>(Api.Wallet, `/agent-hub/${encodeURIComponent(primary.id)}/status`),
71
+ fetchSocialProfile(primary.id),
72
+ ]);
73
+
74
+ if (statusRes.status === 'fulfilled') {
75
+ setRegistered(statusRes.value.registered === true);
76
+ } else {
77
+ setRegistered(false);
78
+ }
79
+
80
+ const profile: AgentProfile = profileRes.status === 'fulfilled'
81
+ ? profileRes.value
82
+ : { pfp: DEFAULT_AGENT_AVATAR, handle: '', displayName: '' };
83
+
84
+ setSelectedPfp(normalizeSpritePfp(profile.pfp));
85
+ setHandle(normalizeHandle(profile.handle || ''));
86
+ setDisplayName((profile.displayName || '').trim());
87
+ } catch (error) {
88
+ setRegistered(false);
89
+ setStatusError(error instanceof Error ? error.message : 'Failed to load primary hub registration status');
90
+ } finally {
91
+ setLoading(false);
92
+ }
93
+ }, []);
94
+
95
+ useEffect(() => {
96
+ void loadStatus();
97
+ }, [loadStatus]);
98
+
99
+ const canSubmit = useMemo(
100
+ () => Boolean(agentId && normalizeHandle(handle) && displayName.trim()),
101
+ [agentId, handle, displayName],
102
+ );
103
+
104
+ const handleRegister = useCallback(async () => {
105
+ if (!agentId || registering) return;
106
+ const normalizedHandle = normalizeHandle(handle);
107
+ const normalizedDisplayName = displayName.trim();
108
+ if (!normalizedHandle || !normalizedDisplayName) {
109
+ setRegisterError('Username and display name are required.');
110
+ return;
111
+ }
112
+
113
+ setRegistering(true);
114
+ setRegisterError(null);
115
+
116
+ try {
117
+ await api.post(Api.Wallet, `/agent-hub/${encodeURIComponent(agentId)}/register`, {});
118
+
119
+ const updates: Array<{ field: string; value: string }> = [
120
+ { field: 'handle', value: normalizedHandle },
121
+ { field: 'display_name', value: normalizedDisplayName },
122
+ { field: 'pfp', value: selectedPfp },
123
+ { field: 'pfp_is_sprite', value: 'true' },
124
+ ];
125
+
126
+ for (const update of updates) {
127
+ await api.post<{ success?: boolean; error?: string }>(
128
+ Api.Wallet,
129
+ '/social/profile',
130
+ { agentId, field: update.field, value: update.value },
131
+ );
132
+ }
133
+
134
+ await loadStatus();
135
+ } catch (error) {
136
+ setRegisterError(error instanceof Error ? error.message : 'Failed to register on primary hub');
137
+ } finally {
138
+ setRegistering(false);
139
+ }
140
+ }, [agentId, displayName, handle, loadStatus, registering, selectedPfp]);
141
+
142
+ if (loading) {
143
+ return (
144
+ <div className="h-full w-full flex items-center justify-center">
145
+ <Loader2 size={18} className="animate-spin text-[var(--color-text-muted,#6b7280)]" />
146
+ </div>
147
+ );
148
+ }
149
+
150
+ if (registered) {
151
+ return <>{children}</>;
152
+ }
153
+
154
+ return (
155
+ <div className="h-full w-full flex items-center justify-center p-6 bg-[var(--color-background,#f4f4f5)]">
156
+ <div className="w-full max-w-[440px] bg-[var(--color-surface,#f4f4f2)] clip-specimen border-mech shadow-mech overflow-hidden font-mono">
157
+ <div className="px-5 py-3 border-b border-[var(--color-border,#d4d4d8)] bg-[var(--color-surface-alt,#fafafa)] flex items-center justify-between">
158
+ <span className="font-sans font-bold text-sm text-[var(--color-text,#0a0a0a)] uppercase tracking-tight">
159
+ Register Agent
160
+ </span>
161
+ <span className="text-[9px] text-[var(--color-text-faint,#9ca3af)] font-bold tracking-widest uppercase inline-flex items-center gap-1">
162
+ <Lock size={10} />
163
+ Locked
164
+ </span>
165
+ </div>
166
+
167
+ <div className="p-5 space-y-4">
168
+ <div className="flex items-center gap-3">
169
+ <AgentPfp src={selectedPfp} isSprite={true} fallbackLetter="A" size="lg" />
170
+ <div>
171
+ <div className="text-[12px] font-semibold text-[var(--color-text,#0a0a0a)]">
172
+ Register your primary agent
173
+ </div>
174
+ <div className="text-[10px] text-[var(--color-text-muted,#6b7280)]">
175
+ Credentials and Social use the primary hub from Settings.
176
+ </div>
177
+ </div>
178
+ </div>
179
+
180
+ <div>
181
+ <label className="block text-[9px] uppercase tracking-widest text-[var(--color-text-muted,#6b7280)] mb-2">
182
+ Profile Image
183
+ </label>
184
+ <div className="grid grid-cols-5 gap-2">
185
+ {SPRITE_OPTIONS.map((src, index) => {
186
+ const spriteUrl = `https://auramaxx.sh${src}`;
187
+ const selected = selectedPfp === spriteUrl;
188
+ return (
189
+ <button
190
+ key={src}
191
+ type="button"
192
+ onClick={() => setSelectedPfp(spriteUrl)}
193
+ className={`rounded border transition-colors ${
194
+ selected
195
+ ? 'border-[var(--color-accent,#6366f1)]'
196
+ : 'border-[var(--color-border,#d4d4d8)] hover:border-[var(--color-text-muted,#6b7280)]'
197
+ }`}
198
+ style={{ padding: '4px 2px' }}
199
+ >
200
+ <div
201
+ className="yo-sprite"
202
+ style={{
203
+ backgroundImage: `url('${src}')`,
204
+ animation: 'yo-sprite-frames 0.9s steps(1, end) infinite',
205
+ animationDelay: `${index * -150}ms`,
206
+ width: '28px',
207
+ height: '40px',
208
+ margin: '0 auto',
209
+ }}
210
+ />
211
+ </button>
212
+ );
213
+ })}
214
+ </div>
215
+ </div>
216
+
217
+ <TextInput
218
+ label="Username"
219
+ compact
220
+ placeholder="@myhandle"
221
+ value={handle}
222
+ onChange={(event) => {
223
+ setHandle(event.target.value);
224
+ setRegisterError(null);
225
+ }}
226
+ leftElement={<User size={12} />}
227
+ />
228
+
229
+ <TextInput
230
+ label="Display Name"
231
+ compact
232
+ placeholder="My Display Name"
233
+ value={displayName}
234
+ onChange={(event) => {
235
+ setDisplayName(event.target.value);
236
+ setRegisterError(null);
237
+ }}
238
+ />
239
+
240
+ {(statusError || registerError) && (
241
+ <div className="text-[10px] text-[var(--color-danger,#ef4444)] bg-[var(--color-danger,#ef4444)]/10 px-3 py-2 border border-[var(--color-danger,#ef4444)]/20">
242
+ {registerError || statusError}
243
+ </div>
244
+ )}
245
+
246
+ <Button
247
+ variant="primary"
248
+ size="sm"
249
+ className="w-full"
250
+ onClick={() => { void handleRegister(); }}
251
+ loading={registering}
252
+ disabled={!canSubmit}
253
+ >
254
+ REGISTER AGENT
255
+ </Button>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ );
260
+ }