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,713 @@
1
+ # Developing Strategies
2
+
3
+ Reference for extending an app with AI-powered automation — strategy manifest fields, hooks, sources, intents, and examples.
4
+
5
+ A strategy is an app with additional manifest fields that activate the AI engine. Start with [DEVELOPING-APPS.md](../DEVELOPING-APPS.md) for the base app manifest, SDK, and security model.
6
+
7
+ For a high-level overview, see [STRATEGY.md](./STRATEGY.md). For AI engine internals (provider selection, tool-use loop, testing), see [AI.md](./AI.md).
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Strategy Manifest Fields](#strategy-manifest-fields)
12
+ 2. [Tick Tiers and Jobs](#tick-tiers-and-jobs)
13
+ 3. [Hooks Lifecycle](#hooks-lifecycle)
14
+ 4. [Hook Response Format](#hook-response-format)
15
+ 5. [Hook Contexts](#hook-contexts)
16
+ 6. [Intent Format and Approval Modes](#intent-format-and-approval-modes)
17
+ 7. [Pre-Computed Actions](#pre-computed-actions)
18
+ 8. [Sources](#sources)
19
+ 9. [Config](#config)
20
+ 10. [Auto-Granted Permissions](#auto-granted-permissions)
21
+ 11. [Budget-Aware Intent Decisions](#budget-aware-intent-decisions)
22
+ 12. [State Management](#state-management)
23
+ 13. [Error Handling Config](#error-handling-config)
24
+ 14. [Validation Rules](#validation-rules)
25
+ 15. [Tool-Use in Hooks](#tool-use-in-hooks)
26
+ 16. [AI Provider Selection and Tiered Models](#ai-provider-selection-and-tiered-models)
27
+ 17. [DB-Backed Template Strategies](#db-backed-template-strategies)
28
+ 18. [Example: Tick-Mode Strategy](#example-tick-mode-strategy)
29
+ 19. [Example: Message-Mode Chat App](#example-message-mode-chat-app)
30
+
31
+ ---
32
+
33
+ ## Strategy Manifest Fields
34
+
35
+ The manifest is a Markdown file (`app.md`) with YAML frontmatter — the same format used by all apps (see [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#manifest-reference)). The body text after `---` is the description shown in the App Store. A strategy adds the fields below to the base app manifest.
36
+
37
+ ### Base Fields (from app manifest)
38
+
39
+ These fields are shared with all apps. See [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#manifest-reference) for full details.
40
+
41
+ | Field | Type | Required | Default | Description |
42
+ |-------|------|:---:|---------|-------------|
43
+ | `name` | string | yes | folder name | Display name |
44
+ | `icon` | string | no | `Box` | [Lucide](https://lucide.dev) icon name |
45
+ | `category` | string | no | `general` | App Store category filter |
46
+ | `size` | string | no | `1x1` | Default grid size `WxH` (1=320x280, 2=640x560, 3=960x840) |
47
+ | `permissions` | string[] | no | `[]` | Wallet permissions the app needs |
48
+
49
+ ### Strategy Fields
50
+
51
+ These fields activate the AI engine and are specific to strategies.
52
+
53
+ | Field | Type | Required | Default | Description |
54
+ |-------|------|:---:|---------|-------------|
55
+ | `autoStart` | boolean | no | `false` | Auto-enable on engine startup |
56
+ | `ticker` | string | no | — | Tick tier. One of: `sniper`, `active`, `standard`, `slow`, `maintenance`. Mutually exclusive with `jobs`. |
57
+ | `jobs` | array | no | — | Multi-interval jobs. Mutually exclusive with `ticker`. |
58
+ | `sources` | array | no | `[]` | External data endpoints fetched each tick |
59
+ | `keys` | array | no | — | API key declarations |
60
+ | `hooks` | object | yes* | — | Hook instructions (at least one of `tick` or `message` required) |
61
+ | `config` | object | no | `{}` | Strategy config passed to hooks |
62
+ | `limits` | object | no | — | Spending caps: `{ fund?: number, send?: number }` |
63
+ | `allowedHosts` | string[] | no | `[]` | Hostnames allowed for external fetches (SSRF allowlist) |
64
+
65
+ ### Permissions
66
+
67
+ Strategies use the same permission system as all apps. Strategies with permissions or limits require human approval before the engine creates auth tokens.
68
+
69
+ See [DEVELOPING-APPS.md](../DEVELOPING-APPS.md#permissions) for the full permissions table, or [AUTH.md](../AUTH.md) for complete auth details.
70
+
71
+ Note: the `action:create` permission is required for strategies that use the `request_human_action` tool in message hooks.
72
+
73
+ ### Limits
74
+
75
+ Spending caps embedded in the strategy's token:
76
+
77
+ ```yaml
78
+ limits:
79
+ fund: 1.0 # Max 1 ETH cold-to-hot transfer
80
+ send: 0.5 # Max 0.5 ETH sends
81
+ ```
82
+
83
+ ### Allowed Hosts
84
+
85
+ Hostnames (no protocol, no path) the strategy engine may fetch. Hosts from `sources[].url` are auto-derived, so you only need to list additional hosts used by templated URLs or external action endpoints.
86
+
87
+ ```yaml
88
+ allowedHosts:
89
+ - api.coingecko.com
90
+ - api.dexscreener.com
91
+ ```
92
+
93
+ Private/reserved hosts (`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, etc.) are always blocked.
94
+
95
+ ---
96
+
97
+ ## Tick Tiers and Jobs
98
+
99
+ ### Tick Tiers
100
+
101
+ | Tier | Interval | Use Case |
102
+ |------|----------|----------|
103
+ | `sniper` | 10 seconds | Time-critical sniping, MEV |
104
+ | `active` | 30 seconds | Active trading, price triggers |
105
+ | `standard` | 1 minute | General monitoring |
106
+ | `slow` | 5 minutes | Portfolio tracking, reporting |
107
+ | `maintenance` | 1 hour | Daily buys, maintenance tasks |
108
+
109
+ ### Jobs
110
+
111
+ For strategies that need multiple tick intervals, use `jobs` instead of `ticker`:
112
+
113
+ ```yaml
114
+ jobs:
115
+ - id: price_check
116
+ ticker: active
117
+ sources:
118
+ - price # Only fetch these sources for this job
119
+ - id: rebalance
120
+ ticker: maintenance
121
+ sources:
122
+ - portfolio
123
+ ```
124
+
125
+ | Field | Type | Required | Description |
126
+ |-------|------|:---:|-------------|
127
+ | `id` | string | yes | Job identifier (passed to tick context) |
128
+ | `ticker` | string | yes | Tick tier for this job |
129
+ | `sources` | string[] | no | Source IDs to fetch (defaults to all) |
130
+
131
+ ---
132
+
133
+ ## Hooks Lifecycle
134
+
135
+ Six lifecycle hooks. Each is a natural-language string instructing the AI what to do. The engine passes structured JSON context and expects a JSON response.
136
+
137
+ | Hook | When Called | Mode |
138
+ |------|-----------|------|
139
+ | `init` | Strategy enabled | Tick |
140
+ | `tick` | Every scheduled interval | Tick |
141
+ | `execute` | Per approved intent (if no pre-computed action) | Tick |
142
+ | `result` | After action execution | Tick |
143
+ | `shutdown` | Strategy disabled | Tick |
144
+ | `message` | Human sends a message | Message |
145
+
146
+ ### Tick Mode Flow
147
+
148
+ ```
149
+ fetch sources -> tick hook -> intents -> (approve?) -> execute hook -> action -> result hook
150
+ ```
151
+
152
+ 1. Engine fetches all `sources`
153
+ 2. Calls `tick` hook with source data, state, config, budget
154
+ 3. AI returns intents (what to do)
155
+ 4. If `config.approve: true` or intent has `permissions[]`, human approves
156
+ 5. For each approved intent: `execute` hook (or pre-computed action) -> API call -> `result` hook
157
+ 6. `result` hook can return follow-up intents (depth limit: 3)
158
+
159
+ ### Message Mode Flow
160
+
161
+ ```
162
+ user message -> message hook (with tools) -> reply + optional intents
163
+ ```
164
+
165
+ 1. User sends message via `AuraApp.send()` or adapter
166
+ 2. Engine calls `message` hook with AI tools (`wallet_api`, `request_human_action`)
167
+ 3. AI uses tools directly (try action -> 403 -> request approval)
168
+ 4. Returns reply text and state updates
169
+
170
+ ### Auto-Injected Context
171
+
172
+ You do **not** need to embed API docs or intent format instructions in your hooks. The engine auto-injects (via `hook-context.ts`):
173
+
174
+ - API endpoint reference (from `docs/API.md`)
175
+ - Response format specification
176
+ - Intent format with `permissions`, `limits`, `ttl`, `action`, `summary` fields
177
+ - Wallet tier documentation (COLD/HOT/TEMP)
178
+ - Budget-aware decision logic
179
+
180
+ Keep hook instructions focused on your app's specific behavior.
181
+
182
+ ---
183
+
184
+ ## Hook Response Format
185
+
186
+ All hooks return `HookResult`:
187
+
188
+ ```json
189
+ {
190
+ "reply": "Text response to the user (message hooks)",
191
+ "state": { "key": "persisted state values" },
192
+ "intents": [{ "type": "swap", "token": "0xABC" }],
193
+ "log": "Optional log message",
194
+ "emit": { "channel": "event-name", "data": { "price": 42 } }
195
+ }
196
+ ```
197
+
198
+ | Field | Type | Description |
199
+ |-------|------|-------------|
200
+ | `reply` | string | Text reply sent to the user (message hooks) |
201
+ | `state` | object | Key-value state updates to persist across ticks |
202
+ | `log` | string | Fallback reply if `reply` is absent; also logged |
203
+ | `intents` | array | High-level intents for the engine to execute (tick mode) |
204
+ | `emit` | object or array | Custom events pushed to the app's iframe. `{ channel, data }` or `[{ channel, data }, ...]` |
205
+
206
+ ### Mode-Specific Response Patterns
207
+
208
+ **Tick mode** hooks should return:
209
+ ```json
210
+ { "state": { ... }, "intents": [{ "type": "buy", ... }] }
211
+ ```
212
+
213
+ **Message mode** hooks should return:
214
+ ```json
215
+ { "reply": "Response text", "state": { ... } }
216
+ ```
217
+
218
+ Message hooks use the tool-call flow (wallet_api + request_human_action) instead of intents. You can still return intents from message hooks, but it's not the recommended pattern.
219
+
220
+ ---
221
+
222
+ ## Hook Contexts
223
+
224
+ Each hook receives a structured JSON context. These are the TypeScript interfaces for reference.
225
+
226
+ ### TickContext (tick hook)
227
+
228
+ ```typescript
229
+ {
230
+ sources: Record<string, unknown[]>; // Fetched source data by source ID
231
+ positions?: unknown[]; // Wallet positions
232
+ state: Record<string, unknown>; // Persisted strategy state
233
+ config: StrategyConfig; // Manifest config + overrides
234
+ wallets?: unknown[]; // Available wallets
235
+ permissions: string[]; // App token's permissions
236
+ budget: {
237
+ limits: Record<string, number>; // Spending caps (ETH)
238
+ spent: Record<string, number>; // Already spent this session
239
+ remaining: Record<string, number>; // Remaining budget
240
+ };
241
+ }
242
+ ```
243
+
244
+ ### ExecuteContext (execute hook)
245
+
246
+ ```typescript
247
+ {
248
+ intent: Intent; // The approved intent to convert to an action
249
+ wallet?: unknown; // Selected wallet
250
+ config: StrategyConfig; // Manifest config
251
+ }
252
+ ```
253
+
254
+ ### ResultContext (result hook)
255
+
256
+ ```typescript
257
+ {
258
+ intent: Intent; // The original intent
259
+ action: Action; // The executed API call
260
+ outcome: ActionOutcome; // { success: boolean, data?, error? }
261
+ state: Record<string, unknown>;
262
+ }
263
+ ```
264
+
265
+ ### InitContext (init hook)
266
+
267
+ ```typescript
268
+ {
269
+ config: StrategyConfig;
270
+ wallets?: unknown[];
271
+ state: Record<string, unknown>;
272
+ storage?: Record<string, unknown>;
273
+ }
274
+ ```
275
+
276
+ ### ShutdownContext (shutdown hook)
277
+
278
+ ```typescript
279
+ {
280
+ positions?: unknown[];
281
+ state: Record<string, unknown>;
282
+ }
283
+ ```
284
+
285
+ ### MessageContext (message hook)
286
+
287
+ ```typescript
288
+ {
289
+ message: string; // User's message text
290
+ appId: string; // App identifier
291
+ state: Record<string, unknown>;
292
+ config: StrategyConfig;
293
+ permissions: string[]; // App token's permissions
294
+ budget: {
295
+ limits: Record<string, number>;
296
+ spent: Record<string, number>;
297
+ remaining: Record<string, number>;
298
+ };
299
+ }
300
+ ```
301
+
302
+ ---
303
+
304
+ ## Intent Format and Approval Modes
305
+
306
+ Intents returned by `tick` or `message` hooks:
307
+
308
+ ```json
309
+ {
310
+ "type": "swap",
311
+ "summary": "Buy 0.01 ETH of TOKEN",
312
+ "permissions": ["swap"],
313
+ "limits": { "swap": 0.01 },
314
+ "ttl": 60,
315
+ "action": {
316
+ "endpoint": "/swap",
317
+ "method": "POST",
318
+ "body": { "tokenIn": "ETH", "tokenOut": "0xABC", "amountIn": "0.01" }
319
+ }
320
+ }
321
+ ```
322
+
323
+ | Field | Type | Required | Description |
324
+ |-------|------|:---:|-------------|
325
+ | `type` | string | yes | Intent type label |
326
+ | `summary` | string | no | Human-readable description for approval card |
327
+ | `permissions` | string[] | no | Triggers per-action token flow with human approval |
328
+ | `limits` | object | no | Spending caps for the temp token |
329
+ | `ttl` | number | no | Token lifetime in seconds (default: 60) |
330
+ | `action` | object | no | Pre-computed API call (skips `execute` hook) |
331
+ | `action.endpoint` | string | — | API path (`/swap`) or external URL |
332
+ | `action.method` | string | — | HTTP method |
333
+ | `action.body` | object | — | Request body |
334
+ | `action.headers` | object | — | Custom headers |
335
+
336
+ ### Approval Modes
337
+
338
+ | Intent has `permissions`? | `config.approve`? | Result |
339
+ |:---:|:---:|---|
340
+ | Yes | Any | Per-action token, individual approval per intent |
341
+ | No | true | Batch boolean approval |
342
+ | No | false | No approval needed |
343
+
344
+ ---
345
+
346
+ ## Pre-Computed Actions
347
+
348
+ Hooks can return intents with an `action` field to skip the `execute` hook entirely:
349
+
350
+ ```json
351
+ {
352
+ "type": "swap",
353
+ "summary": "Buy 0.01 ETH of TOKEN",
354
+ "action": {
355
+ "endpoint": "/swap",
356
+ "method": "POST",
357
+ "body": { "tokenIn": "ETH", "tokenOut": "0xABC", "amountIn": "0.01" }
358
+ }
359
+ }
360
+ ```
361
+
362
+ When `action` is present, the engine calls the API directly instead of invoking the `execute` hook. This is useful when the tick hook already has all the information needed to construct the API call.
363
+
364
+ ---
365
+
366
+ ## Sources
367
+
368
+ External data endpoints fetched before each tick. Results are passed to the `tick` hook as `sources.<id>`.
369
+
370
+ ```yaml
371
+ sources:
372
+ - id: price
373
+ url: https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd
374
+ method: GET
375
+ select:
376
+ items: $.ethereum
377
+ price: $.usd
378
+
379
+ - id: holders
380
+ url: https://api.example.com/holders/${token}
381
+ method: GET
382
+ auth: header
383
+ header: X-API-KEY
384
+ key: example_key
385
+ depends: price
386
+ optional: true
387
+ select:
388
+ items: $.data
389
+ address: $.holder
390
+ balance: $.amount
391
+ ```
392
+
393
+ ### Source Fields
394
+
395
+ | Field | Type | Required | Default | Description |
396
+ |-------|------|:---:|---------|-------------|
397
+ | `id` | string | yes | — | Unique identifier (referenced in `jobs[].sources` and `depends`) |
398
+ | `url` | string | yes | — | URL template. `${var}` resolves from parent source `select` fields or `config` |
399
+ | `method` | string | yes | — | `GET` or `POST` |
400
+ | `body` | object | no | — | POST request body template |
401
+ | `auth` | string | no | `none` | Auth mode: `none`, `header`, `query`, `bearer` |
402
+ | `header` | string | no | — | Header name when `auth: header` |
403
+ | `query` | string | no | — | Query param name when `auth: query` |
404
+ | `key` | string | no | — | App storage key to read the API key from |
405
+ | `depends` | string | no | — | Source ID that must run first (enables URL template chaining) |
406
+ | `job` | string | no | — | Job ID this source belongs to |
407
+ | `optional` | boolean | no | `false` | Skip if API key not found in storage |
408
+ | `rateLimit` | string | no | — | Rate limit specification |
409
+ | `select` | object | no | — | JSONPath extraction: `items` = path to array, other keys = per-item field paths |
410
+
411
+ ### URL Templates
412
+
413
+ Source URLs can contain `${var}` placeholders resolved from:
414
+ 1. `select` fields of a parent source (via `depends`)
415
+ 2. `config` values
416
+
417
+ Templated external URLs require explicit `allowedHosts`.
418
+
419
+ ### API Key Auth
420
+
421
+ Sources that need auth reference a key stored in app storage:
422
+
423
+ ```yaml
424
+ - id: analytics
425
+ url: https://public-api.birdeye.so/defi/token_overview?address=${mint}
426
+ auth: header
427
+ header: X-API-KEY
428
+ key: birdeye # reads from AuraApp.storage.get('birdeye')
429
+ optional: true # skip if key not in storage
430
+ ```
431
+
432
+ The app developer builds the UI for entering and saving the key via `AuraApp.storage.set('birdeye', 'sk-...')`.
433
+
434
+ ### Keys
435
+
436
+ Declare API keys the strategy needs. Informational — helps users know which keys to configure.
437
+
438
+ ```yaml
439
+ keys:
440
+ - id: birdeye
441
+ name: Birdeye API Key
442
+ required: false
443
+ description: Used for token analytics data
444
+ ```
445
+
446
+ | Field | Type | Required | Description |
447
+ |-------|------|:---:|-------------|
448
+ | `id` | string | yes | Key identifier (matches `sources[].key`) |
449
+ | `name` | string | yes | Display name |
450
+ | `required` | boolean | no | Whether the key is required for the app to function |
451
+ | `description` | string | no | What the key is used for |
452
+
453
+ ---
454
+
455
+ ## Config
456
+
457
+ The `config` object is passed to every hook invocation. It supports both special engine-recognized fields and custom fields.
458
+
459
+ ### Special Config Fields
460
+
461
+ | Field | Type | Description |
462
+ |-------|------|-------------|
463
+ | `wallet` | string | Preferred wallet address or `"auto"` |
464
+ | `approve` | boolean | `true` = require batch human approval between tick and execute |
465
+ | `mode` | string | `"live"` (execute actions) or `"paper"` (log only, no execution) |
466
+
467
+ All other config keys are custom and passed through to hooks.
468
+
469
+ ---
470
+
471
+ ## Auto-Granted Permissions
472
+
473
+ The engine auto-grants these permissions — you don't need to list them in `permissions`:
474
+
475
+ - `app:storage` — State persistence (always granted)
476
+ - `app:accesskey` — Granted when sources use `key` fields
477
+
478
+ ---
479
+
480
+ ## Budget-Aware Intent Decisions
481
+
482
+ The tick context includes a `budget` object with `limits`, `spent`, and `remaining` fields. The engine auto-injects budget-aware decision logic into the system context, so hook AIs can make informed decisions about whether to proceed with an action based on remaining budget.
483
+
484
+ ```json
485
+ {
486
+ "budget": {
487
+ "limits": { "swap": 0.1 },
488
+ "spent": { "swap": 0.03 },
489
+ "remaining": { "swap": 0.07 }
490
+ }
491
+ }
492
+ ```
493
+
494
+ ---
495
+
496
+ ## State Management
497
+
498
+ - **In-memory**: `Map<string, Record<string, unknown>>` per app
499
+ - **Persistence**: REST calls to app storage (`PUT /apps/{id}/storage/_strategy_state`)
500
+ - **Restore**: Read from DB at tick start (picks up UI changes)
501
+ - **Auto-persist**: Every 5 minutes + on disable + on error
502
+
503
+ State is passed to hooks via the `state` field in the context and updated via the `state` field in the hook response.
504
+
505
+ ---
506
+
507
+ ## Error Handling Config
508
+
509
+ Configure how the engine handles failures via `config.errors`:
510
+
511
+ ```yaml
512
+ config:
513
+ errors:
514
+ sourceFail: skip # What to do when a source fetch fails
515
+ executeFail: skip # What to do when an action fails
516
+ maxRetries: 3 # Max consecutive retries before pausing
517
+ cooldown: "5m" # Pause duration after max retries
518
+ ```
519
+
520
+ | Field | Type | Default | Options | Description |
521
+ |-------|------|---------|---------|-------------|
522
+ | `sourceFail` | string | `skip` | `skip`, `retry`, `pause` | Behavior on source fetch failure |
523
+ | `executeFail` | string | `skip` | `skip`, `pause` | Behavior on action execution failure |
524
+ | `maxRetries` | number | — | — | Consecutive error count before pausing |
525
+ | `cooldown` | string | — | Duration string | Pause duration (e.g., `"5m"`, `"1h"`) |
526
+
527
+ ---
528
+
529
+ ## Validation Rules
530
+
531
+ The loader (`server/lib/strategy/loader.ts`) enforces these rules. A manifest that fails validation is skipped with a console error.
532
+
533
+ ### Required Structure
534
+
535
+ - Must have **at least one** of: `ticker`, `jobs`, or `hooks.message`
536
+ - If `ticker` or `jobs` is set, `hooks.tick` is **required**
537
+ - `ticker` must be one of: `sniper`, `active`, `standard`, `slow`, `maintenance`
538
+ - Each job must have `id` and a valid `ticker`
539
+
540
+ ### Source Validation
541
+
542
+ - Source `depends` must reference an existing source `id`
543
+ - No circular dependencies between sources
544
+ - Source URLs cannot point to private/reserved hosts (`localhost`, `127.0.0.1`, `10.x`, `192.168.x`, `::1`, etc.)
545
+ - If a source URL uses templates (`${var}`) and points externally, `allowedHosts` must be declared
546
+ - Source hosts must be listed in `allowedHosts` (auto-derived from static URLs, but templated URLs need explicit declaration)
547
+
548
+ ### Host Validation
549
+
550
+ - `allowedHosts` entries cannot be private/reserved IPs or hostnames
551
+ - Hostnames only (no protocol, no path, no port)
552
+
553
+ ---
554
+
555
+ ## Tool-Use in Hooks
556
+
557
+ Hook AIs can call the wallet API mid-conversation:
558
+
559
+ - **`wallet_api`** — `{ method, endpoint, body }` — call any wallet server endpoint
560
+ - **`request_human_action`** — request approval for a privileged action (message hooks only)
561
+
562
+ See [AI.md](./AI.md#tool-use-api-access) for the full tool-use reference.
563
+
564
+ ---
565
+
566
+ ## AI Provider Selection and Tiered Models
567
+
568
+ Models are auto-selected using a 3-tier system based on the hook name and the token's permissions. No user configuration needed.
569
+
570
+ | Tier | When |
571
+ |------|------|
572
+ | `fast` | `init`/`shutdown` hooks, no token, or read-only permissions |
573
+ | `standard` | Write permissions (`wallet:create:hot`, `wallet:create:temp`) |
574
+ | `powerful` | Financial permissions (`swap`, `send:hot`, `send:temp`, `fund`, `launch`) or `admin:*` |
575
+
576
+ See [AI.md](./AI.md#ai-provider-selection) for provider details, model mappings, and configuration.
577
+
578
+ ---
579
+
580
+ ## DB-Backed Template Strategies
581
+
582
+ In addition to file-based `app.md` manifests, strategies can be created via the API from pre-built templates. These use the same `StrategyManifest` shape internally but are stored in the database.
583
+
584
+ Available templates: `recurring_buy`, `buy_on_drop`, `stop_loss`, `portfolio_report`.
585
+
586
+ ```bash
587
+ # Create from template
588
+ curl -X POST http://localhost:4242/strategies \
589
+ -H "Authorization: Bearer <token>" \
590
+ -d '{ "templateId": "recurring_buy", "name": "Daily ETH Buy", "config": { ... } }'
591
+
592
+ # Install from raw manifest
593
+ curl -X POST http://localhost:4242/strategies/install \
594
+ -H "Authorization: Bearer <token>" \
595
+ -d '{ "manifest": { ... }, "approve": false }'
596
+ ```
597
+
598
+ Template strategies have Zod-validated config schemas and capped permissions/limits defined by the template. See `server/lib/strategy/templates.ts` for template definitions.
599
+
600
+ ---
601
+
602
+ ## Example: Tick-Mode Strategy
603
+
604
+ A price-alert app that monitors a token and emits a notification when the price drops.
605
+
606
+ ```markdown
607
+ ---
608
+ name: Price Alert
609
+ icon: Bell
610
+ category: strategy
611
+ size: 2x1
612
+ permissions:
613
+ - wallet:list
614
+ allowedHosts: []
615
+
616
+ ticker: standard
617
+
618
+ sources:
619
+ - id: price
620
+ url: /price/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
621
+ method: GET
622
+ select:
623
+ items: $
624
+ priceUsd: $.priceUsd
625
+
626
+ hooks:
627
+ init: |
628
+ Initialize state with empty lastPrice. No wallets needed for this strategy.
629
+ Return: { "state": { "lastPrice": null, "alertCount": 0 } }
630
+
631
+ tick: |
632
+ Compare current price to state.lastPrice.
633
+ If price dropped more than 5% since last check, return a notify intent.
634
+ Always update state.lastPrice with current price.
635
+
636
+ If no significant change:
637
+ { "state": { "lastPrice": <current> }, "intents": [] }
638
+
639
+ If price dropped >5%:
640
+ {
641
+ "state": { "lastPrice": <current>, "alertCount": <state.alertCount + 1> },
642
+ "intents": [],
643
+ "emit": { "channel": "price-alert", "data": { "price": <current>, "drop": <percent> } }
644
+ }
645
+
646
+ shutdown: |
647
+ No cleanup needed.
648
+ Return: { "state": {} }
649
+
650
+ config:
651
+ dropThreshold: 5
652
+ mode: live
653
+ ---
654
+
655
+ Monitors USDC price on Base and emits an alert when it drops more than 5%.
656
+ Simple read-only strategy with no trading actions.
657
+ ```
658
+
659
+ ### What makes this valid
660
+
661
+ - Has `ticker: standard` (1-minute interval)
662
+ - Has `hooks.tick` (required when ticker is set)
663
+ - Source URL starts with `/` (internal endpoint, no SSRF restrictions)
664
+ - Uses `emit` to push events to the app iframe instead of executing actions
665
+ - Minimal permissions (`wallet:list` is read-only)
666
+
667
+ ---
668
+
669
+ ## Example: Message-Mode Chat App
670
+
671
+ A chat assistant that helps users check balances and request swaps.
672
+
673
+ ```markdown
674
+ ---
675
+ name: Swap Chat
676
+ icon: MessageCircle
677
+ category: tools
678
+ size: 2x2
679
+ permissions:
680
+ - wallet:list
681
+ - action:create
682
+ allowedHosts: []
683
+
684
+ hooks:
685
+ message: |
686
+ You are a token swap assistant for AuraMaxx on Base chain.
687
+
688
+ Use wallet_api to look up wallets and balances. NEVER guess addresses.
689
+
690
+ When the user wants to swap tokens:
691
+ 1. Look up their wallets with wallet_api GET /wallets
692
+ 2. Try the swap with wallet_api POST /swap
693
+ 3. If you get 403, call request_human_action with the swap details
694
+ 4. Tell the user approval has been requested
695
+
696
+ NEVER say "I don't have permission." ALWAYS use request_human_action.
697
+
698
+ Keep replies concise (2-3 sentences).
699
+
700
+ config: {}
701
+ ---
702
+
703
+ A simple swap assistant. Ask it to swap tokens and it will
704
+ handle wallet lookup and approval requests automatically.
705
+ ```
706
+
707
+ ### What makes this valid
708
+
709
+ - Has `hooks.message` (message-only app, no ticker needed)
710
+ - Uses tool-call flow: `wallet_api` for reads/writes, `request_human_action` for 403s
711
+ - `action:create` permission enables the `request_human_action` tool
712
+ - No `intents` in the response — tool-call mode handles actions directly
713
+ - No response format instructions needed — the engine auto-injects the format spec