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,422 @@
1
+ /**
2
+ * Credential CRUD — Encrypted Credential File Management
3
+ * =======================================================
4
+ *
5
+ * Create, read, update, delete credential files in ~/.auramaxx/credentials/.
6
+ * Sensitive fields are encrypted with the vault's derived credential key.
7
+ * Non-sensitive metadata is stored as plaintext for search/filtering.
8
+ */
9
+
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { randomBytes } from 'crypto';
13
+ import { DATA_PATHS } from './config';
14
+ import { getCredentialVaultKey } from './credential-vault';
15
+ import { encryptWithSeed, decryptWithSeed } from './encrypt';
16
+ import { CredentialType, CredentialField, CredentialFile, EncryptedData } from '../types';
17
+
18
+ export type CredentialLocation = 'active' | 'archive' | 'recently_deleted';
19
+ const CREDENTIAL_ID_PATTERN = /^cred-[a-z0-9]{8}$/;
20
+
21
+ // ---------------------------------------------------------------------------
22
+ // ID generation
23
+ // ---------------------------------------------------------------------------
24
+
25
+ function generateCredentialId(): string {
26
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
27
+ const bytes = randomBytes(8);
28
+ let id = 'cred-';
29
+ for (let i = 0; i < 8; i++) {
30
+ id += chars[bytes[i] % chars.length];
31
+ }
32
+ return id;
33
+ }
34
+
35
+ export function isValidCredentialId(id: string): boolean {
36
+ return CREDENTIAL_ID_PATTERN.test(id);
37
+ }
38
+
39
+ function assertValidCredentialId(id: string): string {
40
+ const normalized = id.trim();
41
+ if (!isValidCredentialId(normalized)) {
42
+ throw new Error(`Invalid credential id: ${id}`);
43
+ }
44
+ return normalized;
45
+ }
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // File helpers
49
+ // ---------------------------------------------------------------------------
50
+
51
+ function getCredentialsDir(location: CredentialLocation): string {
52
+ if (location === 'archive') return DATA_PATHS.credentialsArchive;
53
+ if (location === 'recently_deleted') return DATA_PATHS.credentialsRecentlyDeleted;
54
+ return DATA_PATHS.credentials;
55
+ }
56
+
57
+ function getCredentialPath(id: string, location: CredentialLocation = 'active'): string {
58
+ const safeId = assertValidCredentialId(id);
59
+ const baseDir = path.resolve(getCredentialsDir(location));
60
+ const resolved = path.resolve(baseDir, `${safeId}.json`);
61
+ if (!resolved.startsWith(`${baseDir}${path.sep}`)) {
62
+ throw new Error(`Resolved credential path escapes base directory for id: ${id}`);
63
+ }
64
+ return resolved;
65
+ }
66
+
67
+ function readCredentialFile(id: string, location: CredentialLocation = 'active'): CredentialFile | null {
68
+ let filePath: string;
69
+ try {
70
+ filePath = getCredentialPath(id, location);
71
+ } catch {
72
+ return null;
73
+ }
74
+ if (!fs.existsSync(filePath)) return null;
75
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
76
+ }
77
+
78
+ function writeCredentialFile(cred: CredentialFile, location: CredentialLocation = 'active'): void {
79
+ const dir = getCredentialsDir(location);
80
+ if (!fs.existsSync(dir)) {
81
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
82
+ }
83
+ const filePath = getCredentialPath(cred.id, location);
84
+ fs.writeFileSync(filePath, JSON.stringify(cred, null, 2));
85
+ }
86
+
87
+ function moveCredentialFile(
88
+ id: string,
89
+ from: CredentialLocation,
90
+ to: CredentialLocation,
91
+ ): CredentialFile | null {
92
+ let sourcePath: string;
93
+ let destinationPath: string;
94
+ try {
95
+ sourcePath = getCredentialPath(id, from);
96
+ destinationPath = getCredentialPath(id, to);
97
+ } catch {
98
+ return null;
99
+ }
100
+ if (!fs.existsSync(sourcePath)) return null;
101
+
102
+ const destinationDir = getCredentialsDir(to);
103
+ if (!fs.existsSync(destinationDir)) {
104
+ fs.mkdirSync(destinationDir, { recursive: true, mode: 0o700 });
105
+ }
106
+
107
+ fs.renameSync(sourcePath, destinationPath);
108
+ return readCredentialFile(id, to);
109
+ }
110
+
111
+ // ---------------------------------------------------------------------------
112
+ // CRUD operations
113
+ // ---------------------------------------------------------------------------
114
+
115
+ /**
116
+ * Create a new credential.
117
+ * Encrypts sensitive fields with the vault's derived credential key.
118
+ */
119
+ export function createCredential(
120
+ vaultId: string,
121
+ type: CredentialType,
122
+ name: string,
123
+ meta: Record<string, unknown>,
124
+ sensitiveFields: CredentialField[]
125
+ ): CredentialFile {
126
+ const vaultKey = getCredentialVaultKey(vaultId);
127
+ if (!vaultKey) {
128
+ throw new Error(`Credential vault for ${vaultId} is locked`);
129
+ }
130
+
131
+ const id = generateCredentialId();
132
+ const now = new Date().toISOString();
133
+
134
+ const encrypted = encryptWithSeed(JSON.stringify(sensitiveFields), vaultKey);
135
+
136
+ // Store which sensitive keys exist so the UI can conditionally render fields
137
+ meta.sensitive_field_keys = sensitiveFields.map(f => f.key);
138
+
139
+ const cred: CredentialFile = {
140
+ id,
141
+ vaultId,
142
+ type,
143
+ name,
144
+ meta,
145
+ encrypted,
146
+ createdAt: now,
147
+ updatedAt: now,
148
+ };
149
+
150
+ writeCredentialFile(cred);
151
+ return cred;
152
+ }
153
+
154
+ /**
155
+ * Get credential metadata (no decryption).
156
+ */
157
+ export function getCredential(id: string, location: CredentialLocation = 'active'): CredentialFile | null {
158
+ return readCredentialFile(id, location);
159
+ }
160
+
161
+ export function findCredentialLocation(id: string): CredentialLocation | null {
162
+ if (readCredentialFile(id, 'active')) return 'active';
163
+ if (readCredentialFile(id, 'archive')) return 'archive';
164
+ if (readCredentialFile(id, 'recently_deleted')) return 'recently_deleted';
165
+ return null;
166
+ }
167
+
168
+ /**
169
+ * Decrypt and return the sensitive fields of a credential.
170
+ */
171
+ export function readCredentialSecrets(id: string, location: CredentialLocation = 'active'): CredentialField[] {
172
+ const cred = readCredentialFile(id, location);
173
+ if (!cred) {
174
+ throw new Error(`Credential not found: ${id}`);
175
+ }
176
+
177
+ const vaultKey = getCredentialVaultKey(cred.vaultId);
178
+ if (!vaultKey) {
179
+ throw new Error(`Credential vault for ${cred.vaultId} is locked`);
180
+ }
181
+
182
+ const decrypted = decryptWithSeed(cred.encrypted, vaultKey);
183
+ return JSON.parse(decrypted) as CredentialField[];
184
+ }
185
+
186
+ /**
187
+ * Update a credential's metadata and/or sensitive fields.
188
+ */
189
+ export function updateCredential(
190
+ id: string,
191
+ updates: {
192
+ name?: string;
193
+ meta?: Record<string, unknown>;
194
+ sensitiveFields?: CredentialField[];
195
+ }
196
+ ): CredentialFile {
197
+ const cred = readCredentialFile(id, 'active');
198
+ if (!cred) {
199
+ throw new Error(`Credential not found: ${id}`);
200
+ }
201
+
202
+ if (updates.name !== undefined) {
203
+ cred.name = updates.name;
204
+ }
205
+
206
+ if (updates.meta !== undefined) {
207
+ cred.meta = updates.meta;
208
+ }
209
+
210
+ if (updates.sensitiveFields !== undefined) {
211
+ const vaultKey = getCredentialVaultKey(cred.vaultId);
212
+ if (!vaultKey) {
213
+ throw new Error(`Credential vault for ${cred.vaultId} is locked`);
214
+ }
215
+ cred.encrypted = encryptWithSeed(JSON.stringify(updates.sensitiveFields), vaultKey);
216
+ // Update which sensitive keys exist so the UI can conditionally render fields
217
+ cred.meta.sensitive_field_keys = updates.sensitiveFields.map(f => f.key);
218
+ }
219
+
220
+ cred.updatedAt = new Date().toISOString();
221
+ writeCredentialFile(cred, 'active');
222
+ return cred;
223
+ }
224
+
225
+ /**
226
+ * Duplicate an existing credential.
227
+ * Decrypts the source credential's sensitive fields and re-encrypts them into a new credential.
228
+ */
229
+ export function duplicateCredential(
230
+ id: string,
231
+ overrides?: { name?: string; vaultId?: string },
232
+ ): CredentialFile {
233
+ const source = readCredentialFile(id, 'active');
234
+ if (!source) {
235
+ throw new Error(`Credential not found: ${id}`);
236
+ }
237
+
238
+ const sourceVaultKey = getCredentialVaultKey(source.vaultId);
239
+ if (!sourceVaultKey) {
240
+ throw new Error(`Credential vault for ${source.vaultId} is locked`);
241
+ }
242
+
243
+ const decrypted = decryptWithSeed(source.encrypted, sourceVaultKey);
244
+ const sensitiveFields: CredentialField[] = JSON.parse(decrypted);
245
+
246
+ const targetVaultId = overrides?.vaultId ?? source.vaultId;
247
+ const targetVaultKey = getCredentialVaultKey(targetVaultId);
248
+ if (!targetVaultKey) {
249
+ throw new Error(`Credential vault for ${targetVaultId} is locked`);
250
+ }
251
+
252
+ const newId = generateCredentialId();
253
+ const now = new Date().toISOString();
254
+ const newName = overrides?.name ?? `${source.name} (copy)`;
255
+ const meta = JSON.parse(JSON.stringify(source.meta));
256
+ const encrypted = encryptWithSeed(JSON.stringify(sensitiveFields), targetVaultKey);
257
+
258
+ const cred: CredentialFile = {
259
+ id: newId,
260
+ vaultId: targetVaultId,
261
+ type: source.type,
262
+ name: newName,
263
+ meta,
264
+ encrypted,
265
+ createdAt: now,
266
+ updatedAt: now,
267
+ };
268
+
269
+ writeCredentialFile(cred);
270
+ return cred;
271
+ }
272
+
273
+ /**
274
+ * Permanently delete a credential file in the given location.
275
+ */
276
+ export function deleteCredential(id: string, location: CredentialLocation = 'active'): boolean {
277
+ let filePath: string;
278
+ try {
279
+ filePath = getCredentialPath(id, location);
280
+ } catch {
281
+ return false;
282
+ }
283
+ if (!fs.existsSync(filePath)) return false;
284
+ fs.unlinkSync(filePath);
285
+ return true;
286
+ }
287
+
288
+ export function archiveCredential(id: string): CredentialFile | null {
289
+ const moved = moveCredentialFile(id, 'active', 'archive');
290
+ if (!moved) return null;
291
+
292
+ const now = new Date().toISOString();
293
+ moved.archivedAt = now;
294
+ delete moved.deletedAt;
295
+ moved.updatedAt = now;
296
+ writeCredentialFile(moved, 'archive');
297
+ return moved;
298
+ }
299
+
300
+ export function deleteArchivedCredential(id: string): CredentialFile | null {
301
+ const moved = moveCredentialFile(id, 'archive', 'recently_deleted');
302
+ if (!moved) return null;
303
+
304
+ const now = new Date().toISOString();
305
+ moved.archivedAt = moved.archivedAt || now;
306
+ moved.deletedAt = now;
307
+ moved.updatedAt = now;
308
+ writeCredentialFile(moved, 'recently_deleted');
309
+ return moved;
310
+ }
311
+
312
+ export function restoreArchivedCredential(id: string): CredentialFile | null {
313
+ const moved = moveCredentialFile(id, 'archive', 'active');
314
+ if (!moved) return null;
315
+
316
+ delete moved.archivedAt;
317
+ delete moved.deletedAt;
318
+ moved.updatedAt = new Date().toISOString();
319
+ writeCredentialFile(moved, 'active');
320
+ return moved;
321
+ }
322
+
323
+ export function restoreDeletedCredential(id: string): CredentialFile | null {
324
+ const moved = moveCredentialFile(id, 'recently_deleted', 'archive');
325
+ if (!moved) return null;
326
+
327
+ moved.archivedAt = moved.archivedAt || new Date().toISOString();
328
+ delete moved.deletedAt;
329
+ moved.updatedAt = new Date().toISOString();
330
+ writeCredentialFile(moved, 'archive');
331
+ return moved;
332
+ }
333
+
334
+ export function purgeDeletedCredentials(retentionDays = 30): {
335
+ scanned: number;
336
+ purged: number;
337
+ errors: Array<{ id: string; error: string }>;
338
+ } {
339
+ const dir = getCredentialsDir('recently_deleted');
340
+ if (!fs.existsSync(dir)) {
341
+ return { scanned: 0, purged: 0, errors: [] };
342
+ }
343
+
344
+ const cutoffMs = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
345
+ const files = fs.readdirSync(dir).filter(file => file.startsWith('cred-') && file.endsWith('.json'));
346
+ const errors: Array<{ id: string; error: string }> = [];
347
+ let purged = 0;
348
+
349
+ for (const file of files) {
350
+ const id = file.replace(/\.json$/, '');
351
+ try {
352
+ const cred = readCredentialFile(id, 'recently_deleted');
353
+ if (!cred) continue;
354
+
355
+ const deletedAt = cred.deletedAt || cred.updatedAt || cred.createdAt;
356
+ const deletedMs = Date.parse(deletedAt);
357
+ if (Number.isNaN(deletedMs)) continue;
358
+
359
+ if (deletedMs <= cutoffMs) {
360
+ deleteCredential(id, 'recently_deleted');
361
+ purged += 1;
362
+ }
363
+ } catch (error) {
364
+ errors.push({
365
+ id,
366
+ error: error instanceof Error ? error.message : 'Unknown error',
367
+ });
368
+ }
369
+ }
370
+
371
+ return {
372
+ scanned: files.length,
373
+ purged,
374
+ errors,
375
+ };
376
+ }
377
+
378
+ /**
379
+ * List credentials with optional filters.
380
+ * Returns metadata only (no decryption).
381
+ */
382
+ export function listCredentials(filters?: {
383
+ vaultId?: string;
384
+ type?: CredentialType;
385
+ tag?: string;
386
+ query?: string;
387
+ }, location: CredentialLocation = 'active'): CredentialFile[] {
388
+ const dir = getCredentialsDir(location);
389
+ if (!fs.existsSync(dir)) return [];
390
+
391
+ const files = fs.readdirSync(dir);
392
+ const results: CredentialFile[] = [];
393
+
394
+ for (const file of files) {
395
+ if (!file.startsWith('cred-') || !file.endsWith('.json')) continue;
396
+
397
+ try {
398
+ const raw = fs.readFileSync(path.join(dir, file), 'utf-8');
399
+ const cred: CredentialFile = JSON.parse(raw);
400
+
401
+ // Apply filters
402
+ if (filters?.vaultId && cred.vaultId !== filters.vaultId) continue;
403
+ if (filters?.type && cred.type !== filters.type) continue;
404
+ if (filters?.tag) {
405
+ const tags = (cred.meta.tags as string[] | undefined) || [];
406
+ if (!tags.some(t => t.toLowerCase() === filters.tag!.toLowerCase())) continue;
407
+ }
408
+ if (filters?.query) {
409
+ const q = filters.query.toLowerCase();
410
+ if (!cred.name.toLowerCase().includes(q) && !cred.id.toLowerCase().includes(q)) continue;
411
+ }
412
+
413
+ results.push(cred);
414
+ } catch {
415
+ // skip corrupt files
416
+ }
417
+ }
418
+
419
+ // Sort by updatedAt descending
420
+ results.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
421
+ return results;
422
+ }
@@ -0,0 +1,8 @@
1
+ import { createHash } from 'crypto';
2
+
3
+ /**
4
+ * Hash a secret for storage (we only store the hash, never the secret)
5
+ */
6
+ export function hashSecret(secret: string): string {
7
+ return createHash('sha256').update(secret).digest('hex');
8
+ }
@@ -0,0 +1,58 @@
1
+ import { PrismaClient } from '@prisma/client';
2
+ import { getDbUrl } from './config';
3
+
4
+ // The PrismaClient is created lazily on first access. This prevents the
5
+ // module-load-time side-effect that used to run:
6
+ //
7
+ // process.env.DATABASE_URL = getDbUrl(); // ← overwrites test env!
8
+ // export const prisma = new PrismaClient(); // ← connects immediately
9
+ //
10
+ // In tests, workerSetup.ts sets DATABASE_URL to a per-worker path *before*
11
+ // test files are imported. If db.ts eagerly resolves the URL at import time,
12
+ // it can race with the worker setup and hit the real ~/.auramaxx/ database.
13
+ //
14
+ // With a lazy getter the URL is resolved on first query — long after the test
15
+ // environment is fully configured.
16
+
17
+ const globalForPrisma = globalThis as unknown as {
18
+ prisma: PrismaClient | undefined;
19
+ };
20
+
21
+ function createPrismaClient(): PrismaClient {
22
+ const url = getDbUrl();
23
+
24
+ // Safety: never let a test worker connect to the real database.
25
+ // The .env file at the project root contains DATABASE_URL pointing to
26
+ // ~/.auramaxx/auramaxx.db. If Prisma's dotenv loading wins the race
27
+ // against workerSetup.ts, we'd silently hit production data.
28
+ if (process.env.VITEST || process.env.NODE_ENV === 'test') {
29
+ if (!url.includes('test-data') && !url.includes('test.db')) {
30
+ throw new Error(
31
+ `SAFETY: db.ts refusing to connect to non-test database in test mode!\n` +
32
+ ` Resolved URL: ${url}\n` +
33
+ ` Expected a URL containing 'test-data' or 'test.db'.\n` +
34
+ ` Check that workerSetup.ts ran before this module was first accessed.`
35
+ );
36
+ }
37
+ }
38
+
39
+ // Keep process.env in sync so other code that reads it directly still works
40
+ process.env.DATABASE_URL = url;
41
+ return new PrismaClient({
42
+ datasources: { db: { url } },
43
+ });
44
+ }
45
+
46
+ let _lazyPrisma: PrismaClient | undefined = globalForPrisma.prisma;
47
+
48
+ export const prisma = new Proxy({} as PrismaClient, {
49
+ get(_target, prop, receiver) {
50
+ if (!_lazyPrisma) {
51
+ _lazyPrisma = createPrismaClient();
52
+ if (process.env.NODE_ENV !== 'production') {
53
+ globalForPrisma.prisma = _lazyPrisma;
54
+ }
55
+ }
56
+ return Reflect.get(_lazyPrisma, prop, receiver);
57
+ },
58
+ });