auramaxx 1.0.0-alpha.4

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 (363) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +112 -0
  3. package/bin/aurawallet.js +121 -0
  4. package/docs/ADAPTERS.md +467 -0
  5. package/docs/API.md +2679 -0
  6. package/docs/APPS.md +198 -0
  7. package/docs/ARCHITECTURE.md +350 -0
  8. package/docs/AUTH.md +698 -0
  9. package/docs/BEST-PRACTICES.md +121 -0
  10. package/docs/CLI.md +61 -0
  11. package/docs/DEVELOPING-APPS.md +452 -0
  12. package/docs/EXTENSION.md +97 -0
  13. package/docs/JOBS.md +33 -0
  14. package/docs/MCP.md +76 -0
  15. package/docs/PROTOCOL.md +142 -0
  16. package/docs/SETUP.md +219 -0
  17. package/docs/WORKSPACE.md +672 -0
  18. package/docs/agent-auth.md +63 -0
  19. package/docs/aura-file.md +48 -0
  20. package/docs/credentials.md +53 -0
  21. package/docs/external/getting-started.md +65 -0
  22. package/docs/external/overview.md +45 -0
  23. package/docs/external/use-cases.md +48 -0
  24. package/docs/external/why-aura.md +35 -0
  25. package/docs/jobs/connect-agent.md +77 -0
  26. package/docs/jobs/migrate-from-dotenv.md +79 -0
  27. package/docs/jobs/recover-from-lockout.md +72 -0
  28. package/docs/jobs/secure-ci.md +63 -0
  29. package/docs/oauth2.md +42 -0
  30. package/docs/passkeys.md +60 -0
  31. package/docs/security.md +540 -0
  32. package/docs/specs/aura-open-protocol.md +61 -0
  33. package/docs/specs/aura-provider-plugin.md +24 -0
  34. package/docs/specs/aura-registry-model.md +31 -0
  35. package/docs/specs/fixtures/invalid-bad-key.aura +1 -0
  36. package/docs/specs/fixtures/invalid-bad-unicode-escape.aura +1 -0
  37. package/docs/specs/fixtures/invalid-duplicate-key.aura +2 -0
  38. package/docs/specs/fixtures/valid-basic.aura +4 -0
  39. package/docs/specs/fixtures/valid-provider-ref.aura +1 -0
  40. package/docs/specs/fixtures/valid-quoted-escapes.aura +2 -0
  41. package/docs/templates/RELEASE_NOTES_TEMPLATE.md +22 -0
  42. package/docs/totp.md +40 -0
  43. package/docs/wallet/AI.md +508 -0
  44. package/docs/wallet/DEVELOPING-STRATEGIES.md +713 -0
  45. package/docs/wallet/README.md +47 -0
  46. package/docs/wallet/STRATEGY.md +89 -0
  47. package/next.config.ts +21 -0
  48. package/package.json +151 -0
  49. package/postcss.config.mjs +8 -0
  50. package/prisma/migrations/20260214170000_baseline/migration.sql +511 -0
  51. package/prisma/migrations/20260216214537_add_passkey_model/migration.sql +18 -0
  52. package/prisma/migrations/20260217150500_add_credential_access_audit/migration.sql +31 -0
  53. package/prisma/migrations/migration_lock.toml +3 -0
  54. package/prisma/schema.prisma +447 -0
  55. package/public/logo-chevron.svg +31 -0
  56. package/public/logo-concentric.svg +31 -0
  57. package/public/logo-crosshatch.svg +39 -0
  58. package/public/logo-dashed.svg +39 -0
  59. package/public/logo-horizontal.svg +31 -0
  60. package/public/logo-m56.svg +64 -0
  61. package/public/logo.webp +0 -0
  62. package/scripts/add-app.js +245 -0
  63. package/scripts/init.sh +57 -0
  64. package/scripts/migrate-apikeys-to-credentials.ts +35 -0
  65. package/scripts/sandbox-agent-flow.sh +235 -0
  66. package/scripts/sandbox.sh +175 -0
  67. package/scripts/validate-job-docs.mjs +125 -0
  68. package/server/abi/SwapHelper.json +438 -0
  69. package/server/cli/approval.ts +447 -0
  70. package/server/cli/commands/app.ts +204 -0
  71. package/server/cli/commands/cron.ts +24 -0
  72. package/server/cli/commands/doctor.ts +1007 -0
  73. package/server/cli/commands/env.ts +456 -0
  74. package/server/cli/commands/init.ts +752 -0
  75. package/server/cli/commands/mcp.ts +125 -0
  76. package/server/cli/commands/restore.ts +314 -0
  77. package/server/cli/commands/shell-hook.ts +468 -0
  78. package/server/cli/commands/start.ts +62 -0
  79. package/server/cli/commands/status.ts +59 -0
  80. package/server/cli/commands/stop.ts +14 -0
  81. package/server/cli/commands/token.ts +180 -0
  82. package/server/cli/commands/unlock.ts +49 -0
  83. package/server/cli/commands/vault.ts +417 -0
  84. package/server/cli/index.ts +328 -0
  85. package/server/cli/lib/aura-parser.ts +64 -0
  86. package/server/cli/lib/credential-create.ts +74 -0
  87. package/server/cli/lib/credential-resolve.ts +254 -0
  88. package/server/cli/lib/dotenv-migrate.ts +116 -0
  89. package/server/cli/lib/dotenv-parser.ts +146 -0
  90. package/server/cli/lib/http.ts +91 -0
  91. package/server/cli/lib/init-steps.ts +76 -0
  92. package/server/cli/lib/local-agent-trust.ts +45 -0
  93. package/server/cli/lib/process.ts +136 -0
  94. package/server/cli/lib/prompt.ts +85 -0
  95. package/server/cli/lib/theme.ts +240 -0
  96. package/server/cli/socket.ts +570 -0
  97. package/server/cli/transport-client.ts +50 -0
  98. package/server/cron/index.ts +137 -0
  99. package/server/cron/job.ts +31 -0
  100. package/server/cron/jobs/balance-sync.ts +436 -0
  101. package/server/cron/jobs/incoming-scan.ts +506 -0
  102. package/server/cron/jobs/native-price.ts +70 -0
  103. package/server/cron/jobs/orphan-cleanup.ts +40 -0
  104. package/server/cron/jobs/strategy-runner.ts +175 -0
  105. package/server/cron/scheduler.ts +125 -0
  106. package/server/index.ts +406 -0
  107. package/server/lib/adapters/factory.ts +110 -0
  108. package/server/lib/adapters/index.ts +19 -0
  109. package/server/lib/adapters/router.ts +297 -0
  110. package/server/lib/adapters/telegram.ts +645 -0
  111. package/server/lib/adapters/types.ts +89 -0
  112. package/server/lib/adapters/webhook.ts +95 -0
  113. package/server/lib/address.ts +49 -0
  114. package/server/lib/agent-auth/contracts.ts +1194 -0
  115. package/server/lib/agent-profiles.ts +328 -0
  116. package/server/lib/ai.ts +285 -0
  117. package/server/lib/api-registry/contracts.ts +86 -0
  118. package/server/lib/api-registry/validation.ts +172 -0
  119. package/server/lib/apikey-migration.ts +189 -0
  120. package/server/lib/app-installer.ts +505 -0
  121. package/server/lib/app-tokens.ts +247 -0
  122. package/server/lib/auth.ts +314 -0
  123. package/server/lib/batch.ts +242 -0
  124. package/server/lib/cold.ts +874 -0
  125. package/server/lib/config.ts +381 -0
  126. package/server/lib/credential-access-audit.ts +85 -0
  127. package/server/lib/credential-access-policy.ts +110 -0
  128. package/server/lib/credential-health.ts +343 -0
  129. package/server/lib/credential-import.ts +487 -0
  130. package/server/lib/credential-scope.ts +87 -0
  131. package/server/lib/credential-shares.ts +190 -0
  132. package/server/lib/credential-transport.ts +342 -0
  133. package/server/lib/credential-vault.ts +77 -0
  134. package/server/lib/credentials.ts +333 -0
  135. package/server/lib/crypto.ts +8 -0
  136. package/server/lib/db.ts +15 -0
  137. package/server/lib/defaults.ts +366 -0
  138. package/server/lib/dex/index.ts +80 -0
  139. package/server/lib/dex/relay.ts +235 -0
  140. package/server/lib/dex/types.ts +59 -0
  141. package/server/lib/dex/uniswap.ts +370 -0
  142. package/server/lib/e2e-agent/artifacts.ts +36 -0
  143. package/server/lib/e2e-agent/contracts.ts +112 -0
  144. package/server/lib/e2e-agent/validation.ts +135 -0
  145. package/server/lib/encrypt.ts +128 -0
  146. package/server/lib/error.ts +20 -0
  147. package/server/lib/events.ts +205 -0
  148. package/server/lib/hot.ts +357 -0
  149. package/server/lib/key-fingerprint.ts +28 -0
  150. package/server/lib/logger.ts +331 -0
  151. package/server/lib/network.ts +137 -0
  152. package/server/lib/notifications.ts +219 -0
  153. package/server/lib/oauth2-refresh.ts +241 -0
  154. package/server/lib/oursecret.ts +54 -0
  155. package/server/lib/passkey-credential.ts +360 -0
  156. package/server/lib/passkey.ts +68 -0
  157. package/server/lib/permissions.ts +248 -0
  158. package/server/lib/pino.ts +24 -0
  159. package/server/lib/policy-preview.ts +138 -0
  160. package/server/lib/price.ts +338 -0
  161. package/server/lib/prices.ts +34 -0
  162. package/server/lib/project-scope.ts +239 -0
  163. package/server/lib/resolve-action.ts +427 -0
  164. package/server/lib/resolve.ts +36 -0
  165. package/server/lib/sessions.ts +632 -0
  166. package/server/lib/solana/connection.ts +26 -0
  167. package/server/lib/solana/jupiter.ts +128 -0
  168. package/server/lib/solana/transfer.ts +108 -0
  169. package/server/lib/solana/wallet.ts +136 -0
  170. package/server/lib/strategy/emits.ts +21 -0
  171. package/server/lib/strategy/engine.ts +1305 -0
  172. package/server/lib/strategy/executor.ts +115 -0
  173. package/server/lib/strategy/hook-context.ts +158 -0
  174. package/server/lib/strategy/hooks.ts +990 -0
  175. package/server/lib/strategy/index.ts +28 -0
  176. package/server/lib/strategy/installer.ts +305 -0
  177. package/server/lib/strategy/loader.ts +256 -0
  178. package/server/lib/strategy/message.ts +235 -0
  179. package/server/lib/strategy/repository.ts +218 -0
  180. package/server/lib/strategy/session-logger.ts +693 -0
  181. package/server/lib/strategy/sources.ts +288 -0
  182. package/server/lib/strategy/state.ts +189 -0
  183. package/server/lib/strategy/templates.ts +403 -0
  184. package/server/lib/strategy/tick.ts +404 -0
  185. package/server/lib/strategy/types.ts +230 -0
  186. package/server/lib/swap.ts +3 -0
  187. package/server/lib/temp.ts +86 -0
  188. package/server/lib/token-metadata.ts +86 -0
  189. package/server/lib/token-safety.ts +200 -0
  190. package/server/lib/token-search.ts +444 -0
  191. package/server/lib/totp.ts +194 -0
  192. package/server/lib/transactions.ts +123 -0
  193. package/server/lib/transport.ts +75 -0
  194. package/server/lib/txhistory/decoder.ts +262 -0
  195. package/server/lib/txhistory/enricher.ts +652 -0
  196. package/server/lib/txhistory/index.ts +391 -0
  197. package/server/lib/txhistory/signatures.ts +59 -0
  198. package/server/lib/verified-summary.ts +421 -0
  199. package/server/mcp/profile-policy.ts +30 -0
  200. package/server/mcp/server.ts +619 -0
  201. package/server/mcp/tools.ts +523 -0
  202. package/server/middleware/auth.ts +119 -0
  203. package/server/middleware/requestLogger.ts +84 -0
  204. package/server/routes/actions.ts +459 -0
  205. package/server/routes/adapters.ts +703 -0
  206. package/server/routes/addressbook.ts +113 -0
  207. package/server/routes/ai.ts +34 -0
  208. package/server/routes/apikeys.ts +295 -0
  209. package/server/routes/apps.ts +601 -0
  210. package/server/routes/auth.ts +457 -0
  211. package/server/routes/backup.ts +340 -0
  212. package/server/routes/batch.ts +270 -0
  213. package/server/routes/bookmarks.ts +162 -0
  214. package/server/routes/credential-shares.ts +198 -0
  215. package/server/routes/credential-vaults.ts +154 -0
  216. package/server/routes/credentials.ts +1290 -0
  217. package/server/routes/dashboard.ts +71 -0
  218. package/server/routes/defaults.ts +124 -0
  219. package/server/routes/fund.ts +229 -0
  220. package/server/routes/import.ts +352 -0
  221. package/server/routes/launch.ts +665 -0
  222. package/server/routes/lock.ts +54 -0
  223. package/server/routes/logs.ts +68 -0
  224. package/server/routes/nuke.ts +111 -0
  225. package/server/routes/passkey-credentials.ts +99 -0
  226. package/server/routes/passkey.ts +346 -0
  227. package/server/routes/portfolio.ts +217 -0
  228. package/server/routes/price.ts +63 -0
  229. package/server/routes/resolve.ts +31 -0
  230. package/server/routes/security.ts +45 -0
  231. package/server/routes/send-evm.ts +241 -0
  232. package/server/routes/send-solana.ts +281 -0
  233. package/server/routes/send.ts +178 -0
  234. package/server/routes/setup.ts +210 -0
  235. package/server/routes/strategy.ts +894 -0
  236. package/server/routes/swap-evm.ts +353 -0
  237. package/server/routes/swap-solana.ts +177 -0
  238. package/server/routes/swap.ts +356 -0
  239. package/server/routes/token.ts +247 -0
  240. package/server/routes/unlock.ts +403 -0
  241. package/server/routes/wallet-assets.ts +361 -0
  242. package/server/routes/wallet-transactions.ts +515 -0
  243. package/server/routes/wallet.ts +710 -0
  244. package/server/types.ts +146 -0
  245. package/skills/aurawallet/SKILL.md +739 -0
  246. package/skills/aurawallet-setup/SKILL.md +74 -0
  247. package/skills/security-review/SKILL.md +148 -0
  248. package/src/app/api/agent-requests/route.ts +30 -0
  249. package/src/app/api/apps/install/route.ts +126 -0
  250. package/src/app/api/apps/manifests/route.ts +16 -0
  251. package/src/app/api/apps/static/[...path]/route.ts +57 -0
  252. package/src/app/api/events/route.ts +92 -0
  253. package/src/app/api/page.tsx +212 -0
  254. package/src/app/api/workspace/[id]/apps/[wid]/route.ts +119 -0
  255. package/src/app/api/workspace/[id]/apps/route.ts +81 -0
  256. package/src/app/api/workspace/[id]/export/route.ts +67 -0
  257. package/src/app/api/workspace/[id]/route.ts +168 -0
  258. package/src/app/api/workspace/auth.ts +34 -0
  259. package/src/app/api/workspace/config/route.ts +106 -0
  260. package/src/app/api/workspace/import/route.ts +127 -0
  261. package/src/app/api/workspace/route.ts +116 -0
  262. package/src/app/app/page.tsx +2122 -0
  263. package/src/app/apple-icon.png +0 -0
  264. package/src/app/docs/page.tsx +178 -0
  265. package/src/app/favicon.ico +0 -0
  266. package/src/app/globals.css +572 -0
  267. package/src/app/health/page.tsx +5 -0
  268. package/src/app/hello/page.tsx +15 -0
  269. package/src/app/icon.png +0 -0
  270. package/src/app/layout.tsx +34 -0
  271. package/src/app/page.tsx +986 -0
  272. package/src/app/providers.tsx +90 -0
  273. package/src/app/share/[token]/page.tsx +295 -0
  274. package/src/components/ChainSelector.tsx +144 -0
  275. package/src/components/HumanActionBar.tsx +695 -0
  276. package/src/components/NotificationDrawer.tsx +129 -0
  277. package/src/components/apps/AgentKeysApp.tsx +490 -0
  278. package/src/components/apps/App.tsx +153 -0
  279. package/src/components/apps/AppGrid.tsx +15 -0
  280. package/src/components/apps/DetailedAddressDrawer.tsx +325 -0
  281. package/src/components/apps/DraggableApp.tsx +562 -0
  282. package/src/components/apps/IFrameApp.tsx +73 -0
  283. package/src/components/apps/LogsApp.tsx +360 -0
  284. package/src/components/apps/SendApp.tsx +394 -0
  285. package/src/components/apps/SetupWizardApp.tsx +1004 -0
  286. package/src/components/apps/SystemDefaultsApp.tsx +845 -0
  287. package/src/components/apps/ThirdPartyApp.tsx +428 -0
  288. package/src/components/apps/TokenApp.tsx +319 -0
  289. package/src/components/apps/TransactionsApp.tsx +438 -0
  290. package/src/components/apps/WalletDetailApp.tsx +1505 -0
  291. package/src/components/apps/index.ts +13 -0
  292. package/src/components/design-system/Button.tsx +53 -0
  293. package/src/components/design-system/ChainIndicator.tsx +65 -0
  294. package/src/components/design-system/ChainSelector.tsx +137 -0
  295. package/src/components/design-system/ConfirmationModal.tsx +106 -0
  296. package/src/components/design-system/ConfirmationPopover.tsx +81 -0
  297. package/src/components/design-system/Drawer.tsx +123 -0
  298. package/src/components/design-system/FilterDropdown.tsx +72 -0
  299. package/src/components/design-system/Modal.tsx +206 -0
  300. package/src/components/design-system/Popover.tsx +142 -0
  301. package/src/components/design-system/TextInput.tsx +85 -0
  302. package/src/components/design-system/Toggle.tsx +58 -0
  303. package/src/components/design-system/index.ts +11 -0
  304. package/src/components/docs/DocsThemeToggle.tsx +49 -0
  305. package/src/components/health/CredentialHealthDashboard.tsx +214 -0
  306. package/src/components/icons/ChainIcons.tsx +72 -0
  307. package/src/components/layout/AppStoreDrawer.tsx +369 -0
  308. package/src/components/layout/ContentArea.tsx +21 -0
  309. package/src/components/layout/TabBar.tsx +278 -0
  310. package/src/components/layout/WalletSidebar.tsx +1033 -0
  311. package/src/components/layout/index.ts +4 -0
  312. package/src/components/marketing/AuraWalletSpecOverlay.tsx +635 -0
  313. package/src/components/marketing/DeviceMorphExperience.tsx +216 -0
  314. package/src/components/vault/ApiKeysConsole.tsx +1080 -0
  315. package/src/components/vault/AuditConsole.tsx +584 -0
  316. package/src/components/vault/CredentialDetail.tsx +455 -0
  317. package/src/components/vault/CredentialEmpty.tsx +55 -0
  318. package/src/components/vault/CredentialField.tsx +361 -0
  319. package/src/components/vault/CredentialForm.tsx +1212 -0
  320. package/src/components/vault/CredentialList.tsx +165 -0
  321. package/src/components/vault/CredentialRow.tsx +97 -0
  322. package/src/components/vault/CredentialShareModal.tsx +178 -0
  323. package/src/components/vault/CredentialVault.tsx +754 -0
  324. package/src/components/vault/CredentialWalletWidget.tsx +103 -0
  325. package/src/components/vault/ImportCredentialsModal.tsx +515 -0
  326. package/src/components/vault/LargeTypeModal.tsx +64 -0
  327. package/src/components/vault/PasswordGenerator.tsx +224 -0
  328. package/src/components/vault/TOTPDisplay.tsx +123 -0
  329. package/src/components/vault/VaultSidebar.tsx +413 -0
  330. package/src/components/vault/types.ts +54 -0
  331. package/src/context/AuthContext.tsx +337 -0
  332. package/src/context/PriceContext.tsx +113 -0
  333. package/src/context/ThemeContext.tsx +164 -0
  334. package/src/context/WebSocketContext.tsx +269 -0
  335. package/src/context/WorkspaceContext.tsx +668 -0
  336. package/src/hooks/index.ts +3 -0
  337. package/src/hooks/useAgentActions.ts +368 -0
  338. package/src/hooks/useBalance.ts +103 -0
  339. package/src/hooks/useBalances.ts +129 -0
  340. package/src/instrumentation.ts +12 -0
  341. package/src/lib/api.ts +449 -0
  342. package/src/lib/app-loader.ts +148 -0
  343. package/src/lib/app-registry.ts +178 -0
  344. package/src/lib/app-sdk.ts +157 -0
  345. package/src/lib/audit-console-adapter.ts +151 -0
  346. package/src/lib/auth-client.ts +75 -0
  347. package/src/lib/config.ts +74 -0
  348. package/src/lib/crypto.ts +112 -0
  349. package/src/lib/db.ts +21 -0
  350. package/src/lib/docs.ts +390 -0
  351. package/src/lib/events.ts +361 -0
  352. package/src/lib/pino.ts +24 -0
  353. package/src/lib/theme-handlers.ts +168 -0
  354. package/src/lib/theme.ts +351 -0
  355. package/src/lib/tokenData.ts +378 -0
  356. package/src/lib/vault-crypto.ts +129 -0
  357. package/src/lib/websocket-server.ts +302 -0
  358. package/src/lib/websocket-setup.ts +79 -0
  359. package/src/lib/wordlist.ts +2050 -0
  360. package/src/lib/workspace-handlers.ts +285 -0
  361. package/start.sh +80 -0
  362. package/tailwind.config.ts +99 -0
  363. package/tsconfig.json +42 -0
@@ -0,0 +1,672 @@
1
+ # Workspace API - Agent Control Guide
2
+
3
+ Programmatic control of the AuraWallet dashboard via WebSocket.
4
+
5
+ ## Authentication
6
+
7
+ **Read-only operations** (querying state) work without authentication.
8
+
9
+ **Mutation operations** (creating/updating/deleting workspaces and apps, changing themes) require a valid token with `workspace:modify` permission or admin access (`admin:*`).
10
+
11
+ For authentication details, see [AUTH.md](./AUTH.md).
12
+
13
+ ## Quick Start (CLI Script)
14
+
15
+ The easiest way to add apps is via the CLI script:
16
+
17
+ ```bash
18
+ # Set your token (required for mutations)
19
+ export AURA_TOKEN="your-agent-token"
20
+
21
+ # Add an iframe app
22
+ node scripts/add-app.js iframe --url "https://dexscreener.com/base/0x123" --title "Price Chart"
23
+
24
+ # Add a built-in app
25
+ node scripts/add-app.js wallets
26
+ node scripts/add-app.js logs --x 400 --y 100
27
+
28
+ # Add an installed app (from apps/ folder)
29
+ node scripts/add-app.js installed:example-kanban
30
+
31
+ # Specify position and size
32
+ node scripts/add-app.js iframe --url "https://example.com" --x 100 --y 200 --width 600 --height 400
33
+
34
+ # Custom app ID (for multi-instance)
35
+ node scripts/add-app.js iframe --id "my-chart" --url "https://example.com"
36
+ ```
37
+
38
+ Run `node scripts/add-app.js --help` for full usage.
39
+
40
+ > **Note**: Adding apps requires a token with `workspace:modify` permission or admin access. See [AUTH.md](./AUTH.md) for obtaining tokens.
41
+
42
+ ---
43
+
44
+ ## Quick Start (WebSocket)
45
+
46
+ For programmatic control from code:
47
+
48
+ ```javascript
49
+ // Connect with authentication token for mutations
50
+ // Token is passed as URL query parameter
51
+ const token = 'your-agent-token'; // From /auth endpoint or admin token from /unlock
52
+ const ws = new WebSocket(`ws://localhost:4748?token=${encodeURIComponent(token)}`);
53
+
54
+ ws.onopen = () => {
55
+ // Add a app (requires workspace:modify permission or admin:*)
56
+ ws.send(JSON.stringify({
57
+ type: 'app:added',
58
+ timestamp: Date.now(),
59
+ source: 'agent',
60
+ data: {
61
+ workspaceId: 'your-workspace-id',
62
+ appType: 'iframe',
63
+ config: { url: 'https://example.com/chart' },
64
+ x: 100, y: 100, width: 400, height: 300
65
+ }
66
+ }));
67
+ };
68
+
69
+ ws.onmessage = (event) => {
70
+ const msg = JSON.parse(event.data);
71
+
72
+ // Check for permission errors
73
+ if (msg.type === 'error') {
74
+ console.error('Permission denied:', msg.error);
75
+ return;
76
+ }
77
+
78
+ console.log('Received:', msg.type, msg.data);
79
+ };
80
+ ```
81
+
82
+ **Without a token**, you can still query state (read-only):
83
+
84
+ ```javascript
85
+ const ws = new WebSocket('ws://localhost:4748'); // No token
86
+
87
+ ws.onopen = () => {
88
+ // Query current state (no auth required)
89
+ ws.send(JSON.stringify({
90
+ type: 'workspace:state:request',
91
+ timestamp: Date.now(),
92
+ source: 'agent',
93
+ data: { requestId: 'req-123' }
94
+ }));
95
+ };
96
+ ```
97
+
98
+ ---
99
+
100
+ ## WebSocket Events
101
+
102
+ ### Connection
103
+
104
+ ```
105
+ ws://localhost:4748
106
+ ```
107
+
108
+ On connect, you'll receive: `{ type: 'connected', timestamp: ... }`
109
+
110
+ ---
111
+
112
+ ## Query Events (Request/Response)
113
+
114
+ ### Get Current State
115
+
116
+ Request the full workspace state:
117
+
118
+ ```javascript
119
+ ws.send(JSON.stringify({
120
+ type: 'workspace:state:request',
121
+ timestamp: Date.now(),
122
+ source: 'agent',
123
+ data: {
124
+ requestId: 'req-123', // Your unique ID to match response
125
+ workspaceId: 'optional-id' // Omit for default workspace
126
+ }
127
+ }));
128
+ ```
129
+
130
+ Response:
131
+
132
+ ```javascript
133
+ {
134
+ type: 'workspace:state:response',
135
+ data: {
136
+ requestId: 'req-123',
137
+ workspaces: [
138
+ { id: 'ws-1', name: 'HOME', slug: 'home', icon: 'Home', isDefault: true, isCloseable: false }
139
+ ],
140
+ activeWorkspaceId: 'ws-1',
141
+ apps: [
142
+ { id: 'w-1', workspaceId: 'ws-1', appType: 'logs', x: 20, y: 20, width: 600, height: 300, zIndex: 10, isVisible: true, isLocked: false }
143
+ ]
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Mutation Events
151
+
152
+ > **Authentication Required**: All mutation events require a valid token with `workspace:modify` permission or admin access. Connect with `ws://localhost:4748?token=YOUR_TOKEN`. See [AUTH.md](./AUTH.md) for obtaining tokens.
153
+
154
+ All mutations are broadcast to other connected clients automatically.
155
+
156
+ ### Create Workspace
157
+
158
+ ```javascript
159
+ ws.send(JSON.stringify({
160
+ type: 'workspace:created',
161
+ timestamp: Date.now(),
162
+ source: 'agent',
163
+ data: {
164
+ id: 'ws-' + Date.now(), // Optional - auto-generated if omitted
165
+ name: 'TRADING',
166
+ slug: 'trading', // Optional - generated from name
167
+ icon: 'TrendingUp', // Lucide icon name
168
+ order: 1, // Tab order
169
+ isDefault: false,
170
+ isCloseable: true
171
+ }
172
+ }));
173
+ ```
174
+
175
+ ### Delete Workspace
176
+
177
+ ```javascript
178
+ ws.send(JSON.stringify({
179
+ type: 'workspace:deleted',
180
+ timestamp: Date.now(),
181
+ source: 'agent',
182
+ data: { workspaceId: 'ws-123' }
183
+ }));
184
+ ```
185
+
186
+ ### Update Workspace
187
+
188
+ ```javascript
189
+ ws.send(JSON.stringify({
190
+ type: 'workspace:updated',
191
+ timestamp: Date.now(),
192
+ source: 'agent',
193
+ data: {
194
+ id: 'ws-123',
195
+ name: 'NEW NAME',
196
+ icon: 'Zap'
197
+ }
198
+ }));
199
+ ```
200
+
201
+ ---
202
+
203
+ ## App Events
204
+
205
+ ### Add App
206
+
207
+ ```javascript
208
+ ws.send(JSON.stringify({
209
+ type: 'app:added',
210
+ timestamp: Date.now(),
211
+ source: 'agent',
212
+ data: {
213
+ id: 'app-' + Date.now(), // Optional
214
+ workspaceId: 'ws-123', // Required
215
+ appType: 'iframe', // Required - see App Types below
216
+ x: 100, // Position (default: 20)
217
+ y: 100,
218
+ width: 400, // Size (default varies by type)
219
+ height: 300,
220
+ zIndex: 50, // Layering (auto-incremented if omitted)
221
+ isVisible: true,
222
+ isLocked: false,
223
+ config: { // Type-specific config
224
+ url: 'https://example.com'
225
+ }
226
+ }
227
+ }));
228
+ ```
229
+
230
+ ### Remove App
231
+
232
+ ```javascript
233
+ ws.send(JSON.stringify({
234
+ type: 'app:removed',
235
+ timestamp: Date.now(),
236
+ source: 'agent',
237
+ data: { appId: 'app-123' }
238
+ }));
239
+ ```
240
+
241
+ ### Update App
242
+
243
+ Update position, size, visibility, lock state, or config:
244
+
245
+ ```javascript
246
+ ws.send(JSON.stringify({
247
+ type: 'app:updated',
248
+ timestamp: Date.now(),
249
+ source: 'agent',
250
+ data: {
251
+ appId: 'app-123',
252
+ x: 200, // Move app
253
+ y: 150,
254
+ width: 500, // Resize
255
+ height: 400,
256
+ isVisible: true, // Show/hide
257
+ isLocked: true, // Prevent dragging
258
+ config: { ... } // Update config
259
+ }
260
+ }));
261
+ ```
262
+
263
+ ---
264
+
265
+ ## App Types
266
+
267
+ ### Singleton vs Multi-Instance
268
+
269
+ Apps are categorized as **singleton** or **multi-instance**:
270
+
271
+ - **Singleton**: Only one instance per workspace. ID = app type. If you try to add a duplicate, it brings the existing one to front.
272
+ - **Multi-instance**: Can have multiple instances with different IDs. Use custom `id` like `wallet:0x123` or `iframe:my-chart`.
273
+
274
+ ### Built-in Apps (Singleton)
275
+
276
+ | Type | Description | Default Size |
277
+ |------|-------------|--------------|
278
+ | `wallets` | Wallet balances display | 320x400 |
279
+ | `logs` | Event log viewer | 600x300 |
280
+ | `send` | Send ETH form | 320x280 |
281
+ | `agentKeys` | Agent keys & approvals | 340x400 |
282
+ | `status` | System status | 320x200 |
283
+
284
+ ### Multi-Instance Apps
285
+
286
+ These app types can be opened multiple times with different IDs:
287
+
288
+ | Type | Description | Default Size |
289
+ |------|-------------|--------------|
290
+ | `walletDetail` | Detailed view of a single wallet | 320x380 |
291
+ | `iframe` | Embed external URL | 400x300 |
292
+ | `installed:*` | Installed apps from `apps/` folder | varies |
293
+
294
+ **Custom IDs**: Pass an `id` field to control identity:
295
+
296
+ ```javascript
297
+ // Multiple iframe apps with different IDs
298
+ { id: 'chart-eth', appType: 'iframe', config: { url: '...' } }
299
+ { id: 'chart-btc', appType: 'iframe', config: { url: '...' } }
300
+
301
+ // Wallet detail apps
302
+ { id: 'wallet:0x123...', appType: 'walletDetail', config: { address: '0x123...' } }
303
+
304
+ // Installed third-party apps
305
+ { appType: 'installed:example-kanban', config: { appPath: 'example-kanban', appName: 'Kanban Board' } }
306
+ ```
307
+
308
+ If no `id` is provided, one is auto-generated (e.g., `iframe-1738505123456`).
309
+
310
+ > For full details on creating and installing third-party apps, see [docs/APPS.md](./APPS.md).
311
+
312
+ #### IFrame App
313
+
314
+ Embed any URL:
315
+
316
+ ```javascript
317
+ {
318
+ appType: 'iframe',
319
+ config: {
320
+ url: 'https://example.com/chart',
321
+ title: 'Price Chart', // Optional
322
+ }
323
+ }
324
+ ```
325
+
326
+ > **Security note:** Iframes are sandboxed with `allow-scripts allow-forms` (no `allow-same-origin`). The sandbox policy is not configurable by agents to prevent sandbox escape.
327
+
328
+ #### Installed Apps
329
+
330
+ Third-party apps installed as folders under `apps/`. Each installed app consists of a `app.md` manifest and an `index.html` entry point, rendered inside a sandboxed iframe.
331
+
332
+ ```javascript
333
+ {
334
+ appType: 'installed:example-kanban',
335
+ config: {
336
+ appPath: 'example-kanban',
337
+ appName: 'Kanban Board'
338
+ }
339
+ }
340
+ ```
341
+
342
+ Installed apps appear in the App Store under the "INSTALLED" tab. For full details on creating, installing, and developing third-party apps (manifest format, SDK API, storage, security model), see [docs/APPS.md](./APPS.md).
343
+
344
+ ---
345
+
346
+ ## Strategy Events
347
+
348
+ The strategy engine broadcasts events over the WebSocket as strategies execute.
349
+
350
+ | Event | When | Data |
351
+ |-------|------|------|
352
+ | `strategy:tick` | Tick completes | `strategyId`, `intents` (count), `duration` (ms) |
353
+ | `strategy:enabled` | Strategy enabled | `strategyId` |
354
+ | `strategy:paused` | Strategy paused | `strategyId`, `reason` |
355
+ | `strategy:error` | Hook or action failed | `strategyId`, `error`, `phase` |
356
+ | `strategy:approve` | Intents awaiting approval | `strategyId`, `intents[]` |
357
+
358
+ ### Example: strategy:tick
359
+
360
+ ```json
361
+ {
362
+ "type": "strategy:tick",
363
+ "timestamp": 1707052800000,
364
+ "source": "express",
365
+ "data": {
366
+ "strategyId": "dca-eth",
367
+ "intents": 2,
368
+ "duration": 145
369
+ }
370
+ }
371
+ ```
372
+
373
+ ### Example: strategy:approve
374
+
375
+ Sent when a strategy produces intents that require human approval before execution.
376
+
377
+ ```json
378
+ {
379
+ "type": "strategy:approve",
380
+ "timestamp": 1707052800000,
381
+ "source": "express",
382
+ "data": {
383
+ "strategyId": "dca-eth",
384
+ "intents": [
385
+ { "id": "approval-123", "action": "swap", "params": { "token": "0x...", "amount": "0.05" } }
386
+ ]
387
+ }
388
+ }
389
+ ```
390
+
391
+ ### Example: strategy:error
392
+
393
+ ```json
394
+ {
395
+ "type": "strategy:error",
396
+ "timestamp": 1707052800000,
397
+ "source": "express",
398
+ "data": {
399
+ "strategyId": "dca-eth",
400
+ "error": "Hook 'beforeTick' threw: network timeout",
401
+ "phase": "hook"
402
+ }
403
+ }
404
+ ```
405
+
406
+ ---
407
+
408
+ ## REST API
409
+
410
+ Alternative to WebSocket for simple CRUD operations.
411
+
412
+ ### Workspaces
413
+
414
+ ```bash
415
+ # List all workspaces
416
+ GET /api/workspace
417
+
418
+ # Create workspace
419
+ POST /api/workspace
420
+ { "name": "TRADING", "icon": "TrendingUp" }
421
+
422
+ # Get workspace with apps
423
+ GET /api/workspace/:id
424
+
425
+ # Update workspace
426
+ PATCH /api/workspace/:id
427
+ { "name": "NEW NAME" }
428
+
429
+ # Delete workspace
430
+ DELETE /api/workspace/:id
431
+ ```
432
+
433
+ ### Apps
434
+
435
+ ```bash
436
+ # Add app to workspace
437
+ POST /api/workspace/:id/apps
438
+ {
439
+ "appType": "iframe",
440
+ "config": { "url": "https://example.com" },
441
+ "x": 100, "y": 100
442
+ }
443
+
444
+ # Update app
445
+ PATCH /api/workspace/:id/apps/:wid
446
+ { "x": 200, "y": 150, "width": 500 }
447
+
448
+ # Remove app
449
+ DELETE /api/workspace/:id/apps/:wid
450
+ ```
451
+
452
+ ### Export/Import
453
+
454
+ ```bash
455
+ # Export workspace as JSON
456
+ GET /api/workspace/:id/export
457
+
458
+ # Import workspace from JSON
459
+ POST /api/workspace/import
460
+ {
461
+ "workspace": { "name": "Imported", "icon": "Download" },
462
+ "apps": [
463
+ { "appType": "logs", "x": 20, "y": 20 }
464
+ ]
465
+ }
466
+ ```
467
+
468
+ ---
469
+
470
+ ## Persistence
471
+
472
+ - All changes auto-save to SQLite database (500ms debounce)
473
+ - Workspaces persist across server restarts
474
+ - Default "HOME" workspace created automatically
475
+
476
+ ---
477
+
478
+ ## Example: Full Agent Session
479
+
480
+ ```javascript
481
+ // Connect with authentication token
482
+ const token = 'your-agent-token'; // Obtained from /auth endpoint
483
+ const ws = new WebSocket(`ws://localhost:4748?token=${encodeURIComponent(token)}`);
484
+
485
+ ws.onopen = async () => {
486
+ // 1. Get current state (no auth required for queries)
487
+ const requestId = 'req-' + Date.now();
488
+ ws.send(JSON.stringify({
489
+ type: 'workspace:state:request',
490
+ timestamp: Date.now(),
491
+ source: 'agent',
492
+ data: { requestId }
493
+ }));
494
+ };
495
+
496
+ ws.onmessage = (event) => {
497
+ const msg = JSON.parse(event.data);
498
+
499
+ if (msg.type === 'workspace:state:response') {
500
+ const workspaceId = msg.data.activeWorkspaceId;
501
+
502
+ // 2. Add a price chart iframe
503
+ ws.send(JSON.stringify({
504
+ type: 'app:added',
505
+ timestamp: Date.now(),
506
+ source: 'agent',
507
+ data: {
508
+ workspaceId,
509
+ appType: 'iframe',
510
+ config: { url: 'https://www.tradingview.com/chart/', title: 'TradingView' },
511
+ x: 400, y: 20, width: 800, height: 500
512
+ }
513
+ }));
514
+
515
+ // 3. Add an installed third-party app
516
+ ws.send(JSON.stringify({
517
+ type: 'app:added',
518
+ timestamp: Date.now(),
519
+ source: 'agent',
520
+ data: {
521
+ workspaceId,
522
+ appType: 'installed:example-kanban',
523
+ config: { appPath: 'example-kanban', appName: 'Kanban Board' },
524
+ x: 20, y: 20, width: 640, height: 560
525
+ }
526
+ }));
527
+ }
528
+ };
529
+ ```
530
+
531
+ ---
532
+
533
+ ## Theme System
534
+
535
+ The dashboard supports light/dark mode and accent color customization via WebSocket events.
536
+
537
+ ### Query Current Theme
538
+
539
+ ```javascript
540
+ ws.send(JSON.stringify({
541
+ type: 'theme:request',
542
+ timestamp: Date.now(),
543
+ source: 'agent',
544
+ data: { requestId: 'req-123' }
545
+ }));
546
+ ```
547
+
548
+ Response:
549
+
550
+ ```javascript
551
+ {
552
+ type: 'theme:response',
553
+ data: {
554
+ requestId: 'req-123',
555
+ activeThemeId: 'light',
556
+ accentColor: '#ccff00',
557
+ mode: 'light'
558
+ }
559
+ }
560
+ ```
561
+
562
+ ### Change Theme Mode (Light/Dark)
563
+
564
+ > **Authentication Required**: Theme changes require `workspace:modify` permission or admin access.
565
+
566
+ ```javascript
567
+ ws.send(JSON.stringify({
568
+ type: 'theme:mode:changed',
569
+ timestamp: Date.now(),
570
+ source: 'agent',
571
+ data: { mode: 'dark' } // 'light' or 'dark'
572
+ }));
573
+ ```
574
+
575
+ ### Change Accent Color
576
+
577
+ ```javascript
578
+ ws.send(JSON.stringify({
579
+ type: 'theme:accent:changed',
580
+ timestamp: Date.now(),
581
+ source: 'agent',
582
+ data: { accent: '#ff4d00' } // Any hex color
583
+ }));
584
+ ```
585
+
586
+ ### Theme-Aware Apps
587
+
588
+ When creating installed apps, use CSS variables for automatic theme support. The host injects theme CSS variables into every app iframe, so your app automatically adapts to light/dark mode and accent color changes.
589
+
590
+ ```html
591
+ <!-- In your installed app's index.html -->
592
+ <style>
593
+ body {
594
+ background: var(--color-surface, #fff);
595
+ color: var(--color-text, #0a0a0a);
596
+ border: 1px solid var(--color-border, #d4d4d8);
597
+ padding: 16px;
598
+ font-family: ui-monospace, monospace;
599
+ }
600
+ .label {
601
+ color: var(--color-text-muted, #6b7280);
602
+ font-size: 10px;
603
+ }
604
+ .highlight {
605
+ color: var(--color-accent, #ccff00);
606
+ font-weight: bold;
607
+ }
608
+ </style>
609
+ ```
610
+
611
+ > For the full list of injected CSS variables and theming details for installed apps, see [DEVELOPING-APPS.md](./DEVELOPING-APPS.md#theming).
612
+
613
+ ### Available CSS Variables
614
+
615
+ **Core Colors:**
616
+ - `--color-accent` - Primary accent color (default: #ccff00)
617
+ - `--color-background` - Page background
618
+ - `--color-background-alt` - Alternate background (e.g., sidebar)
619
+ - `--color-surface` - Card/app background
620
+ - `--color-surface-alt` - Alternate surface
621
+
622
+ **Text:**
623
+ - `--color-text` - Primary text
624
+ - `--color-text-muted` - Secondary text
625
+ - `--color-text-faint` - Tertiary/disabled text
626
+
627
+ **Borders:**
628
+ - `--color-border` - Default border
629
+ - `--color-border-muted` - Subtle border
630
+ - `--color-border-focus` - Focus ring
631
+
632
+ **Semantic:**
633
+ - `--color-warning` - Warning state (#ff4d00)
634
+ - `--color-danger` - Error/danger state (#ef4444)
635
+ - `--color-success` - Success state (#00c853)
636
+ - `--color-info` - Info state (#0047ff)
637
+
638
+ **App Palette:**
639
+ - `--app-{color}-band` - App header band color
640
+ - `--app-{color}-accent` - App border accent
641
+ - `--app-{color}-bg` - App background tint
642
+ - `--app-{color}-text` - App text color
643
+
644
+ Where `{color}` is: `blue`, `orange`, `lime`, `purple`, `gray`, `teal`, `rose`
645
+
646
+ ### Theme Events Reference
647
+
648
+ | Event | Direction | Description |
649
+ |-------|-----------|-------------|
650
+ | `theme:request` | Agent → Server | Query current theme state |
651
+ | `theme:response` | Server → Agent | Response with theme data |
652
+ | `theme:mode:changed` | Agent/UI → Server → Broadcast | Toggle light/dark mode |
653
+ | `theme:accent:changed` | Agent/UI → Server → Broadcast | Change accent color |
654
+ | `workspace:theme:updated` | Agent/UI → Server → Broadcast | Per-workspace overrides |
655
+
656
+ ### CLI Theme Control
657
+
658
+ Quick theme toggle from command line (requires authentication):
659
+
660
+ ```bash
661
+ # Set your token
662
+ TOKEN="your-agent-token"
663
+
664
+ # Switch to dark mode
665
+ node -e "const ws = new (require('ws'))('ws://localhost:4748?token=$TOKEN'); ws.on('open', () => { ws.send(JSON.stringify({type:'theme:mode:changed',timestamp:Date.now(),source:'agent',data:{mode:'dark'}})); setTimeout(() => process.exit(), 500); });"
666
+
667
+ # Switch to light mode
668
+ node -e "const ws = new (require('ws'))('ws://localhost:4748?token=$TOKEN'); ws.on('open', () => { ws.send(JSON.stringify({type:'theme:mode:changed',timestamp:Date.now(),source:'agent',data:{mode:'light'}})); setTimeout(() => process.exit(), 500); });"
669
+
670
+ # Change accent color
671
+ node -e "const ws = new (require('ws'))('ws://localhost:4748?token=$TOKEN'); ws.on('open', () => { ws.send(JSON.stringify({type:'theme:accent:changed',timestamp:Date.now(),source:'agent',data:{accent:'#ff4d00'}})); setTimeout(() => process.exit(), 500); });"
672
+ ```