auramaxx 0.0.1

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 (418) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +77 -0
  3. package/apps/desktop-electron/main.js +428 -0
  4. package/bin/auramaxx.js +1063 -0
  5. package/docs/ADAPTERS.md +466 -0
  6. package/docs/AGENT_SETUP.md +159 -0
  7. package/docs/API.md +127 -0
  8. package/docs/APPS.md +199 -0
  9. package/docs/ARCHITECTURE.md +235 -0
  10. package/docs/AUTH.md +318 -0
  11. package/docs/BEST-PRACTICES.md +82 -0
  12. package/docs/CLI.md +141 -0
  13. package/docs/DESKTOP_ELECTRON.md +26 -0
  14. package/docs/DEVELOPING-APPS.md +453 -0
  15. package/docs/MCP.md +122 -0
  16. package/docs/PACKAGING_POLICY.md +19 -0
  17. package/docs/PERMISSION.md +137 -0
  18. package/docs/PROTOCOL.md +142 -0
  19. package/docs/README.md +50 -0
  20. package/docs/SKILLS.md +132 -0
  21. package/docs/TROUBLESHOOTING.md +376 -0
  22. package/docs/WORKSPACE.md +673 -0
  23. package/docs/agent-auth.md +14 -0
  24. package/docs/api/authentication.md +79 -0
  25. package/docs/api/secrets/api-keys.md +28 -0
  26. package/docs/api/secrets/credentials.md +80 -0
  27. package/docs/api/secrets/sharing.md +48 -0
  28. package/docs/api/system.md +41 -0
  29. package/docs/api/wallets/apps-strategies.md +66 -0
  30. package/docs/api/wallets/core.md +46 -0
  31. package/docs/api/wallets/data-portfolio.md +42 -0
  32. package/docs/aura-file.md +48 -0
  33. package/docs/core-concepts/FEATURES.md +114 -0
  34. package/docs/credentials.md +120 -0
  35. package/docs/external/HOW_TO_AURAMAXX/GETTING_SECRETS.md +33 -0
  36. package/docs/external/HOW_TO_AURAMAXX/README.md +45 -0
  37. package/docs/external/getting-started.md +10 -0
  38. package/docs/external/overview.md +19 -0
  39. package/docs/external/persona-paths.md +7 -0
  40. package/docs/external/share-secret.md +76 -0
  41. package/docs/external/why-aura.md +7 -0
  42. package/docs/security.md +227 -0
  43. package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
  44. package/docs/wallet/AI.md +508 -0
  45. package/docs/wallet/DEVELOPING-STRATEGIES.md +713 -0
  46. package/docs/wallet/README.md +47 -0
  47. package/docs/wallet/STRATEGY.md +89 -0
  48. package/next.config.ts +28 -0
  49. package/package.json +167 -0
  50. package/postcss.config.mjs +8 -0
  51. package/prisma/migrations/20260214170000_baseline/migration.sql +511 -0
  52. package/prisma/migrations/20260216214537_add_passkey_model/migration.sql +18 -0
  53. package/prisma/migrations/20260217150500_add_credential_access_audit/migration.sql +31 -0
  54. package/prisma/migrations/20260222090000_update_admin_ttl_default/migration.sql +10 -0
  55. package/prisma/migrations/migration_lock.toml +3 -0
  56. package/prisma/schema.prisma +447 -0
  57. package/public/logo.webp +0 -0
  58. package/scripts/add-app.js +245 -0
  59. package/server/abi/SwapHelper.json +438 -0
  60. package/server/cli/approval.ts +447 -0
  61. package/server/cli/commands/actions.ts +474 -0
  62. package/server/cli/commands/api.ts +220 -0
  63. package/server/cli/commands/apikey.ts +277 -0
  64. package/server/cli/commands/app.ts +204 -0
  65. package/server/cli/commands/auth.ts +464 -0
  66. package/server/cli/commands/cron.ts +24 -0
  67. package/server/cli/commands/diary.ts +274 -0
  68. package/server/cli/commands/doctor.ts +1247 -0
  69. package/server/cli/commands/env.ts +476 -0
  70. package/server/cli/commands/experimental.ts +69 -0
  71. package/server/cli/commands/init.ts +798 -0
  72. package/server/cli/commands/lock.ts +157 -0
  73. package/server/cli/commands/mcp.ts +285 -0
  74. package/server/cli/commands/quickhack.ts +86 -0
  75. package/server/cli/commands/release-check.ts +231 -0
  76. package/server/cli/commands/restore.ts +314 -0
  77. package/server/cli/commands/service.ts +320 -0
  78. package/server/cli/commands/shell-hook.ts +512 -0
  79. package/server/cli/commands/skill.ts +216 -0
  80. package/server/cli/commands/start.ts +139 -0
  81. package/server/cli/commands/status.ts +59 -0
  82. package/server/cli/commands/stop.ts +36 -0
  83. package/server/cli/commands/token.ts +180 -0
  84. package/server/cli/commands/unlock.ts +50 -0
  85. package/server/cli/commands/vault.ts +1323 -0
  86. package/server/cli/commands/wallet.ts +209 -0
  87. package/server/cli/index.ts +280 -0
  88. package/server/cli/lib/approval-poll.ts +94 -0
  89. package/server/cli/lib/aura-parser.ts +64 -0
  90. package/server/cli/lib/credential-create.ts +74 -0
  91. package/server/cli/lib/credential-resolve.ts +280 -0
  92. package/server/cli/lib/dotenv-migrate.ts +116 -0
  93. package/server/cli/lib/dotenv-parser.ts +146 -0
  94. package/server/cli/lib/escalation.ts +57 -0
  95. package/server/cli/lib/http.ts +91 -0
  96. package/server/cli/lib/init-steps.ts +76 -0
  97. package/server/cli/lib/local-agent-trust.ts +45 -0
  98. package/server/cli/lib/lock-unlock-helper.ts +71 -0
  99. package/server/cli/lib/process.ts +162 -0
  100. package/server/cli/lib/prompt.ts +294 -0
  101. package/server/cli/lib/theme.ts +240 -0
  102. package/server/cli/socket.ts +579 -0
  103. package/server/cli/transport-client.ts +50 -0
  104. package/server/cron/index.ts +137 -0
  105. package/server/cron/job.ts +31 -0
  106. package/server/cron/jobs/balance-sync.ts +436 -0
  107. package/server/cron/jobs/incoming-scan.ts +506 -0
  108. package/server/cron/jobs/native-price.ts +70 -0
  109. package/server/cron/jobs/orphan-cleanup.ts +40 -0
  110. package/server/cron/jobs/strategy-runner.ts +175 -0
  111. package/server/cron/scheduler.ts +125 -0
  112. package/server/index.ts +420 -0
  113. package/server/lib/adapters/factory.ts +119 -0
  114. package/server/lib/adapters/index.ts +19 -0
  115. package/server/lib/adapters/router.ts +297 -0
  116. package/server/lib/adapters/telegram.ts +645 -0
  117. package/server/lib/adapters/types.ts +89 -0
  118. package/server/lib/adapters/webhook.ts +95 -0
  119. package/server/lib/address.ts +49 -0
  120. package/server/lib/agent-auth/contracts.ts +1194 -0
  121. package/server/lib/agent-profiles.ts +419 -0
  122. package/server/lib/ai.ts +285 -0
  123. package/server/lib/api-registry/contracts.ts +86 -0
  124. package/server/lib/api-registry/validation.ts +172 -0
  125. package/server/lib/apikey-migration.ts +258 -0
  126. package/server/lib/app-installer.ts +505 -0
  127. package/server/lib/app-tokens.ts +247 -0
  128. package/server/lib/approval-link.ts +27 -0
  129. package/server/lib/auth.ts +314 -0
  130. package/server/lib/auto-execute.ts +160 -0
  131. package/server/lib/batch.ts +242 -0
  132. package/server/lib/cold.ts +1048 -0
  133. package/server/lib/config.ts +408 -0
  134. package/server/lib/credential-access-audit.ts +85 -0
  135. package/server/lib/credential-access-policy.ts +111 -0
  136. package/server/lib/credential-health.ts +343 -0
  137. package/server/lib/credential-import.ts +608 -0
  138. package/server/lib/credential-scope.ts +102 -0
  139. package/server/lib/credential-shares.ts +190 -0
  140. package/server/lib/credential-transport.ts +533 -0
  141. package/server/lib/credential-vault.ts +77 -0
  142. package/server/lib/credentials.ts +422 -0
  143. package/server/lib/crypto.ts +8 -0
  144. package/server/lib/db.ts +58 -0
  145. package/server/lib/defaults.ts +386 -0
  146. package/server/lib/dex/index.ts +80 -0
  147. package/server/lib/dex/relay.ts +235 -0
  148. package/server/lib/dex/types.ts +59 -0
  149. package/server/lib/dex/uniswap.ts +370 -0
  150. package/server/lib/diary.ts +34 -0
  151. package/server/lib/dont-ask-again-policy.ts +41 -0
  152. package/server/lib/e2e-agent/artifacts.ts +36 -0
  153. package/server/lib/e2e-agent/contracts.ts +112 -0
  154. package/server/lib/e2e-agent/validation.ts +135 -0
  155. package/server/lib/encrypt.ts +114 -0
  156. package/server/lib/error.ts +20 -0
  157. package/server/lib/events.ts +217 -0
  158. package/server/lib/feature-flags.ts +93 -0
  159. package/server/lib/hot.ts +357 -0
  160. package/server/lib/human-action-summary.ts +80 -0
  161. package/server/lib/key-fingerprint.ts +28 -0
  162. package/server/lib/logger.ts +340 -0
  163. package/server/lib/network.ts +137 -0
  164. package/server/lib/notifications.ts +230 -0
  165. package/server/lib/oauth2-refresh.ts +241 -0
  166. package/server/lib/oursecret.ts +71 -0
  167. package/server/lib/passkey-credential.ts +360 -0
  168. package/server/lib/passkey.ts +68 -0
  169. package/server/lib/permissions.ts +299 -0
  170. package/server/lib/pino.ts +24 -0
  171. package/server/lib/policy-preview.ts +138 -0
  172. package/server/lib/price.ts +338 -0
  173. package/server/lib/prices.ts +34 -0
  174. package/server/lib/project-scope.ts +297 -0
  175. package/server/lib/resolve-action.ts +328 -0
  176. package/server/lib/resolve.ts +36 -0
  177. package/server/lib/secret-gist-share.ts +296 -0
  178. package/server/lib/sessions.ts +634 -0
  179. package/server/lib/socket-path.ts +56 -0
  180. package/server/lib/solana/connection.ts +26 -0
  181. package/server/lib/solana/jupiter.ts +128 -0
  182. package/server/lib/solana/transfer.ts +108 -0
  183. package/server/lib/solana/wallet.ts +136 -0
  184. package/server/lib/strategy/emits.ts +21 -0
  185. package/server/lib/strategy/engine.ts +1305 -0
  186. package/server/lib/strategy/executor.ts +115 -0
  187. package/server/lib/strategy/hook-context.ts +159 -0
  188. package/server/lib/strategy/hooks.ts +990 -0
  189. package/server/lib/strategy/index.ts +28 -0
  190. package/server/lib/strategy/installer.ts +305 -0
  191. package/server/lib/strategy/loader.ts +256 -0
  192. package/server/lib/strategy/message.ts +237 -0
  193. package/server/lib/strategy/repository.ts +218 -0
  194. package/server/lib/strategy/session-logger.ts +693 -0
  195. package/server/lib/strategy/sources.ts +288 -0
  196. package/server/lib/strategy/state.ts +189 -0
  197. package/server/lib/strategy/templates.ts +403 -0
  198. package/server/lib/strategy/tick.ts +404 -0
  199. package/server/lib/strategy/types.ts +230 -0
  200. package/server/lib/swap.ts +3 -0
  201. package/server/lib/temp.ts +86 -0
  202. package/server/lib/token-metadata.ts +86 -0
  203. package/server/lib/token-safety.ts +200 -0
  204. package/server/lib/token-search.ts +444 -0
  205. package/server/lib/totp.ts +194 -0
  206. package/server/lib/transactions.ts +123 -0
  207. package/server/lib/transport.ts +84 -0
  208. package/server/lib/txhistory/decoder.ts +262 -0
  209. package/server/lib/txhistory/enricher.ts +652 -0
  210. package/server/lib/txhistory/index.ts +391 -0
  211. package/server/lib/txhistory/signatures.ts +59 -0
  212. package/server/lib/update-check.ts +35 -0
  213. package/server/lib/verified-summary.ts +414 -0
  214. package/server/lib/view-registry.ts +80 -0
  215. package/server/mcp/profile-policy.ts +30 -0
  216. package/server/mcp/server.ts +1589 -0
  217. package/server/mcp/tools.ts +276 -0
  218. package/server/middleware/auth.ts +119 -0
  219. package/server/middleware/requestLogger.ts +84 -0
  220. package/server/routes/actions.ts +539 -0
  221. package/server/routes/adapters.ts +711 -0
  222. package/server/routes/addressbook.ts +113 -0
  223. package/server/routes/ai.ts +34 -0
  224. package/server/routes/apikeys.ts +343 -0
  225. package/server/routes/apps.ts +601 -0
  226. package/server/routes/auth.ts +406 -0
  227. package/server/routes/backup.ts +404 -0
  228. package/server/routes/batch.ts +270 -0
  229. package/server/routes/bookmarks.ts +162 -0
  230. package/server/routes/credential-shares.ts +380 -0
  231. package/server/routes/credential-vaults.ts +159 -0
  232. package/server/routes/credentials.ts +1782 -0
  233. package/server/routes/dashboard.ts +97 -0
  234. package/server/routes/defaults.ts +124 -0
  235. package/server/routes/flags.ts +11 -0
  236. package/server/routes/fund.ts +225 -0
  237. package/server/routes/heartbeat.ts +375 -0
  238. package/server/routes/import.ts +364 -0
  239. package/server/routes/launch.ts +665 -0
  240. package/server/routes/lock.ts +54 -0
  241. package/server/routes/logs.ts +68 -0
  242. package/server/routes/nuke.ts +111 -0
  243. package/server/routes/passkey-credentials.ts +99 -0
  244. package/server/routes/passkey.ts +366 -0
  245. package/server/routes/portfolio.ts +217 -0
  246. package/server/routes/price.ts +63 -0
  247. package/server/routes/resolve.ts +31 -0
  248. package/server/routes/security.ts +45 -0
  249. package/server/routes/send-evm.ts +241 -0
  250. package/server/routes/send-solana.ts +281 -0
  251. package/server/routes/send.ts +178 -0
  252. package/server/routes/setup.ts +210 -0
  253. package/server/routes/strategy.ts +894 -0
  254. package/server/routes/swap-evm.ts +352 -0
  255. package/server/routes/swap-solana.ts +176 -0
  256. package/server/routes/swap.ts +356 -0
  257. package/server/routes/token.ts +247 -0
  258. package/server/routes/unlock.ts +467 -0
  259. package/server/routes/views.ts +41 -0
  260. package/server/routes/wallet-assets.ts +361 -0
  261. package/server/routes/wallet-transactions.ts +515 -0
  262. package/server/routes/wallet.ts +709 -0
  263. package/server/types.ts +146 -0
  264. package/shared/credential-field-schema.ts +248 -0
  265. package/skills/auramaxx/HEARTBEAT.md +78 -0
  266. package/skills/auramaxx/SKILL.md +745 -0
  267. package/skills/auramaxx/docs/AGENT_SETUP.md +155 -0
  268. package/skills/auramaxx/docs/API.md +127 -0
  269. package/skills/auramaxx/docs/AUTH.md +318 -0
  270. package/skills/auramaxx/docs/CLI.md +130 -0
  271. package/skills/auramaxx/docs/MCP.md +122 -0
  272. package/skills/auramaxx/docs/TROUBLESHOOTING.md +357 -0
  273. package/skills/auramaxx/docs/WORKSPACE.md +673 -0
  274. package/skills/auramaxx/docs/security.md +227 -0
  275. package/skills/task-lifecycle/SKILL.md +378 -0
  276. package/src/app/api/[...doc]/page.tsx +36 -0
  277. package/src/app/api/agent-requests/route.ts +30 -0
  278. package/src/app/api/apps/install/route.ts +132 -0
  279. package/src/app/api/apps/manifests/route.ts +16 -0
  280. package/src/app/api/apps/static/[...path]/route.ts +57 -0
  281. package/src/app/api/docs/plain/route.ts +74 -0
  282. package/src/app/api/events/route.ts +92 -0
  283. package/src/app/api/page.tsx +290 -0
  284. package/src/app/api/workspace/[id]/apps/[wid]/route.ts +119 -0
  285. package/src/app/api/workspace/[id]/apps/route.ts +81 -0
  286. package/src/app/api/workspace/[id]/export/route.ts +67 -0
  287. package/src/app/api/workspace/[id]/route.ts +168 -0
  288. package/src/app/api/workspace/auth.ts +40 -0
  289. package/src/app/api/workspace/config/route.ts +121 -0
  290. package/src/app/api/workspace/import/route.ts +127 -0
  291. package/src/app/api/workspace/route.ts +116 -0
  292. package/src/app/app-legacy-do-not-use/page.tsx +2245 -0
  293. package/src/app/apple-icon.png +0 -0
  294. package/src/app/approve/[actionId]/page.tsx +409 -0
  295. package/src/app/docs/DocsPageContent.tsx +269 -0
  296. package/src/app/docs/[...doc]/page.tsx +41 -0
  297. package/src/app/docs/page.tsx +38 -0
  298. package/src/app/favicon.ico +0 -0
  299. package/src/app/globals.css +819 -0
  300. package/src/app/health/page.tsx +5 -0
  301. package/src/app/hello/page.tsx +102 -0
  302. package/src/app/icon.png +0 -0
  303. package/src/app/layout.tsx +39 -0
  304. package/src/app/page.tsx +1964 -0
  305. package/src/app/privacy/page.tsx +63 -0
  306. package/src/app/providers.tsx +87 -0
  307. package/src/app/share/[token]/page.tsx +295 -0
  308. package/src/app/terms/page.tsx +80 -0
  309. package/src/components/ChainSelector.tsx +44 -0
  310. package/src/components/HumanActionBar.tsx +697 -0
  311. package/src/components/NotificationDrawer.tsx +387 -0
  312. package/src/components/PasskeyEnrollmentPrompt.tsx +235 -0
  313. package/src/components/apps/AgentKeysApp.tsx +490 -0
  314. package/src/components/apps/App.tsx +153 -0
  315. package/src/components/apps/AppGrid.tsx +15 -0
  316. package/src/components/apps/DetailedAddressDrawer.tsx +325 -0
  317. package/src/components/apps/DraggableApp.tsx +562 -0
  318. package/src/components/apps/IFrameApp.tsx +73 -0
  319. package/src/components/apps/LogsApp.tsx +360 -0
  320. package/src/components/apps/SendApp.tsx +394 -0
  321. package/src/components/apps/SetupWizardApp.tsx +1004 -0
  322. package/src/components/apps/SystemDefaultsApp.tsx +845 -0
  323. package/src/components/apps/ThirdPartyApp.tsx +428 -0
  324. package/src/components/apps/TokenApp.tsx +319 -0
  325. package/src/components/apps/TransactionsApp.tsx +438 -0
  326. package/src/components/apps/WalletDetailApp.tsx +1505 -0
  327. package/src/components/apps/index.ts +13 -0
  328. package/src/components/design-system/Button.tsx +88 -0
  329. package/src/components/design-system/ChainIndicator.tsx +65 -0
  330. package/src/components/design-system/ChainSelector.tsx +147 -0
  331. package/src/components/design-system/ConfirmationModal.tsx +107 -0
  332. package/src/components/design-system/ConfirmationPopover.tsx +81 -0
  333. package/src/components/design-system/DownloadButton.tsx +149 -0
  334. package/src/components/design-system/Drawer.tsx +133 -0
  335. package/src/components/design-system/FilterDropdown.tsx +183 -0
  336. package/src/components/design-system/ItemPicker.tsx +157 -0
  337. package/src/components/design-system/Modal.tsx +296 -0
  338. package/src/components/design-system/Popover.tsx +142 -0
  339. package/src/components/design-system/TextInput.tsx +85 -0
  340. package/src/components/design-system/Toggle.tsx +65 -0
  341. package/src/components/design-system/TyvekCollapsibleSection.tsx +55 -0
  342. package/src/components/design-system/index.ts +14 -0
  343. package/src/components/docs/ClientSideMarkdown.tsx +51 -0
  344. package/src/components/docs/DocsSearchBar.tsx +118 -0
  345. package/src/components/docs/DocsThemeToggle.tsx +38 -0
  346. package/src/components/docs/PersistentDocGroup.tsx +91 -0
  347. package/src/components/docs/ShareUrlButton.tsx +33 -0
  348. package/src/components/docs/SidebarScrollMemory.tsx +56 -0
  349. package/src/components/health/CredentialHealthDashboard.tsx +214 -0
  350. package/src/components/icons/ChainIcons.tsx +72 -0
  351. package/src/components/layout/AppStoreDrawer.tsx +369 -0
  352. package/src/components/layout/ContentArea.tsx +21 -0
  353. package/src/components/layout/CreateViewModal.tsx +88 -0
  354. package/src/components/layout/LeftRail.tsx +114 -0
  355. package/src/components/layout/TabBar.tsx +284 -0
  356. package/src/components/layout/WalletSidebar.tsx +1030 -0
  357. package/src/components/layout/index.ts +6 -0
  358. package/src/components/marketing/AuraMaxxSpecOverlay.tsx +653 -0
  359. package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
  360. package/src/components/vault/ApiKeysConsole.tsx +1272 -0
  361. package/src/components/vault/AuditConsole.tsx +600 -0
  362. package/src/components/vault/CredentialDetail.tsx +625 -0
  363. package/src/components/vault/CredentialEmpty.tsx +55 -0
  364. package/src/components/vault/CredentialField.tsx +583 -0
  365. package/src/components/vault/CredentialForm.tsx +1484 -0
  366. package/src/components/vault/CredentialList.tsx +265 -0
  367. package/src/components/vault/CredentialRow.tsx +130 -0
  368. package/src/components/vault/CredentialShareModal.tsx +273 -0
  369. package/src/components/vault/CredentialVault.tsx +1662 -0
  370. package/src/components/vault/CredentialWalletWidget.tsx +103 -0
  371. package/src/components/vault/DocsConsole.tsx +113 -0
  372. package/src/components/vault/ImportCredentialsModal.tsx +578 -0
  373. package/src/components/vault/LargeTypeModal.tsx +88 -0
  374. package/src/components/vault/PasswordGenerator.tsx +232 -0
  375. package/src/components/vault/TOTPDisplay.tsx +108 -0
  376. package/src/components/vault/TotpSetupPanel.tsx +198 -0
  377. package/src/components/vault/VaultSidebar.tsx +881 -0
  378. package/src/components/vault/credentialFormName.ts +91 -0
  379. package/src/components/vault/hooks/useVaultKeyboardShortcuts.ts +69 -0
  380. package/src/components/vault/types.ts +56 -0
  381. package/src/context/AuthContext.tsx +365 -0
  382. package/src/context/PriceContext.tsx +113 -0
  383. package/src/context/ThemeContext.tsx +164 -0
  384. package/src/context/WebSocketContext.tsx +269 -0
  385. package/src/context/WorkspaceContext.tsx +668 -0
  386. package/src/hooks/index.ts +4 -0
  387. package/src/hooks/useAgentActions.ts +552 -0
  388. package/src/hooks/useBalance.ts +103 -0
  389. package/src/hooks/useBalances.ts +129 -0
  390. package/src/hooks/useTheme.ts +156 -0
  391. package/src/instrumentation.ts +12 -0
  392. package/src/lib/api-docs.ts +154 -0
  393. package/src/lib/api.ts +474 -0
  394. package/src/lib/app-loader.ts +148 -0
  395. package/src/lib/app-registry.ts +178 -0
  396. package/src/lib/app-sdk.ts +157 -0
  397. package/src/lib/audit-console-adapter.ts +151 -0
  398. package/src/lib/auth-client.ts +75 -0
  399. package/src/lib/config.ts +74 -0
  400. package/src/lib/credential-field-schema.ts +11 -0
  401. package/src/lib/crypto.ts +112 -0
  402. package/src/lib/db.ts +21 -0
  403. package/src/lib/docs.ts +544 -0
  404. package/src/lib/events.ts +363 -0
  405. package/src/lib/pino.ts +24 -0
  406. package/src/lib/theme-handlers.ts +168 -0
  407. package/src/lib/theme.ts +351 -0
  408. package/src/lib/tokenData.ts +378 -0
  409. package/src/lib/totp-import.ts +57 -0
  410. package/src/lib/vault-crypto.ts +129 -0
  411. package/src/lib/view-registry.ts +57 -0
  412. package/src/lib/websocket-server.ts +302 -0
  413. package/src/lib/websocket-setup.ts +79 -0
  414. package/src/lib/wordlist.ts +2050 -0
  415. package/src/lib/workspace-handlers.ts +285 -0
  416. package/start.sh +170 -0
  417. package/tailwind.config.ts +99 -0
  418. package/tsconfig.json +42 -0
@@ -0,0 +1,164 @@
1
+ 'use client';
2
+
3
+ import {
4
+ createContext,
5
+ useContext,
6
+ useEffect,
7
+ useState,
8
+ useCallback,
9
+ ReactNode,
10
+ } from 'react';
11
+ import {
12
+ Theme,
13
+ DEFAULT_LIGHT_THEME,
14
+ getThemeById,
15
+ applyThemeToCSSVariables,
16
+ createThemeWithAccent,
17
+ } from '@/lib/theme';
18
+ import { useWebSocket } from './WebSocketContext';
19
+ import { THEME_EVENTS, createThemeEvent } from '@/lib/events';
20
+
21
+ interface ThemeContextValue {
22
+ theme: Theme;
23
+ mode: 'light' | 'dark';
24
+ accent: string;
25
+ setMode: (mode: 'light' | 'dark') => void;
26
+ setAccent: (accent: string) => void;
27
+ toggleMode: () => void;
28
+ }
29
+
30
+ const ThemeContext = createContext<ThemeContextValue | null>(null);
31
+
32
+ interface ThemeProviderProps {
33
+ children: ReactNode;
34
+ }
35
+
36
+ export function ThemeProvider({ children }: ThemeProviderProps) {
37
+ const { subscribe, send, connected } = useWebSocket();
38
+
39
+ const [mode, setModeState] = useState<'light' | 'dark'>('light');
40
+ const [accent, setAccentState] = useState('#ccff00');
41
+ const [theme, setTheme] = useState<Theme>(DEFAULT_LIGHT_THEME);
42
+ const [initialized, setInitialized] = useState(false);
43
+
44
+ // Request theme from server on connect
45
+ useEffect(() => {
46
+ if (connected && !initialized) {
47
+ const requestId = `theme-init-${Date.now()}`;
48
+ send(
49
+ createThemeEvent(
50
+ THEME_EVENTS.THEME_REQUEST,
51
+ { requestId },
52
+ 'ui'
53
+ )
54
+ );
55
+ }
56
+ }, [connected, initialized, send]);
57
+
58
+ // Subscribe to theme events
59
+ useEffect(() => {
60
+ const unsubscribe = subscribe(THEME_EVENTS.THEME_RESPONSE, (event) => {
61
+ if (event.type === THEME_EVENTS.THEME_RESPONSE) {
62
+ const data = event.data as {
63
+ activeThemeId: string;
64
+ accentColor: string;
65
+ mode: 'light' | 'dark';
66
+ };
67
+ setModeState(data.mode);
68
+ setAccentState(data.accentColor);
69
+ setInitialized(true);
70
+ }
71
+ });
72
+
73
+ return unsubscribe;
74
+ }, [subscribe]);
75
+
76
+ // Subscribe to mode changes from other clients/agents
77
+ useEffect(() => {
78
+ const unsubscribe = subscribe(THEME_EVENTS.THEME_MODE_CHANGED, (event) => {
79
+ if (event.type === THEME_EVENTS.THEME_MODE_CHANGED) {
80
+ const data = event.data as { mode: 'light' | 'dark' };
81
+ setModeState(data.mode);
82
+ }
83
+ });
84
+
85
+ return unsubscribe;
86
+ }, [subscribe]);
87
+
88
+ // Subscribe to accent changes from other clients/agents
89
+ useEffect(() => {
90
+ const unsubscribe = subscribe(THEME_EVENTS.THEME_ACCENT_CHANGED, (event) => {
91
+ if (event.type === THEME_EVENTS.THEME_ACCENT_CHANGED) {
92
+ const data = event.data as { accent: string };
93
+ setAccentState(data.accent);
94
+ }
95
+ });
96
+
97
+ return unsubscribe;
98
+ }, [subscribe]);
99
+
100
+ // Update theme object when mode or accent changes
101
+ useEffect(() => {
102
+ const baseTheme = getThemeById(mode);
103
+ const newTheme = createThemeWithAccent(baseTheme, accent);
104
+ setTheme(newTheme);
105
+ applyThemeToCSSVariables(newTheme);
106
+ }, [mode, accent]);
107
+
108
+ // Set mode and broadcast to other clients
109
+ const setMode = useCallback(
110
+ (newMode: 'light' | 'dark') => {
111
+ setModeState(newMode);
112
+ send(
113
+ createThemeEvent(
114
+ THEME_EVENTS.THEME_MODE_CHANGED,
115
+ { mode: newMode },
116
+ 'ui'
117
+ )
118
+ );
119
+ },
120
+ [send]
121
+ );
122
+
123
+ // Set accent and broadcast to other clients
124
+ const setAccent = useCallback(
125
+ (newAccent: string) => {
126
+ setAccentState(newAccent);
127
+ send(
128
+ createThemeEvent(
129
+ THEME_EVENTS.THEME_ACCENT_CHANGED,
130
+ { accent: newAccent },
131
+ 'ui'
132
+ )
133
+ );
134
+ },
135
+ [send]
136
+ );
137
+
138
+ // Toggle between light and dark mode
139
+ const toggleMode = useCallback(() => {
140
+ const newMode = mode === 'light' ? 'dark' : 'light';
141
+ setMode(newMode);
142
+ }, [mode, setMode]);
143
+
144
+ const value: ThemeContextValue = {
145
+ theme,
146
+ mode,
147
+ accent,
148
+ setMode,
149
+ setAccent,
150
+ toggleMode,
151
+ };
152
+
153
+ return (
154
+ <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
155
+ );
156
+ }
157
+
158
+ export function useTheme(): ThemeContextValue {
159
+ const context = useContext(ThemeContext);
160
+ if (!context) {
161
+ throw new Error('useTheme must be used within a ThemeProvider');
162
+ }
163
+ return context;
164
+ }
@@ -0,0 +1,269 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, useEffect, useRef, useState, useCallback, ReactNode } from 'react';
4
+ import type { WalletEvent, WalletEventType, WorkspaceEvent, WorkspaceEventType, ThemeEvent, ThemeEventType } from '@/lib/events';
5
+
6
+ type AnyEvent = WalletEvent | WorkspaceEvent | ThemeEvent;
7
+ type AnyEventType = WalletEventType | WorkspaceEventType | ThemeEventType | '*';
8
+ type EventCallback = (event: AnyEvent) => void;
9
+
10
+ interface WebSocketContextValue {
11
+ connected: boolean;
12
+ reconnected: boolean;
13
+ dismissReconnected: () => void;
14
+ subscribe: (eventType: AnyEventType, callback: EventCallback) => () => void;
15
+ send: (event: WorkspaceEvent | ThemeEvent) => void;
16
+ lastEvent: AnyEvent | null;
17
+ }
18
+
19
+ const WebSocketContext = createContext<WebSocketContextValue | null>(null);
20
+
21
+ // Reconnection settings
22
+ const INITIAL_RECONNECT_DELAY = 1000;
23
+ const MAX_RECONNECT_DELAY = 30000;
24
+ const RECONNECT_MULTIPLIER = 1.5;
25
+
26
+ interface WebSocketProviderProps {
27
+ children: ReactNode;
28
+ url?: string;
29
+ token?: string | null; // Auth token for workspace mutations
30
+ }
31
+
32
+ export function WebSocketProvider({
33
+ children,
34
+ url = typeof window !== 'undefined'
35
+ ? ['localhost', '127.0.0.1', '::1'].includes(window.location.hostname)
36
+ // Force IPv4 loopback in local dev to avoid localhost/::1 resolution failures.
37
+ ? `ws://127.0.0.1:${parseInt(window.location.port || '4747', 10) + 1}`
38
+ : `wss://wallet-ws.${window.location.hostname.split('.').slice(1).join('.')}`
39
+ : `ws://127.0.0.1:${parseInt(process.env.DASHBOARD_PORT || '4747', 10) + 1}`,
40
+ token,
41
+ }: WebSocketProviderProps) {
42
+ const [connected, setConnected] = useState(false);
43
+ const [reconnected, setReconnected] = useState(false);
44
+ const [lastEvent, setLastEvent] = useState<AnyEvent | null>(null);
45
+
46
+ const wsRef = useRef<WebSocket | null>(null);
47
+ const subscribersRef = useRef<Map<string, Set<EventCallback>>>(new Map());
48
+ const reconnectDelayRef = useRef(INITIAL_RECONNECT_DELAY);
49
+ const reconnectTimeoutRef = useRef<NodeJS.Timeout | null>(null);
50
+ const mountedRef = useRef(true);
51
+ // Track whether we've had a successful connection before (to distinguish reconnect from first connect)
52
+ const hasConnectedRef = useRef(false);
53
+ // Track whether we were disconnected (to detect reconnection vs token-change reconnect)
54
+ const wasDisconnectedRef = useRef(false);
55
+
56
+ // Use refs to avoid stale closures in callbacks
57
+ const urlRef = useRef(url);
58
+ const tokenRef = useRef(token);
59
+
60
+ // Track connection version to ignore stale onclose handlers
61
+ const connectionVersionRef = useRef(0);
62
+
63
+ // Update refs when props change
64
+ useEffect(() => {
65
+ urlRef.current = url;
66
+ }, [url]);
67
+
68
+ // Send a message to the WebSocket server
69
+ const send = useCallback((event: WorkspaceEvent | ThemeEvent) => {
70
+ if (wsRef.current?.readyState === WebSocket.OPEN) {
71
+ wsRef.current.send(JSON.stringify(event));
72
+ }
73
+ // Silently drop messages when not connected - this can happen during reconnection
74
+ }, []);
75
+
76
+ // Subscribe to events
77
+ const subscribe = useCallback((eventType: AnyEventType, callback: EventCallback) => {
78
+ if (!subscribersRef.current.has(eventType)) {
79
+ subscribersRef.current.set(eventType, new Set());
80
+ }
81
+ subscribersRef.current.get(eventType)!.add(callback);
82
+
83
+ // Return unsubscribe function
84
+ return () => {
85
+ const subscribers = subscribersRef.current.get(eventType);
86
+ if (subscribers) {
87
+ subscribers.delete(callback);
88
+ if (subscribers.size === 0) {
89
+ subscribersRef.current.delete(eventType);
90
+ }
91
+ }
92
+ };
93
+ }, []);
94
+
95
+ // Notify subscribers of an event
96
+ const notifySubscribers = useCallback((event: AnyEvent) => {
97
+ // Notify specific event type subscribers
98
+ const typeSubscribers = subscribersRef.current.get(event.type);
99
+ if (typeSubscribers) {
100
+ typeSubscribers.forEach((callback) => callback(event));
101
+ }
102
+
103
+ // Notify wildcard subscribers
104
+ const wildcardSubscribers = subscribersRef.current.get('*');
105
+ if (wildcardSubscribers) {
106
+ wildcardSubscribers.forEach((callback) => callback(event));
107
+ }
108
+ }, []);
109
+
110
+ // Connect to WebSocket - stable function that reads from refs
111
+ const connect = useCallback(() => {
112
+ if (!mountedRef.current) return;
113
+
114
+ // Clear any pending reconnect
115
+ if (reconnectTimeoutRef.current) {
116
+ clearTimeout(reconnectTimeoutRef.current);
117
+ reconnectTimeoutRef.current = null;
118
+ }
119
+
120
+ // Close existing connection if any
121
+ if (wsRef.current) {
122
+ const state = wsRef.current.readyState;
123
+ if (state === WebSocket.OPEN || state === WebSocket.CONNECTING) {
124
+ wsRef.current.close();
125
+ wsRef.current = null;
126
+ }
127
+ }
128
+
129
+ // Increment version to ignore stale onclose handlers
130
+ connectionVersionRef.current += 1;
131
+ const thisVersion = connectionVersionRef.current;
132
+
133
+ // Get current values from refs
134
+ const currentUrl = urlRef.current;
135
+ const currentToken = tokenRef.current;
136
+
137
+ try {
138
+ const ws = new WebSocket(currentUrl);
139
+ wsRef.current = ws;
140
+
141
+ ws.onopen = () => {
142
+ if (!mountedRef.current || connectionVersionRef.current !== thisVersion) return;
143
+ // Send auth token as first message (instead of URL query param)
144
+ if (currentToken) {
145
+ ws.send(JSON.stringify({ type: 'auth', token: currentToken }));
146
+ }
147
+ // Detect reconnection after a disconnect (server restart)
148
+ if (hasConnectedRef.current && wasDisconnectedRef.current) {
149
+ setReconnected(true);
150
+ }
151
+ hasConnectedRef.current = true;
152
+ wasDisconnectedRef.current = false;
153
+ setConnected(true);
154
+ reconnectDelayRef.current = INITIAL_RECONNECT_DELAY;
155
+ };
156
+
157
+ ws.onmessage = (messageEvent) => {
158
+ if (!mountedRef.current) return;
159
+ try {
160
+ const event = JSON.parse(messageEvent.data) as AnyEvent;
161
+
162
+ // Skip connection confirmation messages
163
+ if ((event as { type: string }).type === 'connected') {
164
+ return;
165
+ }
166
+
167
+ setLastEvent(event);
168
+ notifySubscribers(event);
169
+ } catch (err) {
170
+ console.error('[WS] Failed to parse message:', err);
171
+ }
172
+ };
173
+
174
+ ws.onclose = () => {
175
+ // Ignore if this is a stale connection
176
+ if (connectionVersionRef.current !== thisVersion) return;
177
+ if (!mountedRef.current) return;
178
+
179
+ wasDisconnectedRef.current = true;
180
+ setConnected(false);
181
+ wsRef.current = null;
182
+
183
+ // Schedule reconnect with exponential backoff
184
+ const delay = reconnectDelayRef.current;
185
+ reconnectDelayRef.current = Math.min(
186
+ delay * RECONNECT_MULTIPLIER,
187
+ MAX_RECONNECT_DELAY
188
+ );
189
+
190
+ reconnectTimeoutRef.current = setTimeout(connect, delay);
191
+ };
192
+
193
+ ws.onerror = () => {
194
+ // Browser WebSocket error events are opaque (`{}`); onclose handles retry.
195
+ };
196
+ } catch (err) {
197
+ console.error('[WS] Failed to connect:', err);
198
+ // Schedule reconnect
199
+ const delay = reconnectDelayRef.current;
200
+ reconnectDelayRef.current = Math.min(
201
+ delay * RECONNECT_MULTIPLIER,
202
+ MAX_RECONNECT_DELAY
203
+ );
204
+ reconnectTimeoutRef.current = setTimeout(connect, delay);
205
+ }
206
+ }, [notifySubscribers]); // Stable - only depends on stable notifySubscribers
207
+
208
+ // Handle token changes - reconnect with new token
209
+ useEffect(() => {
210
+ const oldToken = tokenRef.current;
211
+ tokenRef.current = token;
212
+
213
+ // If token actually changed, reconnect (even if no active connection yet)
214
+ if (oldToken !== token) {
215
+ // Small delay to ensure initial connection attempt has started
216
+ setTimeout(() => {
217
+ if (mountedRef.current) {
218
+ connect();
219
+ }
220
+ }, 100);
221
+ }
222
+ }, [token, connect]);
223
+
224
+ // Connect on mount, cleanup on unmount
225
+ useEffect(() => {
226
+ mountedRef.current = true;
227
+ tokenRef.current = token;
228
+ connect();
229
+
230
+ return () => {
231
+ mountedRef.current = false;
232
+ if (reconnectTimeoutRef.current) {
233
+ clearTimeout(reconnectTimeoutRef.current);
234
+ }
235
+ if (wsRef.current) {
236
+ wsRef.current.close();
237
+ wsRef.current = null;
238
+ }
239
+ };
240
+ // eslint-disable-next-line react-hooks/exhaustive-deps
241
+ }, []); // Only run on mount/unmount
242
+
243
+ const dismissReconnected = useCallback(() => {
244
+ setReconnected(false);
245
+ }, []);
246
+
247
+ const value: WebSocketContextValue = {
248
+ connected,
249
+ reconnected,
250
+ dismissReconnected,
251
+ subscribe,
252
+ send,
253
+ lastEvent,
254
+ };
255
+
256
+ return (
257
+ <WebSocketContext.Provider value={value}>
258
+ {children}
259
+ </WebSocketContext.Provider>
260
+ );
261
+ }
262
+
263
+ export function useWebSocket(): WebSocketContextValue {
264
+ const context = useContext(WebSocketContext);
265
+ if (!context) {
266
+ throw new Error('useWebSocket must be used within a WebSocketProvider');
267
+ }
268
+ return context;
269
+ }