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,447 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ generator client {
5
+ provider = "prisma-client-js"
6
+ }
7
+
8
+ datasource db {
9
+ provider = "sqlite"
10
+ url = env("DATABASE_URL")
11
+ }
12
+
13
+ model Log {
14
+ id String @id @default(cuid())
15
+ walletAddress String
16
+ title String
17
+ description String?
18
+ txHash String?
19
+ createdAt DateTime @default(now())
20
+
21
+ @@index([walletAddress])
22
+ @@index([createdAt])
23
+ }
24
+
25
+ model HotWallet {
26
+ id String @id @default(cuid())
27
+ address String @unique
28
+ encryptedPrivateKey String // Encrypted with in-memory seed
29
+ tokenHash String // Which auth token owns this wallet
30
+ coldWalletId String? // Vault ID (null = primary vault)
31
+
32
+ // Decorative fields
33
+ name String?
34
+ color String? // Hex color e.g. "#FF5733"
35
+ description String?
36
+ emoji String? // e.g. "🔥"
37
+ hidden Boolean @default(false)
38
+
39
+ chain String @default("base")
40
+ createdAt DateTime @default(now())
41
+
42
+ @@index([address])
43
+ @@index([tokenHash])
44
+ @@index([hidden])
45
+ @@index([coldWalletId])
46
+ }
47
+
48
+ model HumanAction {
49
+ id String @id @default(cuid())
50
+ type String // 'fund' | 'send' | 'agent_access' | 'action' | 'app:approve'
51
+ fromTier String // 'cold' | 'hot' | 'temp' | 'system'
52
+ toAddress String?
53
+ amount String?
54
+ chain String
55
+ status String @default("pending") // 'pending' | 'approved' | 'rejected'
56
+ createdAt DateTime @default(now())
57
+ resolvedAt DateTime?
58
+ metadata String? // JSON string for flexible metadata
59
+ notification Notification?
60
+
61
+ @@index([status])
62
+ @@index([createdAt])
63
+ }
64
+
65
+ model Notification {
66
+ id String @id @default(cuid())
67
+ type String // 'pending_approval' | 'info' | 'warning' | 'success' | 'error' | 'system'
68
+ category String? // 'transaction' | 'security' | 'token' | 'wallet' | 'general'
69
+ title String
70
+ message String
71
+ read Boolean @default(false)
72
+ dismissed Boolean @default(false)
73
+ actions String? // JSON: [{ id, label, type, action, endpoint, href }]
74
+ metadata String? // JSON for flexible data
75
+ humanActionId String? @unique
76
+ humanAction HumanAction? @relation(fields: [humanActionId], references: [id])
77
+ expiresAt DateTime?
78
+ createdAt DateTime @default(now())
79
+ updatedAt DateTime @updatedAt
80
+ source String @default("system") // 'system' | 'agent' | 'user'
81
+ agentId String?
82
+
83
+ @@index([read, dismissed])
84
+ @@index([type])
85
+ @@index([createdAt])
86
+ }
87
+
88
+ // Stores all WebSocket events for debugging and audit trail
89
+ model Event {
90
+ id String @id @default(cuid())
91
+ type String // e.g., 'request:created', 'token:revoked'
92
+ source String // 'express' | 'nextjs'
93
+ data String // JSON payload
94
+ timestamp DateTime @default(now())
95
+ createdAt DateTime @default(now())
96
+
97
+ @@index([type])
98
+ @@index([timestamp])
99
+ @@index([source])
100
+ }
101
+
102
+ // Stores token metadata for UI/logs - actual signing stays in memory
103
+ model AgentToken {
104
+ id String @id @default(cuid())
105
+ tokenHash String @unique // Hash of token for identification (not the token itself)
106
+ agentId String
107
+ limit Float // Max spending limit in ETH
108
+ spent Float @default(0)
109
+ permissions String // JSON array of permissions
110
+ expiresAt DateTime
111
+ isRevoked Boolean @default(false)
112
+ revokedAt DateTime?
113
+ createdAt DateTime @default(now())
114
+ lastUsedAt DateTime?
115
+
116
+ @@index([agentId])
117
+ @@index([isRevoked])
118
+ @@index([expiresAt])
119
+ }
120
+
121
+ model CredentialAccessAudit {
122
+ id String @id @default(cuid())
123
+ timestamp DateTime @default(now())
124
+ credentialId String
125
+ vaultId String
126
+ action String
127
+ allowed Boolean
128
+ result String
129
+ reasonCode String
130
+ httpStatus Int
131
+ tokenHash String?
132
+ agentId String?
133
+ requestId String?
134
+ actorType String
135
+ projectScope String?
136
+ sensitiveRead Boolean @default(true)
137
+ metadata String?
138
+
139
+ @@index([credentialId, timestamp(sort: Desc)])
140
+ @@index([tokenHash, timestamp(sort: Desc)])
141
+ @@index([allowed, timestamp(sort: Desc)])
142
+ @@index([reasonCode, timestamp(sort: Desc)])
143
+ }
144
+
145
+ // Workspace system for programmatic dashboard control
146
+ model Workspace {
147
+ id String @id @default(cuid())
148
+ name String
149
+ slug String @unique
150
+ icon String? // Lucide icon name
151
+ emoji String? // Emoji character e.g. "🚀"
152
+ color String? // Hex color code e.g. "#ff4d00"
153
+ order Int @default(0)
154
+ isDefault Boolean @default(false)
155
+ isCloseable Boolean @default(true)
156
+ createdAt DateTime @default(now())
157
+ updatedAt DateTime @updatedAt
158
+ apps WorkspaceApp[]
159
+ theme WorkspaceTheme?
160
+ }
161
+
162
+ model WorkspaceApp {
163
+ id String @id @default(cuid())
164
+ workspaceId String
165
+ workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
166
+
167
+ appType String // 'wallets' | 'logs' | 'iframe' | 'installed:app-id'
168
+ x Int @default(20)
169
+ y Int @default(20)
170
+ width Int @default(320)
171
+ height Int @default(280)
172
+ zIndex Int @default(10)
173
+ isVisible Boolean @default(true)
174
+ isLocked Boolean @default(false)
175
+ config String? // JSON for iframe url, installed app props, etc.
176
+
177
+ createdAt DateTime @default(now())
178
+ updatedAt DateTime @updatedAt
179
+
180
+ @@index([workspaceId])
181
+ }
182
+
183
+ // Global theme configuration
184
+ model ThemeConfig {
185
+ id String @id @default("global")
186
+ activeThemeId String @default("light")
187
+ accentColor String @default("#ccff00")
188
+ customThemes String? // JSON array of custom themes
189
+ createdAt DateTime @default(now())
190
+ updatedAt DateTime @updatedAt
191
+ }
192
+
193
+ // Per-workspace theme overrides
194
+ model WorkspaceTheme {
195
+ id String @id @default(cuid())
196
+ workspaceId String @unique
197
+ workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
198
+ mode String? // 'light' | 'dark' - null means inherit from global
199
+ accent String? // Hex color - null means inherit from global
200
+ overrides String? // JSON for app palette overrides
201
+ createdAt DateTime @default(now())
202
+ updatedAt DateTime @updatedAt
203
+ }
204
+
205
+ // API Keys for external services (Alchemy, etc.)
206
+ model ApiKey {
207
+ id String @id @default(cuid())
208
+ service String // 'alchemy' | 'infura' | 'etherscan' | etc.
209
+ name String // Display name e.g. "My Alchemy Key"
210
+ key String // The actual API key (stored encrypted in production)
211
+ metadata String? // JSON for service-specific config (e.g., allowed chains)
212
+ isActive Boolean @default(true)
213
+ createdAt DateTime @default(now())
214
+ updatedAt DateTime @updatedAt
215
+
216
+ @@unique([service, name])
217
+ @@index([service])
218
+ @@index([isActive])
219
+ }
220
+
221
+ // Transaction history for wallets
222
+ model Transaction {
223
+ id String @id @default(cuid())
224
+ walletAddress String
225
+ txHash String?
226
+ type String // 'send' | 'receive' | 'swap' | 'contract' | 'manual'
227
+ status String @default("confirmed")
228
+ amount String? // ETH amount
229
+ tokenAddress String? // Token contract address if applicable
230
+ tokenAmount String? // Token amount if applicable
231
+ from String?
232
+ to String?
233
+ description String?
234
+ blockNumber Int?
235
+ chain String @default("base")
236
+ createdAt DateTime @default(now())
237
+ updatedAt DateTime @updatedAt
238
+ executedAt DateTime?
239
+
240
+ @@unique([txHash, chain])
241
+ @@index([walletAddress])
242
+ @@index([walletAddress, createdAt])
243
+ @@index([type])
244
+ @@index([tokenAddress])
245
+ }
246
+
247
+ // Tracked assets (tokens) for wallets
248
+ model TrackedAsset {
249
+ id String @id @default(cuid())
250
+ walletAddress String?
251
+ tokenAddress String
252
+ symbol String?
253
+ name String?
254
+ decimals Int @default(18)
255
+ lastBalance String?
256
+ lastBalanceAt DateTime?
257
+ isHidden Boolean @default(false)
258
+ chain String @default("base")
259
+ poolAddress String? // Cached pool address for price lookup
260
+ poolVersion String? // "v2" | "v3" | "v4"
261
+ icon String? // Token icon URL
262
+ createdAt DateTime @default(now())
263
+ updatedAt DateTime @updatedAt
264
+
265
+ @@unique([walletAddress, tokenAddress, chain])
266
+ @@index([walletAddress])
267
+ @@index([walletAddress, updatedAt])
268
+ @@index([tokenAddress])
269
+ }
270
+
271
+ // Cached native balances (ETH/SOL) per wallet per chain
272
+ model NativeBalance {
273
+ id String @id @default(cuid())
274
+ walletAddress String
275
+ chain String
276
+ balance String
277
+ updatedAt DateTime @updatedAt
278
+
279
+ @@unique([walletAddress, chain])
280
+ @@index([walletAddress])
281
+ }
282
+
283
+ // Cached native currency prices (ETH, SOL → USD)
284
+ model NativePrice {
285
+ currency String @id // "ETH" | "SOL"
286
+ priceUsd String
287
+ updatedAt DateTime @updatedAt
288
+ }
289
+
290
+ // Balance sync state per chain
291
+ model SyncState {
292
+ id String @id @default(cuid())
293
+ chain String @unique
294
+ lastSyncAt DateTime?
295
+ lastSyncStatus String @default("idle")
296
+ lastError String?
297
+ syncCount Int @default(0)
298
+ lastBlock String? // Block cursor for event scanning jobs (stringified bigint)
299
+ updatedAt DateTime @updatedAt
300
+ }
301
+
302
+ // First-class strategy resources (template/headless + app-linked compatibility)
303
+ model Strategy {
304
+ id String @id @default(cuid())
305
+ name String
306
+ templateId String?
307
+ mode String @default("headless") // 'headless' | 'app-linked'
308
+ manifest String // JSON-encoded strategy manifest snapshot
309
+ config String? // JSON-encoded user config
310
+ state String? // JSON-encoded strategy state
311
+ schedule String? // JSON-encoded schedule metadata (tier/cron/interval)
312
+ permissions String @default("[]") // JSON-encoded permission list
313
+ limits String? // JSON-encoded limits object
314
+ enabled Boolean @default(false)
315
+ status String @default("draft")
316
+ createdBy String @default("human")
317
+ provenance String? // JSON-encoded source/provenance metadata
318
+ appId String? // legacy linkage when imported from a app
319
+ lastTickAt DateTime?
320
+ lastError String?
321
+ errorCount Int @default(0)
322
+ createdAt DateTime @default(now())
323
+ updatedAt DateTime @updatedAt
324
+ runs StrategyRun[]
325
+
326
+ @@index([enabled, status])
327
+ @@index([templateId])
328
+ @@index([appId])
329
+ }
330
+
331
+ // Optional strategy run audit trail for cron/runtime debugging
332
+ model StrategyRun {
333
+ id String @id @default(cuid())
334
+ strategyId String
335
+ strategy Strategy @relation(fields: [strategyId], references: [id], onDelete: Cascade)
336
+ startedAt DateTime @default(now())
337
+ endedAt DateTime?
338
+ status String
339
+ error String?
340
+ metadata String? // JSON-encoded run metadata
341
+
342
+ @@index([strategyId, startedAt])
343
+ }
344
+
345
+ // Per-app persistent storage for third-party apps
346
+ model AppStorage {
347
+ id String @id @default(cuid())
348
+ appId String
349
+ key String
350
+ value String // JSON stringified
351
+ updatedAt DateTime @updatedAt
352
+
353
+ @@unique([appId, key])
354
+ @@index([appId])
355
+ }
356
+
357
+ // Cached token metadata for enriching on-chain events
358
+ model TokenMetadata {
359
+ id String @id @default(cuid())
360
+ tokenAddress String
361
+ chain String
362
+ symbol String?
363
+ name String?
364
+ decimals Int @default(18)
365
+ icon String?
366
+ description String?
367
+ priceUsd String? // Last known USD price (string for decimal precision)
368
+ marketCap Float?
369
+ fdv Float?
370
+ liquidity Float? // DEX liquidity USD
371
+ volume24h Float?
372
+ dexId String? // Source DEX (e.g. "uniswap", "raydium")
373
+ pairAddress String?
374
+ websites String? // JSON-encoded string array
375
+ socials String? // JSON-encoded [{type,url}] array
376
+ lastAccessedAt DateTime @default(now())
377
+ lastVerifiedAt DateTime?
378
+ updatedAt DateTime @updatedAt
379
+
380
+ @@unique([tokenAddress, chain])
381
+ @@index([tokenAddress])
382
+ }
383
+
384
+ // Cached DEX pool metadata for enriching swap events
385
+ model PoolMetadata {
386
+ id String @id @default(cuid())
387
+ poolAddress String
388
+ chain String
389
+ token0 String?
390
+ token1 String?
391
+ fee Int?
392
+ dex String? // "uniswap_v2" | "uniswap_v3" | "uniswap_v4"
393
+
394
+ @@unique([poolAddress, chain])
395
+ @@index([poolAddress])
396
+ }
397
+
398
+ // Address book for labeling external addresses
399
+ model AddressLabel {
400
+ id String @id @default(cuid())
401
+ address String @unique
402
+ label String
403
+ emoji String?
404
+ color String?
405
+ notes String?
406
+ createdBy String @default("human")
407
+ createdAt DateTime @default(now())
408
+ updatedAt DateTime @updatedAt
409
+
410
+ @@index([label])
411
+ }
412
+
413
+ // Centralized system defaults (key-value store for configurable limits, permissions, TTLs, etc.)
414
+ model SystemDefault {
415
+ key String @id // e.g. "limits.fund", "permissions.default"
416
+ value String // JSON-encoded value
417
+ type String // Category: "permissions" | "financial" | "ttl" | "rate_limit" | "ai_safety" | "launch" | "app" | "swap"
418
+ label String // Human-readable label for dashboard
419
+ description String? // Optional description
420
+ updatedAt DateTime @updatedAt
421
+
422
+ @@index([type])
423
+ }
424
+
425
+ // WebAuthn passkey credentials for biometric vault unlock
426
+ model Passkey {
427
+ id String @id @default(cuid())
428
+ credentialId String @unique // base64url WebAuthn credential ID
429
+ publicKey Bytes // COSE public key (base64url ↔ Uint8Array conversion needed)
430
+ counter Int @default(0) // signature counter (replay/clone detection)
431
+ transports String @default("[]") // JSON array of transport hints
432
+ rpId String // relying party ID (e.g. "localhost")
433
+ aaguid String @default("") // authenticator AAGUID
434
+ createdAt DateTime @default(now())
435
+ lastUsedAt DateTime?
436
+
437
+ @@index([rpId])
438
+ }
439
+
440
+ // Global app configuration (singleton)
441
+ model AppConfig {
442
+ id String @id @default("global")
443
+ chainConfig String? // JSON: { base: { rpc: "...", chainId: 8453 }, ... }
444
+ adapterConfig String? // JSON: { enabled: true, adapters: [{ type, enabled, config }] }
445
+ createdAt DateTime @default(now())
446
+ updatedAt DateTime @updatedAt
447
+ }
Binary file
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Add a app to the AuraMaxx dashboard via WebSocket.
4
+ *
5
+ * Usage:
6
+ * node scripts/add-app.js <appType> [options]
7
+ *
8
+ * Examples:
9
+ * # Inline dynamic app
10
+ * node scripts/add-app.js dynamic --code "function Hi() { return <div>Hello</div>; }"
11
+ *
12
+ * # File-based dynamic app (agents: use tmp/, then rm after)
13
+ * node scripts/add-app.js dynamic --file tmp/app.jsx --id "my-app"
14
+ *
15
+ * # Iframe app
16
+ * node scripts/add-app.js iframe --url "https://example.com" --title "My Chart"
17
+ *
18
+ * # Built-in apps
19
+ * node scripts/add-app.js wallets
20
+ * node scripts/add-app.js logs --x 400 --y 100
21
+ *
22
+ * # Custom app (from src/components/apps/custom/)
23
+ * node scripts/add-app.js custom:ExampleApp --message "Hello"
24
+ *
25
+ * # Position and size
26
+ * node scripts/add-app.js iframe --url "https://example.com" --x 100 --y 200 --width 500 --height 400
27
+ *
28
+ * # Target a specific workspace
29
+ * node scripts/add-app.js logs --workspace "home"
30
+ */
31
+
32
+ const WebSocket = require('ws');
33
+ const fs = require('fs');
34
+ const path = require('path');
35
+
36
+ const WS_BASE_URL = process.env.WORKSPACE_WS_URL || 'ws://localhost:4748';
37
+ const AUTH_TOKEN = process.env.AURA_TOKEN;
38
+
39
+ // Build WebSocket URL with optional token
40
+ function getWsUrl() {
41
+ if (AUTH_TOKEN) {
42
+ return `${WS_BASE_URL}?token=${encodeURIComponent(AUTH_TOKEN)}`;
43
+ }
44
+ return WS_BASE_URL;
45
+ }
46
+
47
+ // Parse command line arguments
48
+ function parseArgs(args) {
49
+ const result = { _: [] };
50
+ let i = 0;
51
+
52
+ while (i < args.length) {
53
+ const arg = args[i];
54
+
55
+ if (arg.startsWith('--')) {
56
+ const key = arg.slice(2);
57
+ const next = args[i + 1];
58
+
59
+ if (next && !next.startsWith('--')) {
60
+ // Try to parse as number
61
+ const num = parseFloat(next);
62
+ result[key] = isNaN(num) ? next : num;
63
+ i += 2;
64
+ } else {
65
+ result[key] = true;
66
+ i += 1;
67
+ }
68
+ } else {
69
+ result._.push(arg);
70
+ i += 1;
71
+ }
72
+ }
73
+
74
+ return result;
75
+ }
76
+
77
+ function printUsage() {
78
+ console.log(`
79
+ Usage: node scripts/add-app.js <appType> [options]
80
+
81
+ Authentication:
82
+ Set AURA_TOKEN env var with a valid token that has workspace:modify permission.
83
+ Example: export AURA_TOKEN="your-agent-token"
84
+
85
+ App Types:
86
+ Built-in (singleton):
87
+ wallets, logs, send, agentKeys, status, launch
88
+
89
+ Multi-instance:
90
+ iframe --url <url> [--title <title>]
91
+ dynamic --code <code> | --file <path>
92
+ custom:* --<key> <value> (passed as config)
93
+
94
+ Options:
95
+ --id <id> Custom app ID (for multi-instance apps)
96
+ --workspace <id> Target workspace ID (default: active workspace)
97
+ --x <number> X position (default: 20)
98
+ --y <number> Y position (default: 20)
99
+ --width <number> App width
100
+ --height <number> App height
101
+
102
+ Examples:
103
+ # Set token first
104
+ export AURA_TOKEN="your-agent-token"
105
+
106
+ # Inline dynamic app
107
+ node scripts/add-app.js dynamic --code "function Hi() { return <div>Hello</div>; }"
108
+
109
+ # File-based dynamic app (use tmp/, then rm after)
110
+ node scripts/add-app.js dynamic --file tmp/app.jsx --id "my-app"
111
+
112
+ # Iframe
113
+ node scripts/add-app.js iframe --url "https://dexscreener.com/base/0x123"
114
+
115
+ # Built-in apps
116
+ node scripts/add-app.js wallets --x 400 --y 100
117
+
118
+ # Custom app (from src/components/apps/custom/)
119
+ node scripts/add-app.js custom:ExampleApp --message "Hello"
120
+ `);
121
+ }
122
+
123
+ async function main() {
124
+ const args = parseArgs(process.argv.slice(2));
125
+ const appType = args._[0];
126
+
127
+ if (!appType || args.help) {
128
+ printUsage();
129
+ process.exit(args.help ? 0 : 1);
130
+ }
131
+
132
+ // Build config from remaining args
133
+ const config = {};
134
+ const reserved = ['_', 'id', 'workspace', 'x', 'y', 'width', 'height', 'file', 'code', 'url', 'title'];
135
+
136
+ // Handle specific app types
137
+ if (appType === 'iframe') {
138
+ if (!args.url) {
139
+ console.error('Error: iframe app requires --url');
140
+ process.exit(1);
141
+ }
142
+ config.url = args.url;
143
+ if (args.title) config.title = args.title;
144
+ } else if (appType === 'dynamic') {
145
+ if (args.file) {
146
+ const filePath = path.resolve(args.file);
147
+ if (!fs.existsSync(filePath)) {
148
+ console.error(`Error: File not found: ${filePath}`);
149
+ process.exit(1);
150
+ }
151
+ config.code = fs.readFileSync(filePath, 'utf-8');
152
+ } else if (args.code) {
153
+ config.code = args.code;
154
+ } else {
155
+ console.error('Error: dynamic app requires --code or --file');
156
+ process.exit(1);
157
+ }
158
+ } else {
159
+ // Pass through any non-reserved args as config
160
+ for (const [key, value] of Object.entries(args)) {
161
+ if (!reserved.includes(key)) {
162
+ config[key] = value;
163
+ }
164
+ }
165
+ }
166
+
167
+ // Connect to WebSocket with optional authentication
168
+ const wsUrl = getWsUrl();
169
+ const ws = new WebSocket(wsUrl);
170
+
171
+ ws.on('error', (err) => {
172
+ console.error('WebSocket error:', err.message);
173
+ console.log('Make sure the Next.js app is running on port 4748');
174
+ if (!AUTH_TOKEN) {
175
+ console.log('Tip: Set AURA_TOKEN env var for authenticated mutations');
176
+ }
177
+ process.exit(1);
178
+ });
179
+
180
+ ws.on('open', () => {
181
+ // Request current workspace state
182
+ ws.send(JSON.stringify({
183
+ type: 'workspace:state:request',
184
+ timestamp: Date.now(),
185
+ source: 'agent',
186
+ data: { requestId: 'add-app-script' }
187
+ }));
188
+ });
189
+
190
+ ws.on('message', (rawData) => {
191
+ const msg = JSON.parse(rawData.toString());
192
+
193
+ // Handle permission errors
194
+ if (msg.type === 'error') {
195
+ console.error('Error:', msg.error);
196
+ if (msg.error.includes('Permission denied')) {
197
+ console.log('Tip: Set AURA_TOKEN env var with a token that has workspace:modify permission');
198
+ }
199
+ ws.close();
200
+ process.exit(1);
201
+ }
202
+
203
+ if (msg.type === 'workspace:state:response') {
204
+ const workspaceId = args.workspace || msg.data.activeWorkspaceId;
205
+
206
+ const appData = {
207
+ workspaceId,
208
+ appType,
209
+ x: args.x || 20,
210
+ y: args.y || 20
211
+ };
212
+
213
+ if (args.id) appData.id = args.id;
214
+ if (args.width) appData.width = args.width;
215
+ if (args.height) appData.height = args.height;
216
+ if (Object.keys(config).length > 0) appData.config = config;
217
+
218
+ // Wait for token validation to complete (race condition workaround)
219
+ // The server validates tokens asynchronously, so we need a brief delay
220
+ setTimeout(() => {
221
+ ws.send(JSON.stringify({
222
+ type: 'app:added',
223
+ timestamp: Date.now(),
224
+ source: 'agent',
225
+ data: appData
226
+ }));
227
+
228
+ // Wait for potential error response, then assume success
229
+ setTimeout(() => {
230
+ console.log('App added:', appType);
231
+ if (args.id) console.log(' ID:', args.id);
232
+ console.log(' Workspace:', workspaceId);
233
+ console.log(' Position:', `(${appData.x}, ${appData.y})`);
234
+ if (Object.keys(config).length > 0) {
235
+ console.log(' Config:', JSON.stringify(config, null, 2).split('\n').map((l, i) => i === 0 ? l : ' ' + l).join('\n'));
236
+ }
237
+ ws.close();
238
+ process.exit(0);
239
+ }, 300);
240
+ }, 150);
241
+ }
242
+ });
243
+ }
244
+
245
+ main();