auramaxx 0.0.12 → 0.0.13

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 (334) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +244 -227
  3. package/.next/app-path-routes-manifest.json +11 -10
  4. package/.next/build-manifest.json +14 -14
  5. package/.next/prerender-manifest.json +49 -25
  6. package/.next/react-loadable-manifest.json +41 -41
  7. package/.next/routes-manifest.json +6 -0
  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 +12 -12
  11. package/.next/server/app/api/[...doc]/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/api/agent-requests/route_client-reference-manifest.js +1 -1
  13. package/.next/server/app/api/apps/install/route_client-reference-manifest.js +1 -1
  14. package/.next/server/app/api/apps/manifests/route_client-reference-manifest.js +1 -1
  15. package/.next/server/app/api/apps/static/[...path]/route_client-reference-manifest.js +1 -1
  16. package/.next/server/app/api/docs/plain/route_client-reference-manifest.js +1 -1
  17. package/.next/server/app/api/events/route.js +1 -19
  18. package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  19. package/.next/server/app/api/import-from-openclaw/[channel]/route_client-reference-manifest.js +1 -1
  20. package/.next/server/app/api/import-from-openclaw/route_client-reference-manifest.js +1 -1
  21. package/.next/server/app/api/import-from-openclaw/validate/[channel]/route_client-reference-manifest.js +1 -1
  22. package/.next/server/app/api/page_client-reference-manifest.js +1 -1
  23. package/.next/server/app/api/restart/route_client-reference-manifest.js +1 -1
  24. package/.next/server/app/api/update/route.js +63 -1
  25. package/.next/server/app/api/update/route.js.nft.json +1 -1
  26. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  27. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  28. package/.next/server/app/api/workspace/[id]/apps/[wid]/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/workspace/[id]/apps/route_client-reference-manifest.js +1 -1
  30. package/.next/server/app/api/workspace/[id]/export/route_client-reference-manifest.js +1 -1
  31. package/.next/server/app/api/workspace/[id]/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/workspace/config/route_client-reference-manifest.js +1 -1
  33. package/.next/server/app/api/workspace/import/route_client-reference-manifest.js +1 -1
  34. package/.next/server/app/api/workspace/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/app-legacy-do-not-use/page.js +1 -1
  36. package/.next/server/app/app-legacy-do-not-use/page.js.nft.json +1 -1
  37. package/.next/server/app/app-legacy-do-not-use/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/app-legacy-do-not-use.html +1 -1
  39. package/.next/server/app/app-legacy-do-not-use.rsc +14 -14
  40. package/.next/server/app/approve/[actionId]/page.js +1 -1
  41. package/.next/server/app/approve/[actionId]/page_client-reference-manifest.js +1 -1
  42. package/.next/server/app/docs/[...doc]/page_client-reference-manifest.js +1 -1
  43. package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
  44. package/.next/server/app/health/page_client-reference-manifest.js +1 -1
  45. package/.next/server/app/health.html +1 -1
  46. package/.next/server/app/health.rsc +13 -13
  47. package/.next/server/app/hello/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/hello.html +1 -1
  49. package/.next/server/app/hello.rsc +14 -14
  50. package/.next/server/app/index.html +1 -1
  51. package/.next/server/app/index.rsc +18 -21
  52. package/.next/server/app/page.js +3 -3
  53. package/.next/server/app/page.js.nft.json +1 -1
  54. package/.next/server/app/page_client-reference-manifest.js +1 -1
  55. package/.next/server/app/privacy/page_client-reference-manifest.js +1 -1
  56. package/.next/server/app/privacy.html +1 -1
  57. package/.next/server/app/privacy.rsc +13 -13
  58. package/.next/server/app/share/[token]/page_client-reference-manifest.js +1 -1
  59. package/.next/server/app/terms/page_client-reference-manifest.js +1 -1
  60. package/.next/server/app/terms.html +1 -1
  61. package/.next/server/app/terms.rsc +13 -13
  62. package/.next/server/app/yo/page.js +2 -0
  63. package/.next/server/app/yo/page.js.nft.json +1 -0
  64. package/.next/server/app/yo/page_client-reference-manifest.js +1 -0
  65. package/.next/server/app/yo.html +1 -0
  66. package/.next/server/app/yo.meta +7 -0
  67. package/.next/server/app/yo.rsc +23 -0
  68. package/.next/server/app-paths-manifest.json +11 -10
  69. package/.next/server/chunks/2145.js +1 -1
  70. package/.next/server/chunks/2460.js +1 -1
  71. package/.next/server/chunks/5246.js +1 -1
  72. package/.next/server/chunks/5678.js +1 -1
  73. package/.next/server/chunks/5784.js +1 -1
  74. package/.next/server/chunks/6086.js +2 -20
  75. package/.next/server/chunks/{5553.js → 6415.js} +2 -2
  76. package/.next/server/chunks/7935.js +2 -2
  77. package/.next/server/functions-config-manifest.json +1 -1
  78. package/.next/server/instrumentation.js +1 -1
  79. package/.next/server/middleware-build-manifest.js +1 -1
  80. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  81. package/.next/server/pages/404.html +1 -1
  82. package/.next/server/pages/500.html +1 -1
  83. package/.next/server/server-reference-manifest.json +1 -1
  84. package/.next/server/webpack-runtime.js +1 -1
  85. package/.next/static/WshFGr6RxGYP6AbWuT9OG/_buildManifest.js +1 -0
  86. package/.next/static/chunks/1168.aaac1edbb597fe5a.js +1 -0
  87. package/.next/static/chunks/1255-7999eac54f80a49f.js +1 -0
  88. package/.next/static/chunks/142-fa9752f53a551f63.js +1 -0
  89. package/.next/static/chunks/2505.d54ccadc42f4e3d1.js +1 -0
  90. package/.next/static/chunks/2619-04bc32f026a0d946.js +1 -0
  91. package/.next/static/chunks/2927.7e00cc878d9a3f52.js +1 -0
  92. package/.next/static/chunks/3573-1b41d7b8a000d015.js +1 -0
  93. package/.next/static/chunks/3609.ded5a5306e18af9c.js +1 -0
  94. package/.next/static/chunks/3667-1db7bd03948e60df.js +1 -0
  95. package/.next/static/chunks/3826.a73d4a88d8c09030.js +1 -0
  96. package/.next/static/chunks/{3a91511d-648a2ba3dad7df0c.js → 3a91511d-ba215c0b5dc21ba9.js} +1 -1
  97. package/.next/static/chunks/4256.48407d9abad5ea33.js +1 -0
  98. package/.next/static/chunks/4685-7f53bbfc4a9845eb.js +1 -0
  99. package/.next/static/chunks/4901-ba6a32818662e70a.js +1 -0
  100. package/.next/static/chunks/4919-7e7cdd5efc9f2110.js +1 -0
  101. package/.next/static/chunks/4bd1b696-100b9d70ed4e49c1.js +1 -0
  102. package/.next/static/chunks/5336-233ec7ab3807267c.js +1 -0
  103. package/.next/static/chunks/5442-b5bb869e832e8967.js +1 -0
  104. package/.next/static/chunks/6233-97a810aa272af547.js +1 -0
  105. package/.next/static/chunks/626.a5109d16f9eca1f6.js +1 -0
  106. package/.next/static/chunks/6872-faea0f088ab2d450.js +1 -0
  107. package/.next/static/chunks/7338-3ce17a93614f1d77.js +59 -0
  108. package/.next/static/chunks/7394-4bdb1feefad1a74a.js +1 -0
  109. package/.next/static/chunks/7616-1129bcb3eee8d315.js +1 -0
  110. package/.next/static/chunks/786-26deffb41572cbb3.js +1 -0
  111. package/.next/static/chunks/8273-8e92d34180669ca9.js +1 -0
  112. package/.next/static/chunks/8357.5dee1e0c4e5bb091.js +1 -0
  113. package/.next/static/chunks/9062-2bc2d089f9c9c6ba.js +1 -0
  114. package/.next/static/chunks/9380.f198afbf0c6b5369.js +1 -0
  115. package/.next/static/chunks/app/_not-found/page-5a8c6a29f762fa58.js +1 -0
  116. package/.next/static/chunks/app/api/[...doc]/page-f0852f35f0fd1d44.js +1 -0
  117. package/.next/static/chunks/app/api/agent-requests/route-cf84f975aad4c719.js +1 -0
  118. package/.next/static/chunks/app/api/apps/install/route-cf84f975aad4c719.js +1 -0
  119. package/.next/static/chunks/app/api/apps/manifests/route-cf84f975aad4c719.js +1 -0
  120. package/.next/static/chunks/app/api/apps/static/[...path]/route-cf84f975aad4c719.js +1 -0
  121. package/.next/static/chunks/app/api/docs/plain/route-cf84f975aad4c719.js +1 -0
  122. package/.next/static/chunks/app/api/events/route-cf84f975aad4c719.js +1 -0
  123. package/.next/static/chunks/app/api/import-from-openclaw/[channel]/route-cf84f975aad4c719.js +1 -0
  124. package/.next/static/chunks/app/api/import-from-openclaw/route-cf84f975aad4c719.js +1 -0
  125. package/.next/static/chunks/app/api/import-from-openclaw/validate/[channel]/route-cf84f975aad4c719.js +1 -0
  126. package/.next/static/chunks/app/api/page-cc59bebcc0d2c01d.js +1 -0
  127. package/.next/static/chunks/app/api/restart/route-cf84f975aad4c719.js +1 -0
  128. package/.next/static/chunks/app/api/update/route-cf84f975aad4c719.js +1 -0
  129. package/.next/static/chunks/app/api/version/route-cf84f975aad4c719.js +1 -0
  130. package/.next/static/chunks/app/api/workspace/[id]/apps/[wid]/route-cf84f975aad4c719.js +1 -0
  131. package/.next/static/chunks/app/api/workspace/[id]/apps/route-cf84f975aad4c719.js +1 -0
  132. package/.next/static/chunks/app/api/workspace/[id]/export/route-cf84f975aad4c719.js +1 -0
  133. package/.next/static/chunks/app/api/workspace/[id]/route-cf84f975aad4c719.js +1 -0
  134. package/.next/static/chunks/app/api/workspace/config/route-cf84f975aad4c719.js +1 -0
  135. package/.next/static/chunks/app/api/workspace/import/route-cf84f975aad4c719.js +1 -0
  136. package/.next/static/chunks/app/api/workspace/route-cf84f975aad4c719.js +1 -0
  137. package/.next/static/chunks/app/app-legacy-do-not-use/page-e5dc864e92d90ca7.js +1 -0
  138. package/.next/static/chunks/app/approve/[actionId]/page-2acca1f490424f21.js +1 -0
  139. package/.next/static/chunks/app/docs/[...doc]/page-8e2a2d036caab242.js +1 -0
  140. package/.next/static/chunks/app/docs/page-acf872a03ff79893.js +1 -0
  141. package/.next/static/chunks/app/error-66f983b7769dabfa.js +1 -0
  142. package/.next/static/chunks/app/health/page-c9185854ed9c86d0.js +1 -0
  143. package/.next/static/chunks/app/hello/page-74c9f4deaa4b03dd.js +1 -0
  144. package/.next/static/chunks/app/layout-af8d9969c7aeb758.js +1 -0
  145. package/.next/static/chunks/app/page-16dfcd1c7cc88bcc.js +1 -0
  146. package/.next/static/chunks/app/privacy/page-8e2d17079355c2cc.js +1 -0
  147. package/.next/static/chunks/app/share/[token]/page-5dd9b0418eee411f.js +1 -0
  148. package/.next/static/chunks/app/terms/page-8e2d17079355c2cc.js +1 -0
  149. package/.next/static/chunks/app/yo/layout-cf84f975aad4c719.js +1 -0
  150. package/.next/static/chunks/app/yo/page-719dc5f213fdfb30.js +1 -0
  151. package/.next/static/chunks/framework-a32a2a465584c0bc.js +1 -0
  152. package/.next/static/chunks/main-0f0f9142f74e7215.js +1 -0
  153. package/.next/static/chunks/main-app-24f0c92ba10af457.js +1 -0
  154. package/.next/static/chunks/pages/_app-4b3fb5e477a0267f.js +1 -0
  155. package/.next/static/chunks/pages/_error-c970d8b55ace1b48.js +1 -0
  156. package/.next/static/chunks/{webpack-768de8b7d6a7a27a.js → webpack-79ad58260e9b10b4.js} +1 -1
  157. package/.next/static/css/83cd401584ab787f.css +3 -0
  158. package/.next/trace +28 -28
  159. package/.next/types/app/yo/layout.ts +84 -0
  160. package/.next/types/app/yo/page.ts +84 -0
  161. package/.next/types/routes.d.ts +4 -2
  162. package/.next/types/validator.ts +18 -0
  163. package/bin/auramaxx.js +9 -24
  164. package/docs/ARCHITECTURE.md +1 -1
  165. package/docs/AUTH.md +6 -3
  166. package/docs/CLI.md +2 -0
  167. package/docs/MCP.md +2 -0
  168. package/docs/credentials.md +2 -0
  169. package/package.json +1 -1
  170. package/prisma/migrations/20260227214000_update_agent_action_ttl_defaults/migration.sql +19 -0
  171. package/public/0a167e5e-4f52-4715-ae23-bf63d259a6b1.png +0 -0
  172. package/public/141ec92c-6780-4b23-838f-9a7bf1e91bb8.png +0 -0
  173. package/public/3afc4935-92cb-42af-9624-0b1341c12a5e.png +0 -0
  174. package/public/43947df5-dbcf-4e49-ab8b-41b9162c0410.png +0 -0
  175. package/public/5aeae9ce-0d38-49ea-8fd1-167892a04a85.png +0 -0
  176. package/public/660e4ea3-a3a6-4be4-a8ca-2cb74c51dfb5.png +0 -0
  177. package/public/733f02d7-6b58-4ba6-a5c8-d062cd205e1d.png +0 -0
  178. package/public/a32d65cb-95b0-4977-be6b-cf69f515afbe.png +0 -0
  179. package/public/agent1.png +0 -0
  180. package/public/agent10.png +0 -0
  181. package/public/agent2.png +0 -0
  182. package/public/agent3.png +0 -0
  183. package/public/agent4.png +0 -0
  184. package/public/agent5.png +0 -0
  185. package/public/agent6.png +0 -0
  186. package/public/agent7.png +0 -0
  187. package/public/agent8.png +0 -0
  188. package/public/agent9.png +0 -0
  189. package/public/c4938305-b811-4ccc-91db-94d309734827.png +0 -0
  190. package/public/f2ca6825-a4f3-4107-815c-51ee740dfc09.png +0 -0
  191. package/public/llm.txt +2 -0
  192. package/public/llms.txt +39 -0
  193. package/public/ss-dark1.png +0 -0
  194. package/public/ss-dark1.webp +0 -0
  195. package/public/ss-dark2.png +0 -0
  196. package/public/ss-dark2.webp +0 -0
  197. package/public/ss-dark3.png +0 -0
  198. package/public/ss-dark3.webp +0 -0
  199. package/public/ss-light1.png +0 -0
  200. package/public/ss-light1.webp +0 -0
  201. package/public/ss-light2.png +0 -0
  202. package/public/ss-light2.webp +0 -0
  203. package/public/ss-light3.png +0 -0
  204. package/public/ss-light3.webp +0 -0
  205. package/shared/agent-profile-schema.ts +81 -0
  206. package/shared/credential-field-schema.ts +12 -0
  207. package/skills/auramaxx/SKILL.md +71 -691
  208. package/src/app/UnlockPageClient.tsx +1939 -0
  209. package/src/app/api/page.tsx +8 -9
  210. package/src/app/api/update/route.ts +105 -36
  211. package/src/app/approve/[actionId]/page.tsx +4 -1
  212. package/src/app/docs/DocsPageContent.tsx +3 -3
  213. package/src/app/globals.css +94 -0
  214. package/src/app/layout.tsx +1 -0
  215. package/src/app/page.tsx +25 -1935
  216. package/src/app/yo/layout.tsx +29 -0
  217. package/src/app/yo/page.tsx +528 -0
  218. package/src/components/HumanActionBar.tsx +34 -8
  219. package/src/components/agent/AgentSidebar.tsx +3 -1
  220. package/src/components/agent/CredentialAgent.tsx +5 -1
  221. package/src/components/agent/CredentialDetail.tsx +32 -1
  222. package/src/components/agent/CredentialForm.tsx +94 -7
  223. package/src/components/agent/CredentialRow.tsx +8 -1
  224. package/src/components/agent/credentialFormName.ts +22 -1
  225. package/src/components/agent/types.ts +2 -2
  226. package/src/components/design-system/Modal.tsx +14 -1
  227. package/src/hooks/useUpdateChecker.ts +17 -1
  228. package/src/lib/pino.ts +77 -8
  229. package/src/server/cli/commands/actions.ts +1 -1
  230. package/src/server/cli/commands/agent.ts +110 -65
  231. package/src/server/cli/commands/approve.ts +1 -1
  232. package/src/server/cli/commands/auth.ts +81 -20
  233. package/src/server/cli/commands/token.ts +2 -2
  234. package/src/server/cli/lib/escalation.ts +109 -24
  235. package/src/server/cli/lib/process.ts +2 -1
  236. package/src/server/cli/socket.ts +1 -1
  237. package/src/server/index.ts +2 -0
  238. package/src/server/lib/agent-profile-records.ts +72 -0
  239. package/src/server/lib/credential-transport.ts +27 -11
  240. package/src/server/lib/defaults.ts +3 -3
  241. package/src/server/lib/escalation-responder.ts +1 -1
  242. package/src/server/lib/resolve-action.ts +2 -2
  243. package/src/server/mcp/server.ts +6 -1
  244. package/src/server/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  245. package/src/server/routes/actions.ts +2 -2
  246. package/src/server/routes/agent-profiles.ts +82 -0
  247. package/src/server/routes/auth.ts +39 -4
  248. package/src/server/routes/credentials.ts +18 -0
  249. package/src/server/tests/cli/agent-auth.test.ts +20 -39
  250. package/src/server/tests/cli/agent.test.ts +18 -0
  251. package/src/server/tests/cli/auth-action-flag.test.ts +3 -2
  252. package/src/server/tests/cli/bin-entrypoint.test.ts +35 -11
  253. package/src/server/tests/cli/escalation.test.ts +7 -3
  254. package/src/server/tests/cli/process.test.ts +3 -3
  255. package/src/server/tests/cli/socket.test.ts +2 -2
  256. package/src/server/tests/endpoints/actions.test.ts +2 -2
  257. package/src/server/tests/endpoints/agent-profiles.test.ts +117 -0
  258. package/src/server/tests/endpoints/auth.test.ts +34 -0
  259. package/src/server/tests/lib/credential-transport.test.ts +68 -2
  260. package/src/server/tests/lib/defaults.test.ts +2 -2
  261. package/src/server/tests/lib/escalation-responder.test.ts +2 -2
  262. package/src/server/tests/setup.ts +7 -0
  263. package/src/server/tsconfig.tsbuildinfo +1 -1
  264. package/src/server/types.ts +1 -1
  265. package/.next/static/chunks/1168.63dbb444a33b1867.js +0 -1
  266. package/.next/static/chunks/1255-e8718b02724690dd.js +0 -1
  267. package/.next/static/chunks/142-aeaf7ffa9c53516d.js +0 -1
  268. package/.next/static/chunks/2505.22aaa333fd65908f.js +0 -1
  269. package/.next/static/chunks/2619-3c9e02e22d10480a.js +0 -1
  270. package/.next/static/chunks/2927.e7e9e2a1b8d2dc61.js +0 -1
  271. package/.next/static/chunks/3573-27e17f4ff2dd86ed.js +0 -1
  272. package/.next/static/chunks/3609.6f8e0ecd6de9566c.js +0 -1
  273. package/.next/static/chunks/3667-d6770121629db38b.js +0 -1
  274. package/.next/static/chunks/3826.7dfe96467cd74e45.js +0 -1
  275. package/.next/static/chunks/4256.50cb375c979ffd5a.js +0 -1
  276. package/.next/static/chunks/4685-3f8d92f574366fec.js +0 -1
  277. package/.next/static/chunks/4901-54c1ac380b7b43bb.js +0 -1
  278. package/.next/static/chunks/4919-fe6f1553abfc9420.js +0 -1
  279. package/.next/static/chunks/4bd1b696-f785427dddbba9fb.js +0 -1
  280. package/.next/static/chunks/5336-bd251f91235f7c11.js +0 -1
  281. package/.next/static/chunks/5442-be197c885bf12079.js +0 -1
  282. package/.next/static/chunks/5553-c8b86fe3513fce04.js +0 -59
  283. package/.next/static/chunks/6233-44e6fe57a552a816.js +0 -1
  284. package/.next/static/chunks/626.2583673a0386a81b.js +0 -1
  285. package/.next/static/chunks/6872-6442f2f5cce36ce5.js +0 -1
  286. package/.next/static/chunks/7411-3ca797c21b722ccd.js +0 -1
  287. package/.next/static/chunks/7616-b8bd37ce1f735d6f.js +0 -1
  288. package/.next/static/chunks/786-9ed39f96091b2be4.js +0 -1
  289. package/.next/static/chunks/8273-922091226ba84a94.js +0 -1
  290. package/.next/static/chunks/8357.6159472717ff7d11.js +0 -1
  291. package/.next/static/chunks/9062-3eb1607c96486f88.js +0 -1
  292. package/.next/static/chunks/9380.93f361baab2eefdf.js +0 -1
  293. package/.next/static/chunks/app/_not-found/page-c3b87025baf0a9c2.js +0 -1
  294. package/.next/static/chunks/app/api/[...doc]/page-790c4b33ba1fde4a.js +0 -1
  295. package/.next/static/chunks/app/api/agent-requests/route-e83b12cbab2e8707.js +0 -1
  296. package/.next/static/chunks/app/api/apps/install/route-e83b12cbab2e8707.js +0 -1
  297. package/.next/static/chunks/app/api/apps/manifests/route-e83b12cbab2e8707.js +0 -1
  298. package/.next/static/chunks/app/api/apps/static/[...path]/route-e83b12cbab2e8707.js +0 -1
  299. package/.next/static/chunks/app/api/docs/plain/route-e83b12cbab2e8707.js +0 -1
  300. package/.next/static/chunks/app/api/events/route-e83b12cbab2e8707.js +0 -1
  301. package/.next/static/chunks/app/api/import-from-openclaw/[channel]/route-e83b12cbab2e8707.js +0 -1
  302. package/.next/static/chunks/app/api/import-from-openclaw/route-e83b12cbab2e8707.js +0 -1
  303. package/.next/static/chunks/app/api/import-from-openclaw/validate/[channel]/route-e83b12cbab2e8707.js +0 -1
  304. package/.next/static/chunks/app/api/page-b53f9aa17a4c5201.js +0 -1
  305. package/.next/static/chunks/app/api/restart/route-e83b12cbab2e8707.js +0 -1
  306. package/.next/static/chunks/app/api/update/route-e83b12cbab2e8707.js +0 -1
  307. package/.next/static/chunks/app/api/version/route-e83b12cbab2e8707.js +0 -1
  308. package/.next/static/chunks/app/api/workspace/[id]/apps/[wid]/route-e83b12cbab2e8707.js +0 -1
  309. package/.next/static/chunks/app/api/workspace/[id]/apps/route-e83b12cbab2e8707.js +0 -1
  310. package/.next/static/chunks/app/api/workspace/[id]/export/route-e83b12cbab2e8707.js +0 -1
  311. package/.next/static/chunks/app/api/workspace/[id]/route-e83b12cbab2e8707.js +0 -1
  312. package/.next/static/chunks/app/api/workspace/config/route-e83b12cbab2e8707.js +0 -1
  313. package/.next/static/chunks/app/api/workspace/import/route-e83b12cbab2e8707.js +0 -1
  314. package/.next/static/chunks/app/api/workspace/route-e83b12cbab2e8707.js +0 -1
  315. package/.next/static/chunks/app/app-legacy-do-not-use/page-0052191daef60036.js +0 -1
  316. package/.next/static/chunks/app/approve/[actionId]/page-45cd3b8fa062d5e5.js +0 -1
  317. package/.next/static/chunks/app/docs/[...doc]/page-632ac406200b66fe.js +0 -1
  318. package/.next/static/chunks/app/docs/page-b7556394709b43df.js +0 -1
  319. package/.next/static/chunks/app/error-3d6057da512253d8.js +0 -1
  320. package/.next/static/chunks/app/health/page-80c985cd72328b74.js +0 -1
  321. package/.next/static/chunks/app/hello/page-fd71babcd192729b.js +0 -1
  322. package/.next/static/chunks/app/layout-285c6ef3f16bae63.js +0 -1
  323. package/.next/static/chunks/app/page-85017185df14c37b.js +0 -1
  324. package/.next/static/chunks/app/privacy/page-faf36cd0dde6dfa3.js +0 -1
  325. package/.next/static/chunks/app/share/[token]/page-22d51d6c5a47bb75.js +0 -1
  326. package/.next/static/chunks/app/terms/page-faf36cd0dde6dfa3.js +0 -1
  327. package/.next/static/chunks/framework-e60c938074ff7136.js +0 -1
  328. package/.next/static/chunks/main-447abf206d7ebd2f.js +0 -1
  329. package/.next/static/chunks/main-app-f63b86bdbf5b7b88.js +0 -1
  330. package/.next/static/chunks/pages/_app-6c8c2371b16a04b8.js +0 -1
  331. package/.next/static/chunks/pages/_error-94812ad32cad7365.js +0 -1
  332. package/.next/static/css/eb25c6452113486f.css +0 -3
  333. package/.next/static/zCR6u3S4dIjlCtV80nNsp/_buildManifest.js +0 -1
  334. /package/.next/static/{zCR6u3S4dIjlCtV80nNsp → WshFGr6RxGYP6AbWuT9OG}/_ssgManifest.js +0 -0
@@ -47,7 +47,7 @@ type CreateCredentialStart = 'api-key-form' | 'type-picker';
47
47
  type CreatePrefill = {
48
48
  agentId?: string;
49
49
  tags?: string[];
50
- type?: 'login' | 'card' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
50
+ type?: 'login' | 'card' | 'sso' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
51
51
  name?: string;
52
52
  noteContent?: string;
53
53
  };
@@ -88,6 +88,9 @@ const SEARCH_FIELD_PRIORITY = [
88
88
  'cardholder',
89
89
  'brand',
90
90
  'last4',
91
+ 'website',
92
+ 'provider',
93
+ 'identifier',
91
94
  'token_endpoint',
92
95
  'scopes',
93
96
  'fingerprint',
@@ -751,6 +754,7 @@ export const CredentialAgent: React.FC<CredentialAgentProps> = ({
751
754
  all: base.length,
752
755
  login: base.filter((c) => c.type === 'login').length,
753
756
  card: base.filter((c) => c.type === 'card').length,
757
+ sso: base.filter((c) => c.type === 'sso').length,
754
758
  note: base.filter((c) => c.type === 'note').length,
755
759
  plain_note: base.filter((c) => c.type === 'plain_note').length,
756
760
  hot_wallet: base.filter((c) => c.type === 'hot_wallet').length,
@@ -130,6 +130,7 @@ export const CredentialDetail: React.FC<CredentialDetailProps> = ({
130
130
  const typeLabelMap: Record<string, string> = {
131
131
  login: 'Login',
132
132
  card: 'Card',
133
+ sso: 'SSO Login',
133
134
  note: 'Note',
134
135
  plain_note: 'Plain Note',
135
136
  hot_wallet: 'Hot Wallet',
@@ -327,6 +328,37 @@ export const CredentialDetail: React.FC<CredentialDetailProps> = ({
327
328
  </>
328
329
  )}
329
330
 
331
+ {credential.type === 'sso' && (
332
+ <>
333
+ <CredentialField
334
+ label="Website"
335
+ value={credential.meta.website as string | undefined}
336
+ credentialId={credential.id}
337
+ fieldKey={CREDENTIAL_FIELD_KEYS.sso.website}
338
+ isSensitive={false}
339
+ onShowLargeType={handleShowLargeType}
340
+ />
341
+ <CredentialField
342
+ label="Provider"
343
+ value={credential.meta.provider as string | undefined}
344
+ credentialId={credential.id}
345
+ fieldKey={CREDENTIAL_FIELD_KEYS.sso.provider}
346
+ isSensitive={false}
347
+ onShowLargeType={handleShowLargeType}
348
+ />
349
+ {credential.meta.identifier && (
350
+ <CredentialField
351
+ label="Identifier"
352
+ value={credential.meta.identifier as string | undefined}
353
+ credentialId={credential.id}
354
+ fieldKey={CREDENTIAL_FIELD_KEYS.sso.identifier}
355
+ isSensitive={false}
356
+ onShowLargeType={handleShowLargeType}
357
+ />
358
+ )}
359
+ </>
360
+ )}
361
+
330
362
  {credential.type === 'note' && (
331
363
  <CredentialField
332
364
  label="Content"
@@ -423,7 +455,6 @@ export const CredentialDetail: React.FC<CredentialDetailProps> = ({
423
455
  />
424
456
  </>
425
457
  )}
426
-
427
458
  {credential.type === 'ssh' && (
428
459
  <>
429
460
  <CredentialField label="Fingerprint" value={credential.meta.fingerprint as string | undefined} credentialId={credential.id} fieldKey={CREDENTIAL_FIELD_KEYS.ssh.fingerprint} isSensitive={false} onShowLargeType={handleShowLargeType} />
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
4
- import { Key, Eye, Loader2, CreditCard, FileText, RefreshCw, ArrowLeft, Wallet, Upload } from 'lucide-react';
4
+ import { Key, Eye, Loader2, CreditCard, FileText, RefreshCw, ArrowLeft, Wallet, Upload, Apple, Facebook, Chrome } from 'lucide-react';
5
5
  import { Button, TextInput, FilterDropdown, Modal, Toggle, ItemPicker } from '@/components/design-system';
6
6
  import { api, Api } from '@/lib/api';
7
7
  import { decryptCredentialPayload } from '@/lib/agent-crypto';
@@ -36,10 +36,11 @@ interface CredentialFormProps {
36
36
  };
37
37
  }
38
38
 
39
- type FormType = 'login' | 'card' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
39
+ type FormType = 'login' | 'card' | 'sso' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
40
40
 
41
41
  const LOGIN_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.login;
42
42
  const CARD_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.card;
43
+ const SSO_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.sso;
43
44
  const HOT_WALLET_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.hot_wallet;
44
45
  const APIKEY_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.apikey;
45
46
  const OAUTH2_FIELD_KEYS = CREDENTIAL_FIELD_KEYS.oauth2;
@@ -55,6 +56,7 @@ const TYPE_META: Record<FormType, {
55
56
  plain_note: { label: 'Plain Note', description: 'Readable note content stored without encryption', icon: FileText },
56
57
  apikey: { label: 'API Key', description: 'Simple key/value secret', icon: Key },
57
58
  login: { label: 'Login', description: 'Websites and app accounts', icon: Key },
59
+ sso: { label: 'SSO Login', description: 'Website + identity provider references', icon: RefreshCw },
58
60
  note: { label: 'Secure Note', description: 'Private notes and secrets', icon: FileText },
59
61
  card: { label: 'Credit Card', description: 'Payment cards and details', icon: CreditCard },
60
62
  oauth2: { label: 'OAuth2', description: 'Auto-refreshing OAuth2 tokens', icon: RefreshCw },
@@ -64,7 +66,7 @@ const TYPE_META: Record<FormType, {
64
66
  };
65
67
 
66
68
  const FEATURED_TYPE_ORDER: FormType[] = ['apikey', 'login', 'plain_note'];
67
- const REMAINING_TYPE_ORDER: FormType[] = ['custom', 'card', 'hot_wallet', 'note', 'oauth2', 'ssh', 'gpg'];
69
+ const REMAINING_TYPE_ORDER: FormType[] = ['custom', 'card', 'hot_wallet', 'sso', 'note', 'oauth2', 'ssh', 'gpg'];
68
70
  const MARKDOWN_NOTE_IMPORT_ACCEPT = '.md,.markdown,text/markdown';
69
71
 
70
72
  const escapeHtml = (value: string): string => value
@@ -86,6 +88,12 @@ const BRAND_OPTIONS = [
86
88
  { value: 'other', label: 'Other' },
87
89
  ];
88
90
 
91
+ const SSO_PROVIDER_OPTIONS = [
92
+ { value: 'apple', label: 'Apple', icon: <Apple size={14} /> },
93
+ { value: 'facebook', label: 'Facebook', icon: <Facebook size={14} /> },
94
+ { value: 'google', label: 'Google', icon: <Chrome size={14} /> },
95
+ ];
96
+
89
97
  const normalizeForRank = (value: string) => value.trim().toLowerCase();
90
98
 
91
99
  const toTimestamp = (updatedAt?: string, createdAt?: string) => {
@@ -133,6 +141,11 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
133
141
  const [billingZip, setBillingZip] = useState('');
134
142
  const [cardNotes, setCardNotes] = useState('');
135
143
 
144
+ // SSO fields
145
+ const [ssoWebsite, setSsoWebsite] = useState('');
146
+ const [ssoProvider, setSsoProvider] = useState('');
147
+ const [ssoIdentifier, setSsoIdentifier] = useState('');
148
+
136
149
  // Note fields
137
150
  const [noteContent, setNoteContent] = useState('');
138
151
 
@@ -280,6 +293,10 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
280
293
  setBrand((cred.meta[CARD_FIELD_KEYS.brand] as string) || 'visa');
281
294
  setCardLast4((cred.meta[CARD_FIELD_KEYS.last4] as string) || '');
282
295
  setBillingZip((cred.meta[CARD_FIELD_KEYS.billingZip] as string) || '');
296
+ } else if (cred.type === 'sso') {
297
+ setSsoWebsite((cred.meta[SSO_FIELD_KEYS.website] as string) || '');
298
+ setSsoProvider((cred.meta[SSO_FIELD_KEYS.provider] as string) || '');
299
+ setSsoIdentifier((cred.meta[SSO_FIELD_KEYS.identifier] as string) || '');
283
300
  } else if (cred.type === 'apikey') {
284
301
  setApiKeyName((cred.meta[APIKEY_FIELD_KEYS.key] as string) || '');
285
302
  setApiKeyValue((cred.meta[APIKEY_FIELD_KEYS.value] as string) || '');
@@ -565,6 +582,9 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
565
582
  setCvv('');
566
583
  setBillingZip('');
567
584
  setCardNotes('');
585
+ setSsoWebsite('');
586
+ setSsoProvider('');
587
+ setSsoIdentifier('');
568
588
  setNoteContent('');
569
589
  setHotWalletChain('base');
570
590
  setHotWalletAddress('');
@@ -699,6 +719,8 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
699
719
  cardholder,
700
720
  cardNumber,
701
721
  cardLast4,
722
+ ssoWebsite,
723
+ ssoProvider,
702
724
  oauth2TokenEndpoint,
703
725
  sshHostsInput,
704
726
  gpgKeyId,
@@ -712,6 +734,7 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
712
734
  if (type === 'plain_note' && !noteContent.trim()) return false;
713
735
  if (type === 'apikey' && (!apiKeyName.trim() || !apiKeyValue.trim())) return false;
714
736
  if (type === 'custom' && (!customFieldKey.trim() || !customFieldValue.trim())) return false;
737
+ if (type === 'sso' && (!ssoWebsite.trim() || !ssoProvider.trim())) return false;
715
738
  if (type === 'ssh' && !sshPrivateKey.trim() && !isEdit) return false;
716
739
  if (type === 'gpg' && !gpgPrivateKey.trim() && !isEdit) return false;
717
740
 
@@ -750,6 +773,8 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
750
773
  oauth2RefreshToken,
751
774
  oauth2TokenEndpoint,
752
775
  password,
776
+ ssoProvider,
777
+ ssoWebsite,
753
778
  sshHostsInput,
754
779
  sshPrivateKey,
755
780
  totpIntent,
@@ -775,6 +800,8 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
775
800
  cardNumber,
776
801
  cardBrand: brand,
777
802
  cardLast4: resolvedCardLast4,
803
+ ssoWebsite,
804
+ ssoProvider,
778
805
  oauth2TokenEndpoint,
779
806
  sshHostsInput,
780
807
  gpgKeyId,
@@ -816,6 +843,17 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
816
843
  [CARD_FIELD_KEYS.billingZip]: billingZip,
817
844
  };
818
845
  break;
846
+ case 'sso':
847
+ fields.push({ key: SSO_FIELD_KEYS.website, value: ssoWebsite.trim(), type: 'text', sensitive: false });
848
+ fields.push({ key: SSO_FIELD_KEYS.provider, value: ssoProvider.trim().toLowerCase(), type: 'text', sensitive: false });
849
+ fields.push({ key: SSO_FIELD_KEYS.identifier, value: ssoIdentifier.trim(), type: 'text', sensitive: false });
850
+ meta = {
851
+ ...meta,
852
+ [SSO_FIELD_KEYS.website]: ssoWebsite.trim(),
853
+ [SSO_FIELD_KEYS.provider]: ssoProvider.trim().toLowerCase(),
854
+ [SSO_FIELD_KEYS.identifier]: ssoIdentifier.trim(),
855
+ };
856
+ break;
819
857
  case 'note':
820
858
  fields.push({ key: NOTE_CONTENT_KEY, value: noteContent, type: 'text', sensitive: true });
821
859
  break;
@@ -906,15 +944,13 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
906
944
  cardholder,
907
945
  cardNumber,
908
946
  cardLast4,
947
+ ssoWebsite,
948
+ ssoProvider,
909
949
  oauth2TokenEndpoint,
910
950
  sshHostsInput,
911
951
  gpgKeyId,
912
952
  gpgUidEmail,
913
953
  });
914
- if (!name.trim() && !canDeriveName) {
915
- setError('Name is required');
916
- return;
917
- }
918
954
  if (type === 'login' && !isEdit && !password.trim()) {
919
955
  setError('Password is required for login');
920
956
  return;
@@ -935,6 +971,14 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
935
971
  setError('Primary key and value are required for custom type');
936
972
  return;
937
973
  }
974
+ if (type === 'sso' && !ssoWebsite.trim()) {
975
+ setError('Website is required for SSO login');
976
+ return;
977
+ }
978
+ if (type === 'sso' && !ssoProvider.trim()) {
979
+ setError('Provider is required for SSO login');
980
+ return;
981
+ }
938
982
  if (type === 'ssh' && !sshPrivateKey.trim() && !isEdit) {
939
983
  setError('SSH private key is required');
940
984
  return;
@@ -973,6 +1017,10 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
973
1017
  }
974
1018
  }
975
1019
  }
1020
+ if (!name.trim() && !canDeriveName) {
1021
+ setError('Name is required');
1022
+ return;
1023
+ }
976
1024
  setSaving(true);
977
1025
  setError(null);
978
1026
 
@@ -1325,6 +1373,45 @@ export const CredentialForm: React.FC<CredentialFormProps> = ({
1325
1373
  </div>
1326
1374
  )}
1327
1375
 
1376
+ {type === 'sso' && (
1377
+ <div className="space-y-3">
1378
+ <TextInput
1379
+ label="Website"
1380
+ value={ssoWebsite}
1381
+ onChange={(e) => setSsoWebsite(e.target.value)}
1382
+ placeholder="https://example.com"
1383
+ />
1384
+ <div className="space-y-1">
1385
+ <label className="block font-mono text-[9px] font-bold uppercase tracking-widest text-[var(--color-text-muted,#6b7280)]">
1386
+ Provider
1387
+ </label>
1388
+ <div data-testid="sso-provider-select">
1389
+ <ItemPicker
1390
+ ariaLabel="SSO Provider"
1391
+ options={SSO_PROVIDER_OPTIONS.map((providerOption) => ({
1392
+ value: providerOption.value,
1393
+ label: providerOption.label,
1394
+ description: `Sign in with ${providerOption.label}`,
1395
+ icon: providerOption.icon,
1396
+ }))}
1397
+ value={ssoProvider}
1398
+ onChange={(val) => setSsoProvider(String(val))}
1399
+ />
1400
+ </div>
1401
+ </div>
1402
+ {showGlobalAdvanced && (
1403
+ <div className="space-y-3 border border-[var(--color-border,#d4d4d8)] p-3 bg-[var(--color-background-alt,#f4f4f5)]">
1404
+ <TextInput
1405
+ label="Identifier (email/phone/username)"
1406
+ value={ssoIdentifier}
1407
+ onChange={(e) => setSsoIdentifier(e.target.value)}
1408
+ placeholder="alice@example.com"
1409
+ />
1410
+ </div>
1411
+ )}
1412
+ </div>
1413
+ )}
1414
+
1328
1415
  {type === 'note' && (
1329
1416
  <div>
1330
1417
  <div className="flex items-center justify-between mb-1.5 px-1">
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import React from 'react';
4
- import { Key, CreditCard, FileText, Star, RefreshCw, Terminal, ShieldCheck, Wallet } from 'lucide-react';
4
+ import { Key, CreditCard, FileText, Star, RefreshCw, Terminal, ShieldCheck, Wallet, Globe } from 'lucide-react';
5
5
  import type { CredentialMeta } from './types';
6
6
  import { getCredentialDisplayName } from './credentialDisplayName';
7
7
 
@@ -14,6 +14,7 @@ interface CredentialRowProps {
14
14
  const typeIcons: Record<string, React.FC<{ size: number; className?: string }>> = {
15
15
  login: Key,
16
16
  card: CreditCard,
17
+ sso: Globe,
17
18
  note: FileText,
18
19
  hot_wallet: Wallet,
19
20
  plain_note: FileText,
@@ -29,6 +30,12 @@ function getSubtitle(credential: CredentialMeta): string {
29
30
  return credential.meta.username || credential.meta.url || '';
30
31
  case 'card':
31
32
  return credential.meta.last4 ? `\u2022\u2022\u2022\u2022 ${credential.meta.last4}` : '';
33
+ case 'sso': {
34
+ const provider = String(credential.meta.provider || '').trim();
35
+ const website = String(credential.meta.website || '').trim();
36
+ if (provider && website) return `${provider} • ${website}`;
37
+ return provider || website || 'SSO Login';
38
+ }
32
39
  case 'note':
33
40
  return 'Secure Note';
34
41
  case 'hot_wallet':
@@ -1,4 +1,4 @@
1
- type FormType = 'login' | 'card' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
1
+ type FormType = 'login' | 'card' | 'sso' | 'note' | 'plain_note' | 'hot_wallet' | 'apikey' | 'oauth2' | 'ssh' | 'gpg' | 'custom';
2
2
 
3
3
  type NameInputs = {
4
4
  type: FormType;
@@ -13,6 +13,8 @@ type NameInputs = {
13
13
  cardNumber: string;
14
14
  cardBrand?: string;
15
15
  cardLast4?: string;
16
+ ssoWebsite?: string;
17
+ ssoProvider?: string;
16
18
  oauth2TokenEndpoint: string;
17
19
  sshHostsInput: string;
18
20
  gpgKeyId: string;
@@ -42,6 +44,12 @@ const deriveNoteTitleFromContent = (raw: string): string => {
42
44
  return firstNonEmptyLine.slice(0, 48);
43
45
  };
44
46
 
47
+ const formatSsoProviderLabel = (rawProvider: string): string => {
48
+ const normalized = rawProvider.trim().toLowerCase();
49
+ if (!normalized) return '';
50
+ return normalized.charAt(0).toUpperCase() + normalized.slice(1);
51
+ };
52
+
45
53
  export function deriveCredentialName(inputs: NameInputs): string {
46
54
  const {
47
55
  type,
@@ -55,6 +63,8 @@ export function deriveCredentialName(inputs: NameInputs): string {
55
63
  cardNumber,
56
64
  cardBrand,
57
65
  cardLast4,
66
+ ssoWebsite,
67
+ ssoProvider,
58
68
  oauth2TokenEndpoint,
59
69
  sshHostsInput,
60
70
  gpgKeyId,
@@ -64,6 +74,8 @@ export function deriveCredentialName(inputs: NameInputs): string {
64
74
  const safeCardNumber = cardNumber || '';
65
75
  const safeCardBrand = cardBrand || '';
66
76
  const safeCardLast4 = cardLast4 || '';
77
+ const safeSsoWebsite = ssoWebsite || '';
78
+ const safeSsoProvider = ssoProvider || '';
67
79
  const safeOauth2TokenEndpoint = oauth2TokenEndpoint || '';
68
80
  const safeGpgKeyId = gpgKeyId || '';
69
81
  const safeGpgUidEmail = gpgUidEmail || '';
@@ -76,6 +88,11 @@ export function deriveCredentialName(inputs: NameInputs): string {
76
88
  .split(/\n|,/)
77
89
  .map((host) => host.trim())
78
90
  .filter(Boolean);
91
+ const ssoProviderLabel = formatSsoProviderLabel(safeSsoProvider);
92
+ const ssoWebsiteValue = safeSsoWebsite.trim();
93
+ const ssoDisplayName = ssoProviderLabel && ssoWebsiteValue
94
+ ? `${ssoProviderLabel} (${ssoWebsiteValue})`
95
+ : ssoWebsiteValue || (ssoProviderLabel ? `${ssoProviderLabel} SSO` : 'SSO Login');
79
96
  const derivedNameByType: Partial<Record<FormType, string>> = {
80
97
  plain_note: deriveNoteTitleFromContent(noteContent),
81
98
  apikey: apiKeyName.trim(),
@@ -84,6 +101,7 @@ export function deriveCredentialName(inputs: NameInputs): string {
84
101
  hot_wallet: hotWalletChain.trim() ? `Hot Wallet (${hotWalletChain.trim().toUpperCase()})` : 'Hot Wallet',
85
102
  custom: customFieldKey.trim(),
86
103
  card: cardDisplayName,
104
+ sso: ssoDisplayName,
87
105
  oauth2: safeOauth2TokenEndpoint.trim() || 'OAuth2',
88
106
  ssh: trimmedHosts[0] || 'SSH Key',
89
107
  gpg: safeGpgKeyId.trim() || safeGpgUidEmail.trim() || 'GPG Key',
@@ -107,6 +125,8 @@ export function canDeriveName(inputs: Omit<NameInputs, 'name'>): boolean {
107
125
  cardholder,
108
126
  cardNumber,
109
127
  cardLast4,
128
+ ssoWebsite,
129
+ ssoProvider,
110
130
  oauth2TokenEndpoint,
111
131
  sshHostsInput,
112
132
  gpgKeyId,
@@ -121,6 +141,7 @@ export function canDeriveName(inputs: Omit<NameInputs, 'name'>): boolean {
121
141
  || (type === 'hot_wallet' && (!!hotWalletChain.trim() || true))
122
142
  || (type === 'custom' && !!customFieldKey.trim())
123
143
  || (type === 'card' && (!!cardholder?.trim() || !!cardNumber?.trim() || !!cardLast4?.trim()))
144
+ || (type === 'sso' && (!!ssoWebsite?.trim() || !!ssoProvider?.trim()))
124
145
  || (type === 'oauth2' && !!oauth2TokenEndpoint?.trim())
125
146
  || (type === 'ssh' && !!sshHostsInput?.trim())
126
147
  || (type === 'gpg' && (!!gpgKeyId?.trim() || !!gpgUidEmail?.trim()))
@@ -40,11 +40,11 @@ export interface WalletLinkMetaV1 {
40
40
  linkedAt: string;
41
41
  }
42
42
 
43
- export type CredentialType = 'login' | 'card' | 'note' | 'plain_note' | 'hot_wallet' | 'api' | 'apikey' | 'custom' | 'passkey' | 'oauth2' | 'ssh' | 'gpg';
43
+ export type CredentialType = 'login' | 'card' | 'sso' | 'note' | 'plain_note' | 'hot_wallet' | 'api' | 'apikey' | 'custom' | 'passkey' | 'oauth2' | 'ssh' | 'gpg';
44
44
  export type CredentialLifecycleFilter = 'active' | 'archive' | 'recently_deleted';
45
45
  export type CredentialWithLocation = CredentialMeta & { location: CredentialLifecycleFilter };
46
46
 
47
- export type CategoryFilter = 'all' | 'login' | 'card' | 'note' | 'plain_note' | 'hot_wallet' | 'api' | 'apikey' | 'custom' | 'passkey' | 'oauth2' | 'ssh' | 'gpg';
47
+ export type CategoryFilter = 'all' | 'login' | 'card' | 'sso' | 'note' | 'plain_note' | 'hot_wallet' | 'api' | 'apikey' | 'custom' | 'passkey' | 'oauth2' | 'ssh' | 'gpg';
48
48
 
49
49
  export interface AgentFilters {
50
50
  agentId: string | null;
@@ -109,8 +109,21 @@ export const Modal: React.FC<ModalProps> = ({
109
109
  '[tabindex]:not([tabindex="-1"])',
110
110
  ].join(',');
111
111
 
112
+ const isFocusableElement = (el: HTMLElement) => {
113
+ if (el.hasAttribute('disabled') || el.getAttribute('aria-disabled') === 'true') return false;
114
+ if (el.tabIndex === -1) return false;
115
+ if (el.closest('[inert]')) return false;
116
+ if (el.hasAttribute('hidden')) return false;
117
+ if (el instanceof HTMLInputElement && el.type === 'hidden') return false;
118
+
119
+ const computedStyle = window.getComputedStyle(el);
120
+ if (computedStyle.display === 'none' || computedStyle.visibility === 'hidden') return false;
121
+
122
+ return true;
123
+ };
124
+
112
125
  const getFocusable = () => Array.from(dialogEl.querySelectorAll<HTMLElement>(focusableSelector))
113
- .filter((el) => !el.hasAttribute('disabled') && el.tabIndex !== -1);
126
+ .filter(isFocusableElement);
114
127
 
115
128
  const initialFocusable = getFocusable();
116
129
  const priorityFocus = initialFocusable.find((el) => {
@@ -63,8 +63,24 @@ export function useUpdateChecker() {
63
63
  setState((prev) => ({ ...prev, updating: true, updateError: null, updateOutput: null }));
64
64
  try {
65
65
  const res = await fetch('/api/update', { method: 'POST' });
66
- const data = await res.json() as { success: boolean; output?: string; error?: string };
66
+ const data = await res.json() as {
67
+ success: boolean;
68
+ deferred?: boolean;
69
+ message?: string;
70
+ output?: string;
71
+ error?: string;
72
+ };
67
73
  if (data.success) {
74
+ if (data.deferred) {
75
+ setState((prev) => ({
76
+ ...prev,
77
+ updating: false,
78
+ updateOutput: data.output || data.message || 'Update started in background.',
79
+ updateError: null,
80
+ }));
81
+ return;
82
+ }
83
+
68
84
  setState((prev) => ({
69
85
  ...prev,
70
86
  updating: false,
package/src/lib/pino.ts CHANGED
@@ -1,13 +1,82 @@
1
1
  /**
2
- * Shared Pino logger instance for the WebSocket server (port 4748)
2
+ * Shared logger instance for the WebSocket server (port 4748).
3
3
  *
4
- * Keep this logger transport-free because it runs inside Next.js
5
- * instrumentation/server runtime where optional vendor chunks can
6
- * fail to resolve during startup.
4
+ * This module is imported by the Next.js instrumentation runtime.
5
+ * A static `import pino from 'pino'` can force a vendor chunk that may
6
+ * not exist in stale/incremental `.next` outputs, so we resolve it at runtime
7
+ * and fall back to a minimal console logger when needed.
7
8
  */
8
9
 
9
- import pino from 'pino';
10
+ type Level = 'debug' | 'info' | 'warn' | 'error';
10
11
 
11
- export const log = pino(
12
- { level: process.env.LOG_LEVEL || 'debug' },
13
- );
12
+ export interface LoggerLike {
13
+ child(bindings: Record<string, unknown>): LoggerLike;
14
+ debug(...args: unknown[]): void;
15
+ info(...args: unknown[]): void;
16
+ warn(...args: unknown[]): void;
17
+ error(...args: unknown[]): void;
18
+ }
19
+
20
+ function parseArgs(args: unknown[]): { data?: unknown; msg?: string } {
21
+ if (args.length === 0) return {};
22
+ if (typeof args[0] === 'string') {
23
+ return { msg: args[0] as string };
24
+ }
25
+ if (typeof args[1] === 'string') {
26
+ return { data: args[0], msg: args[1] as string };
27
+ }
28
+ return { data: args[0] };
29
+ }
30
+
31
+ function createConsoleLogger(bindings: Record<string, unknown> = {}): LoggerLike {
32
+ const emit = (level: Level, args: unknown[]) => {
33
+ const { data, msg } = parseArgs(args);
34
+ const payload = {
35
+ level,
36
+ component: 'ws',
37
+ ...bindings,
38
+ ...(data && typeof data === 'object' ? data as Record<string, unknown> : {}),
39
+ msg,
40
+ time: new Date().toISOString(),
41
+ };
42
+
43
+ const sink = level === 'error' ? console.error : level === 'warn' ? console.warn : console.log;
44
+ sink(payload);
45
+ };
46
+
47
+ return {
48
+ child(extraBindings: Record<string, unknown>) {
49
+ return createConsoleLogger({ ...bindings, ...extraBindings });
50
+ },
51
+ debug(...args: unknown[]) {
52
+ emit('debug', args);
53
+ },
54
+ info(...args: unknown[]) {
55
+ emit('info', args);
56
+ },
57
+ warn(...args: unknown[]) {
58
+ emit('warn', args);
59
+ },
60
+ error(...args: unknown[]) {
61
+ emit('error', args);
62
+ },
63
+ };
64
+ }
65
+
66
+ function createRuntimePinoLogger(): LoggerLike | null {
67
+ try {
68
+ const requireFn = new Function('return require')() as NodeRequire;
69
+ const maybeModule = requireFn('pino') as
70
+ | ((options?: Record<string, unknown>) => LoggerLike)
71
+ | { default?: (options?: Record<string, unknown>) => LoggerLike };
72
+ const pinoFactory =
73
+ typeof maybeModule === 'function' ? maybeModule : maybeModule.default;
74
+
75
+ if (!pinoFactory) return null;
76
+ return pinoFactory({ level: process.env.LOG_LEVEL || 'debug' });
77
+ } catch {
78
+ return null;
79
+ }
80
+ }
81
+
82
+ export const log: LoggerLike = createRuntimePinoLogger() ?? createConsoleLogger();
@@ -53,7 +53,7 @@ function showHelp(): void {
53
53
  ' --json JSON output',
54
54
  '',
55
55
  'Auth bootstrap options (when AURA_TOKEN is not set):',
56
- ' --profile <id> /auth fallback profile (default: strict)',
56
+ ' --profile <id> /auth fallback profile (default: trust.localProfile, then dev)',
57
57
  ' --profile-version <v> /auth fallback profile version (default: v1)',
58
58
  ' --profile-overrides <json> Tighten-only profile override JSON',
59
59
  '',