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,1063 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * AuraMaxx CLI entry point
4
+ *
5
+ * Routes subcommands to server/cli/commands/<cmd>.ts via tsx.
6
+ * Works with: npx auramaxx <command> [args]
7
+ */
8
+
9
+ const { execFileSync } = require('child_process');
10
+ const fs = require('fs');
11
+ const crypto = require('crypto');
12
+ const os = require('os');
13
+ const path = require('path');
14
+ const readline = require('readline');
15
+
16
+ const root = path.join(__dirname, '..');
17
+ let cmd = process.argv[2];
18
+ const args = process.argv.slice(3);
19
+ let inferredCommand = false;
20
+
21
+ const COMMANDS = {
22
+ init: 'Advanced/compat setup flow (most users should run start)',
23
+ start: 'Canonical startup: includes bootstrap/setup checks + runtime start',
24
+ stop: 'Stop running servers',
25
+ status: 'Show server and wallet status',
26
+ doctor: 'Run deterministic onboarding/runtime diagnostics',
27
+ 'release-check': 'Run release diff/sanity/privacy/security checklist guardrail',
28
+ unlock: 'Unlock the vault interactively',
29
+ lock: 'Lock all vaults or a specific vault',
30
+ restore: 'Restore from a backup (--list, --latest, --dry-run)',
31
+ api: 'Call any wallet API endpoint from CLI (auth + JSON wrapper)',
32
+ auth: 'Request/poll agent auth approvals from CLI',
33
+ diary: 'Append daily diary entries via authenticated CLI path',
34
+ actions: 'Create/list/resolve human actions and manage action tokens',
35
+ apikey: 'List/validate/set/delete API keys',
36
+ app: 'Manage installed apps (install, remove, list, update)',
37
+ mcp: 'Start MCP server (stdio) for Claude Code, Cursor, etc.',
38
+ cron: 'Run the cron server standalone (balance sync, price sync)',
39
+ experimental: 'Toggle dev feature flags (list, enable, disable)',
40
+ skill: 'Install AuraMaxx skills for Claude/Codex/OpenClaw and run install doctor',
41
+ wallet: 'Wallet API wrappers (status, assets, transactions, swap, send, fund, launch)',
42
+ quickhack: 'Generate random tutorial secret, run set+inject, and print copyable commands',
43
+ vault: 'Retrieve/manage credentials (get, set, share via secret gist, delete, list)',
44
+ service: 'Manage background service (install, uninstall, status)',
45
+ secret: 'Run commands with injected secret env vars (inject)',
46
+ token: 'Preview profile-based token policy before issuance',
47
+ env: 'Load env vars from vault via .aura file (run, inject, check, list, init)',
48
+ 'shell-hook': 'Auto-load .aura env vars on cd (like direnv)',
49
+ };
50
+
51
+ const VAULT_ALIASES = {
52
+ get: 'get',
53
+ set: 'set',
54
+ share: 'share',
55
+ del: 'delete',
56
+ delete: 'delete',
57
+ list: 'list',
58
+ health: 'health',
59
+ getsecret: 'get',
60
+ 'get-secret': 'get',
61
+ readsecret: 'get',
62
+ 'read-secret': 'get',
63
+ listsecrets: 'list',
64
+ 'list-secrets': 'list',
65
+ secretlist: 'list',
66
+ 'secret-list': 'list',
67
+ secrethealth: 'health',
68
+ 'secret-health': 'health',
69
+ secret: 'secret',
70
+ inject: 'inject',
71
+ use: 'inject',
72
+ };
73
+
74
+ const SHORTCUT_COMMANDS = [
75
+ { name: 'get <name>', desc: 'Read primary credential value (--json for full payload)' },
76
+ { name: 'set <name> <value>', desc: 'Create or update a secret (default type: api key)' },
77
+ { name: 'list', desc: 'List credential names' },
78
+ { name: 'share <name>', desc: 'Create a GitHub secret gist share for a credential' },
79
+ { name: 'inject <name> [-- <cmd>]', desc: 'Save primary secret to env var (AURA_SECRET default) and optionally run command' },
80
+ { name: 'del <name>', desc: 'Delete a credential' },
81
+ ];
82
+
83
+ const DEFAULT_ADMIN = ['start', 'status', 'init', 'mcp', 'skill', 'auth'];
84
+
85
+ const COMMON_EXAMPLES = [
86
+ { cmd: 'aura status', note: 'Check if services are running' },
87
+ { cmd: 'aura list', note: 'List credential names' },
88
+ { cmd: 'aura diary write --entry "heartbeat ok"', note: 'Append a daily diary entry (auth-aware)' },
89
+ { cmd: 'aura get OURSECRET', note: 'Read a credential' },
90
+ { cmd: 'aura set OURSECRET 123', note: 'Create or update a credential value' },
91
+ { cmd: 'aura set GITHUB_LOGIN hunter2 --type login', note: 'Store as login credential (password field)' },
92
+ { cmd: 'aura share OURSECRET --expires-after 24h', note: 'Create a shareable secret gist link' },
93
+ { cmd: 'aura inject DONTLOOK --env HIDETHIS -- printenv HIDETHIS', note: 'Execute command with injected secret env var' },
94
+ ];
95
+
96
+ let localTsxCliPath;
97
+ let localTsxCliResolved = false;
98
+ const AURA_RC_BLOCK_START = '# >>> Aura CLI managed fallback >>>';
99
+ const AURA_RC_BLOCK_END = '# <<< Aura CLI managed fallback <<<';
100
+
101
+ function escapeForDoubleQuotedShell(value) {
102
+ return value.replace(/(["\\$`])/g, '\\$1');
103
+ }
104
+
105
+ function resolveLocalCliEntrypoint() {
106
+ const entrypoint = path.join(root, 'bin', 'auramaxx.js');
107
+ if (!fs.existsSync(entrypoint)) return null;
108
+ if (isTransientPathEntry(entrypoint)) return null;
109
+ return entrypoint;
110
+ }
111
+
112
+ function resolvePreferredCliInvocation() {
113
+ const localEntrypoint = resolveLocalCliEntrypoint();
114
+ if (!localEntrypoint) {
115
+ return {
116
+ mode: 'npx',
117
+ localEntrypoint: null,
118
+ runCommand: 'npx auramaxx',
119
+ aliasValue: 'npx auramaxx',
120
+ };
121
+ }
122
+
123
+ const escapedEntrypoint = escapeForDoubleQuotedShell(localEntrypoint);
124
+ return {
125
+ mode: 'local',
126
+ localEntrypoint,
127
+ runCommand: `node "${escapedEntrypoint}"`,
128
+ aliasValue: `node "${escapedEntrypoint}"`,
129
+ };
130
+ }
131
+
132
+ function resolvePortableCliInvocation() {
133
+ return {
134
+ mode: 'npx',
135
+ localEntrypoint: null,
136
+ runCommand: 'npx auramaxx',
137
+ aliasValue: 'npx auramaxx',
138
+ };
139
+ }
140
+
141
+ function renderFunctionLine(aliasName, runCommand) {
142
+ return `${aliasName}() { ${runCommand} "$@"; }`;
143
+ }
144
+
145
+ function renderManagedRcFallbackBlock() {
146
+ const portable = resolvePortableCliInvocation();
147
+ return [
148
+ AURA_RC_BLOCK_START,
149
+ '# Ensures aura/auramaxx work across restarts without global install.',
150
+ renderFunctionLine('aura', portable.runCommand),
151
+ renderFunctionLine('auramaxx', portable.runCommand),
152
+ AURA_RC_BLOCK_END,
153
+ ].join('\n');
154
+ }
155
+
156
+ function resolveLocalTsxCliPath() {
157
+ if (localTsxCliResolved) return localTsxCliPath;
158
+ localTsxCliResolved = true;
159
+ try {
160
+ localTsxCliPath = require.resolve('tsx/dist/cli.mjs', { paths: [root] });
161
+ } catch {
162
+ localTsxCliPath = null;
163
+ }
164
+ return localTsxCliPath;
165
+ }
166
+
167
+ function showHelp(showAll = false) {
168
+ // Inline Tyvek theme (bin/ is plain CJS - cannot import TS theme module)
169
+ const isTTY = process.stdout.isTTY && !process.env.NO_COLOR && process.env.CI !== 'true' && process.env.TERM !== 'dumb';
170
+ const RST = isTTY ? '\x1b[0m' : '';
171
+ const BOLD = isTTY ? '\x1b[1m' : '';
172
+ const DIM = isTTY ? '\x1b[2m' : '';
173
+ const CYAN = isTTY ? '\x1b[38;5;154m' : '';
174
+ const GRAY = isTTY ? '\x1b[90m' : '';
175
+
176
+ const W = 62;
177
+ const TL = `${GRAY}.-${RST}`;
178
+ const TR = `${GRAY}-.${RST}`;
179
+ const BL = `${GRAY}'-${RST}`;
180
+ const BR = `${GRAY}-'${RST}`;
181
+ const PIPE = `${GRAY}|${RST}`;
182
+ const SEP = ' ' + '- '.repeat(Math.floor(W / 2));
183
+
184
+ // Banner - three diagonal stripes in a square (aura_logo.svg)
185
+ const LP = `${GRAY}|${RST}`;
186
+ const LT = `${GRAY}.${RST}${DIM}----------${RST}${GRAY}.${RST}`;
187
+ const LB = `${GRAY}'${RST}${DIM}----------${RST}${GRAY}'${RST}`;
188
+
189
+ console.log('');
190
+ console.log(` ${TL}${DIM}${' '.repeat(W - 4)}${RST}${TR}`);
191
+ console.log(` ${PIPE} ${LT}${' '.repeat(W - 19)}${PIPE}`);
192
+ console.log(` ${PIPE} ${LP}${BOLD}\\\\${RST} ${BOLD}\\\\${RST} ${BOLD}\\\\${RST}${LP} ${BOLD}A U R A${RST}${' '.repeat(W - 30)}${PIPE}`);
193
+ console.log(` ${PIPE} ${LP}${BOLD}\\\\${RST} ${BOLD}\\\\${RST} ${BOLD}\\\\${RST}${LP} ${DIM}M A X X . S H${RST}${' '.repeat(W - 36)}${PIPE}`);
194
+ console.log(` ${PIPE} ${LP}${BOLD}\\\\${RST} ${BOLD}\\\\${RST} ${BOLD}\\\\${RST}${LP} ${CYAN}COMMAND REFERENCE${RST}${' '.repeat(W - 40)}${PIPE}`);
195
+ console.log(` ${PIPE} ${LB}${' '.repeat(W - 19)}${PIPE}`);
196
+ console.log(` ${BL}${DIM}${' '.repeat(W - 4)}${RST}${BR}`);
197
+ console.log('');
198
+
199
+ console.log(` ${BOLD}Usage:${RST} aura [command] [options]`);
200
+ console.log(` ${DIM}npx auramaxx [command] [options]${RST}`);
201
+ console.log('');
202
+
203
+ // --- OPTIONS ---
204
+ console.log(SEP);
205
+ console.log(` ${BOLD}[ OPTIONS ]${RST}`);
206
+ console.log('');
207
+ console.log(` ${CYAN}${'--help'.padEnd(16)}${RST}Show this help message`);
208
+ console.log(` ${CYAN}${'--help --all'.padEnd(16)}${RST}Show all commands including advanced admin`);
209
+ console.log(` ${CYAN}${'--json'.padEnd(16)}${RST}Output full command metadata as JSON`);
210
+ console.log(` ${CYAN}${'--env'.padEnd(16)}${RST}Save to env var, used together with aura inject`);
211
+ console.log(` ${CYAN}${'--debug'.padEnd(16)}${RST}Show verbose bootstrap/setup details during start`);
212
+ console.log('');
213
+
214
+ // --- ADMIN (essential or all) ---
215
+ console.log(SEP);
216
+ console.log(` ${BOLD}[ ADMIN ]${RST}`);
217
+ console.log('');
218
+
219
+ if (showAll) {
220
+ for (const [name, desc] of Object.entries(COMMANDS)) {
221
+ console.log(` ${CYAN}${name.padEnd(16)}${RST}${desc}`);
222
+ }
223
+ } else {
224
+ for (const name of DEFAULT_ADMIN) {
225
+ if (COMMANDS[name]) {
226
+ console.log(` ${CYAN}${name.padEnd(16)}${RST}${COMMANDS[name]}`);
227
+ }
228
+ }
229
+ console.log('');
230
+ console.log(` ${DIM}Run aura --help --all to see all commands${RST}`);
231
+ }
232
+ console.log('');
233
+
234
+ // --- COMMANDS (aliases) ---
235
+ console.log(SEP);
236
+ console.log(` ${BOLD}[ COMMANDS ]${RST}`);
237
+ console.log('');
238
+ const shortcutWidth = Math.max(...SHORTCUT_COMMANDS.map((shortcut) => shortcut.name.length)) + 2;
239
+ for (const shortcut of SHORTCUT_COMMANDS) {
240
+ console.log(` ${CYAN}${shortcut.name.padEnd(shortcutWidth)}${RST}${shortcut.desc}`);
241
+ }
242
+ console.log('');
243
+
244
+ // --- EXAMPLES ---
245
+ console.log(SEP);
246
+ console.log(` ${BOLD}[ EXAMPLES ]${RST}`);
247
+ console.log('');
248
+ const exampleWidth = Math.max(...COMMON_EXAMPLES.map((example) => example.cmd.length)) + 2;
249
+ for (const example of COMMON_EXAMPLES) {
250
+ console.log(` ${example.cmd.padEnd(exampleWidth)}${DIM}# ${example.note}${RST}`);
251
+ }
252
+ console.log('');
253
+ }
254
+
255
+ function getHelpMetadata() {
256
+ return {
257
+ cli: 'auramaxx',
258
+ usage: [
259
+ 'npx auramaxx [command] [options]',
260
+ 'aura [command] [options] (alias)',
261
+ ],
262
+ options: [
263
+ { flag: '--help', aliases: ['-h'], description: 'Show this help message' },
264
+ { flag: '--json', description: 'Output full command metadata as JSON' },
265
+ { flag: '--env', description: 'Save to env var, used together with npx auramaxx inject' },
266
+ ],
267
+ commands: Object.entries(COMMANDS).map(([name, description]) => ({
268
+ name,
269
+ description,
270
+ entrypoint: `server/cli/commands/${name}.ts`,
271
+ })),
272
+ commandShortcuts: SHORTCUT_COMMANDS.map((entry) => ({ ...entry })),
273
+ vaultAliases: Object.entries(VAULT_ALIASES).map(([alias, subcommand]) => ({
274
+ alias,
275
+ command: 'vault',
276
+ subcommand,
277
+ })),
278
+ examples: COMMON_EXAMPLES.map((entry) => ({ ...entry })),
279
+ };
280
+ }
281
+
282
+ function showHelpJson() {
283
+ console.log(JSON.stringify(getHelpMetadata(), null, 2));
284
+ }
285
+
286
+ function resolveDefaultCommand() {
287
+ // Canonical golden path: always start.
288
+ // `start` now owns first-run bootstrap/setup checks and returning-run startup.
289
+ return 'start';
290
+ }
291
+
292
+ function getDataDirState(dataDir) {
293
+ try {
294
+ if (!fs.existsSync(dataDir)) {
295
+ return {
296
+ dataDir,
297
+ exists: false,
298
+ files: [],
299
+ hasDb: false,
300
+ hasVaultFiles: false,
301
+ brokenState: false,
302
+ };
303
+ }
304
+
305
+ const files = fs.readdirSync(dataDir);
306
+ const hasDb = files.includes('auramaxx.db');
307
+ const hasVaultFiles = files.some((file) =>
308
+ file === 'vault-primary.json' || file === 'cold.json' || /^vault-.*\.json$/i.test(file)
309
+ );
310
+
311
+ return {
312
+ dataDir,
313
+ exists: true,
314
+ files,
315
+ hasDb,
316
+ hasVaultFiles,
317
+ brokenState: hasDb && !hasVaultFiles,
318
+ };
319
+ } catch {
320
+ return {
321
+ dataDir,
322
+ exists: false,
323
+ files: [],
324
+ hasDb: false,
325
+ hasVaultFiles: false,
326
+ brokenState: false,
327
+ };
328
+ }
329
+ }
330
+
331
+ function wipeDataDirContents(dataDir) {
332
+ if (!fs.existsSync(dataDir)) return;
333
+ for (const entry of fs.readdirSync(dataDir)) {
334
+ fs.rmSync(path.join(dataDir, entry), { recursive: true, force: true });
335
+ }
336
+ }
337
+
338
+ function canPromptForInput() {
339
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY && process.env.CI !== 'true');
340
+ }
341
+
342
+ function promptLine(question) {
343
+ return new Promise((resolve) => {
344
+ const rl = readline.createInterface({
345
+ input: process.stdin,
346
+ output: process.stdout,
347
+ });
348
+ rl.question(question, (answer) => {
349
+ rl.close();
350
+ resolve(answer);
351
+ });
352
+ });
353
+ }
354
+
355
+ async function maybeHandleBrokenLocalState() {
356
+ const dataDir = process.env.WALLET_DATA_DIR || path.join(os.homedir(), '.auramaxx');
357
+ const state = getDataDirState(dataDir);
358
+ if (!state.brokenState) return null;
359
+
360
+ console.log('');
361
+ console.log('⚠️ Detected partial local state: database exists but vault files are missing.');
362
+ console.log(` Data directory: ${state.dataDir}`);
363
+ console.log(" This can happen after deleting vault files but keeping auramaxx.db.");
364
+ console.log(' Setup cannot decrypt old encrypted records without the old vault.');
365
+ console.log('');
366
+
367
+ if (!canPromptForInput()) {
368
+ console.log(" Non-interactive shell: keeping files and continuing with 'start'.");
369
+ console.log(' WARNING: old encrypted data cannot be decrypted without the old vault files.');
370
+ return 'start';
371
+ }
372
+
373
+ console.log(' DANGER: Wipe removes local Aura data in this directory (DB, credentials, logs, config).');
374
+ const answer = String(await promptLine(" Type 'y' to wipe everything and continue with setup, or 'n' to keep files and start: "))
375
+ .trim()
376
+ .toLowerCase();
377
+
378
+ if (answer === 'y') {
379
+ wipeDataDirContents(state.dataDir);
380
+ console.log(' Local Aura data wiped.');
381
+ return 'init';
382
+ }
383
+
384
+ console.log(" Keeping existing files and continuing with 'start'.");
385
+ console.log(' WARNING: old encrypted data cannot be decrypted without the old vault files.');
386
+ return 'start';
387
+ }
388
+
389
+ function parseSemverParts(version) {
390
+ const cleaned = String(version || '').trim().replace(/^v/i, '');
391
+ const [core, pre = ''] = cleaned.split('-', 2);
392
+ const coreParts = core.split('.').map((v) => parseInt(v, 10) || 0);
393
+ const preParts = pre ? pre.split('.').map((v) => (/^\d+$/.test(v) ? Number(v) : v)) : [];
394
+ return { coreParts, preParts };
395
+ }
396
+
397
+ function compareVersions(a, b) {
398
+ const av = parseSemverParts(a);
399
+ const bv = parseSemverParts(b);
400
+ for (let i = 0; i < 3; i++) {
401
+ const diff = (av.coreParts[i] || 0) - (bv.coreParts[i] || 0);
402
+ if (diff !== 0) return diff;
403
+ }
404
+ if (av.preParts.length === 0 && bv.preParts.length > 0) return 1;
405
+ if (av.preParts.length > 0 && bv.preParts.length === 0) return -1;
406
+ const len = Math.max(av.preParts.length, bv.preParts.length);
407
+ for (let i = 0; i < len; i++) {
408
+ const left = av.preParts[i];
409
+ const right = bv.preParts[i];
410
+ if (left === undefined) return -1;
411
+ if (right === undefined) return 1;
412
+ if (left === right) continue;
413
+ if (typeof left === 'number' && typeof right === 'number') return left - right;
414
+ return String(left).localeCompare(String(right));
415
+ }
416
+ return 0;
417
+ }
418
+
419
+ function getUpdateCachePath() {
420
+ const dataDir = process.env.WALLET_DATA_DIR || path.join(os.homedir(), '.auramaxx');
421
+ const key = crypto.createHash('sha1').update(root).digest('hex').slice(0, 8);
422
+ return path.join(dataDir, `update-check-${key}.json`);
423
+ }
424
+
425
+ function maybePrintUpdateNotice() {
426
+ if (process.env.AURA_NO_UPDATE_CHECK === '1' || process.env.CI === 'true') return;
427
+
428
+ const now = Date.now();
429
+ const throttleMs = Number(process.env.AURA_UPDATE_CHECK_CACHE_MINUTES || '360') * 60 * 1000;
430
+ const cachePath = getUpdateCachePath();
431
+
432
+ let cache = null;
433
+ try {
434
+ cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
435
+ } catch {}
436
+
437
+ if (!process.env.AURA_UPDATE_CHECK_FORCE && cache && typeof cache.checkedAt === 'number' && now - cache.checkedAt < throttleMs) {
438
+ if (cache.latest && compareVersions(cache.latest, cache.current || '') > 0) {
439
+ console.log(`\n⚠️ Update available: aura${cache.current} → aura${cache.latest}`);
440
+ console.log(' Run: npm i -g auramaxx (or use latest npx cache)\n');
441
+ }
442
+ return;
443
+ }
444
+
445
+ let latest = process.env.AURA_UPDATE_CHECK_MOCK_LATEST || null;
446
+ const current = `v${require(path.join(root, 'package.json')).version}`;
447
+
448
+ if (!latest) {
449
+ try {
450
+ const out = execFileSync('npm', ['view', 'auramaxx', 'version', '--json'], {
451
+ cwd: root,
452
+ stdio: ['ignore', 'pipe', 'ignore'],
453
+ timeout: Number(process.env.AURA_UPDATE_CHECK_TIMEOUT_MS || '1200'),
454
+ }).toString('utf8').trim();
455
+ latest = JSON.parse(out);
456
+ } catch {
457
+ return;
458
+ }
459
+ }
460
+
461
+ try {
462
+ fs.mkdirSync(path.dirname(cachePath), { recursive: true });
463
+ fs.writeFileSync(cachePath, JSON.stringify({ checkedAt: now, current, latest }, null, 2));
464
+ } catch {}
465
+
466
+ if (latest && compareVersions(latest, current) > 0) {
467
+ console.log(`\n⚠️ Update available: aura${current} → aura${latest}`);
468
+ console.log(' Run: npm i -g auramaxx (or use latest npx cache)\n');
469
+ }
470
+ }
471
+
472
+ function buildRunner(commandName, commandArgs = []) {
473
+ const commandFile = path.join(root, 'server', 'cli', 'commands', `${commandName}.ts`);
474
+ const useNodeTsxLoader = process.env.SANDBOX_MODE === 'true' || process.env.AURA_FORCE_NODE_TSX === '1' || process.env.CODEX_SANDBOX;
475
+ if (useNodeTsxLoader) {
476
+ return { command: process.execPath, args: ['--import', 'tsx', commandFile, ...commandArgs] };
477
+ }
478
+
479
+ const forceNpxTsx = process.env.AURA_FORCE_NPX_TSX === '1';
480
+ if (!forceNpxTsx) {
481
+ const tsxCliPath = resolveLocalTsxCliPath();
482
+ if (tsxCliPath) {
483
+ return { command: process.execPath, args: [tsxCliPath, commandFile, ...commandArgs] };
484
+ }
485
+ }
486
+
487
+ return { command: 'npx', args: ['tsx', commandFile, ...commandArgs] };
488
+ }
489
+
490
+ function runCommand(commandName, commandArgs = [], allowFailure = false, quiet = false) {
491
+ const runner = buildRunner(commandName, commandArgs);
492
+ try {
493
+ execFileSync(runner.command, runner.args, {
494
+ cwd: root,
495
+ stdio: quiet ? 'ignore' : 'inherit',
496
+ env: process.env,
497
+ });
498
+ return true;
499
+ } catch (error) {
500
+ if (allowFailure) return false;
501
+ process.exit(error.status || 1);
502
+ }
503
+ }
504
+
505
+ function isCliAgentEnvironment() {
506
+ return Boolean(
507
+ process.env.CODEX_CI ||
508
+ process.env.CODEX_SANDBOX ||
509
+ process.env.CLAUDE_CODE ||
510
+ process.env.CLAUDECODE ||
511
+ process.env.AURA_CLI_AGENT
512
+ );
513
+ }
514
+
515
+ function shouldRunOnboardingAutoconfig() {
516
+ const inferredInitOrStart = inferredCommand && (cmd === 'init' || cmd === 'start');
517
+ const explicitInitOrStart = !inferredCommand && (cmd === 'init' || cmd === 'start');
518
+ return inferredInitOrStart || explicitInitOrStart;
519
+ }
520
+
521
+ function shouldLogBootstrapDetails() {
522
+ if (process.env.AURA_BOOTSTRAP_VERBOSE === '1') return true;
523
+ return args.includes('--debug');
524
+ }
525
+
526
+ function logProgress(message) {
527
+ if (!shouldRunOnboardingAutoconfig()) return;
528
+ if (shouldLogBootstrapDetails()) return; // verbose mode prints its own details
529
+ console.log(message);
530
+ }
531
+
532
+ function getPathEntries() {
533
+ return (process.env.PATH || '')
534
+ .split(path.delimiter)
535
+ .map((entry) => entry.trim())
536
+ .filter(Boolean);
537
+ }
538
+
539
+ function isTransientPathEntry(entry) {
540
+ const normalized = entry.replace(/\\/g, '/').toLowerCase();
541
+ if (normalized.includes('/.npm/_npx/')) return true;
542
+ if (normalized.includes('/_npx/')) return true;
543
+ if (normalized.includes('/.codex/tmp/')) return true;
544
+ if (normalized.includes('/node_modules/.bin')) return true;
545
+ if (normalized.includes('/pnpm/dlx')) return true;
546
+ return false;
547
+ }
548
+
549
+ function getStablePathEntries() {
550
+ return getPathEntries().filter((entry) => !isTransientPathEntry(entry));
551
+ }
552
+
553
+ function isExecutable(filePath) {
554
+ try {
555
+ fs.accessSync(filePath, fs.constants.X_OK);
556
+ return true;
557
+ } catch {
558
+ return false;
559
+ }
560
+ }
561
+
562
+ function findCommandInPath(commandName) {
563
+ const pathEntries = getStablePathEntries();
564
+ const extCandidates = process.platform === 'win32'
565
+ ? (process.env.PATHEXT || '.COM;.EXE;.BAT;.CMD')
566
+ .split(';')
567
+ .map((ext) => ext.trim())
568
+ .filter(Boolean)
569
+ : [''];
570
+
571
+ for (const dir of pathEntries) {
572
+ for (const ext of extCandidates) {
573
+ const candidate = process.platform === 'win32'
574
+ ? path.join(dir, `${commandName}${ext}`)
575
+ : path.join(dir, commandName);
576
+
577
+ if (fs.existsSync(candidate) && isExecutable(candidate)) {
578
+ return candidate;
579
+ }
580
+ }
581
+ }
582
+
583
+ return null;
584
+ }
585
+
586
+ function canWriteExecutableInDir(dirPath) {
587
+ try {
588
+ fs.accessSync(dirPath, fs.constants.W_OK | fs.constants.X_OK);
589
+ return true;
590
+ } catch {
591
+ return false;
592
+ }
593
+ }
594
+
595
+ function orderedPathEntriesForAuraShim() {
596
+ const seen = new Set();
597
+ const unique = [];
598
+ for (const entry of getStablePathEntries()) {
599
+ if (!seen.has(entry)) {
600
+ seen.add(entry);
601
+ unique.push(entry);
602
+ }
603
+ }
604
+
605
+ const homeDir = os.homedir();
606
+ const localPreferred = [
607
+ path.join(homeDir, '.local', 'bin'),
608
+ path.join(homeDir, 'bin'),
609
+ ];
610
+
611
+ const preferred = [];
612
+ const rest = [];
613
+
614
+ for (const entry of unique) {
615
+ if (localPreferred.includes(entry) || entry.startsWith(`${homeDir}${path.sep}`)) {
616
+ preferred.push(entry);
617
+ } else {
618
+ rest.push(entry);
619
+ }
620
+ }
621
+
622
+ return [...preferred, ...rest];
623
+ }
624
+
625
+ function installCommandShim(commandName) {
626
+ const shimName = process.platform === 'win32' ? `${commandName}.cmd` : commandName;
627
+ const preferredCli = resolvePreferredCliInvocation();
628
+ const shimBody = process.platform === 'win32'
629
+ ? preferredCli.mode === 'local'
630
+ ? `@echo off\r\nnode "${preferredCli.localEntrypoint.replace(/"/g, '""')}" %*\r\n`
631
+ : '@echo off\r\nnpx auramaxx %*\r\n'
632
+ : `#!/usr/bin/env sh\n# Aura CLI shim for ${commandName} (auto-installed by auramaxx)\nexec ${preferredCli.runCommand} "$@"\n`;
633
+
634
+ for (const dir of orderedPathEntriesForAuraShim()) {
635
+ if (!fs.existsSync(dir) || !canWriteExecutableInDir(dir)) {
636
+ continue;
637
+ }
638
+
639
+ const shimPath = path.join(dir, shimName);
640
+ if (fs.existsSync(shimPath)) {
641
+ try {
642
+ const existing = fs.readFileSync(shimPath, 'utf8');
643
+ const ours = existing.includes('Aura CLI shim (auto-installed by auramaxx)') || existing.includes('npx auramaxx') || existing.includes('bin/auramaxx.js');
644
+ if (!ours) {
645
+ continue;
646
+ }
647
+ } catch {
648
+ continue;
649
+ }
650
+ }
651
+
652
+ try {
653
+ fs.writeFileSync(shimPath, shimBody, { mode: 0o755 });
654
+ if (process.platform !== 'win32') {
655
+ fs.chmodSync(shimPath, 0o755);
656
+ }
657
+ return shimPath;
658
+ } catch {
659
+ // Keep searching PATH candidates.
660
+ }
661
+ }
662
+
663
+ return null;
664
+ }
665
+
666
+ function resolveShellAliasTarget() {
667
+ const shell = path.basename(process.env.SHELL || '');
668
+ switch (shell) {
669
+ case 'zsh':
670
+ return path.join(os.homedir(), '.zshrc');
671
+ case 'bash':
672
+ return path.join(os.homedir(), '.bashrc');
673
+ default:
674
+ return null;
675
+ }
676
+ }
677
+
678
+ function stripAuraLegacyAliasLines(content) {
679
+ const lines = content.split(/\r?\n/);
680
+ const kept = [];
681
+ let removed = false;
682
+
683
+ for (const line of lines) {
684
+ const isAuraNpxAlias = /^\s*alias\s+aura=.+\bnpx\s+auramaxx\b.*$/.test(line);
685
+ const isAuramaxxNpxAlias = /^\s*alias\s+auramaxx=.+\bnpx\s+auramaxx\b.*$/.test(line);
686
+ const isAuraAliasComment = /^\s*#\s*Aura CLI shorthand\s*$/.test(line);
687
+ if (isAuraNpxAlias || isAuramaxxNpxAlias || isAuraAliasComment) {
688
+ removed = true;
689
+ continue;
690
+ }
691
+ kept.push(line);
692
+ }
693
+
694
+ return {
695
+ content: kept.join('\n').replace(/\n+$/, ''),
696
+ removed,
697
+ };
698
+ }
699
+
700
+ function removeManagedRcFallbackBlock(content) {
701
+ const start = content.indexOf(AURA_RC_BLOCK_START);
702
+ const end = content.indexOf(AURA_RC_BLOCK_END);
703
+ if (start === -1 || end === -1 || end < start) {
704
+ return { content, removed: false };
705
+ }
706
+
707
+ const endWithMarker = end + AURA_RC_BLOCK_END.length;
708
+ const nextChar = content[endWithMarker] === '\n' ? endWithMarker + 1 : endWithMarker;
709
+ const stripped = `${content.slice(0, start)}${content.slice(nextChar)}`;
710
+ return {
711
+ content: stripped.replace(/\n{3,}/g, '\n\n').replace(/\n+$/, ''),
712
+ removed: true,
713
+ };
714
+ }
715
+
716
+ function installManagedRcFallback() {
717
+ const rcFile = resolveShellAliasTarget();
718
+ if (!rcFile) return { state: 'unsupported-shell' };
719
+ const managedBlock = renderManagedRcFallbackBlock();
720
+
721
+ let content = '';
722
+ try {
723
+ if (fs.existsSync(rcFile)) {
724
+ content = fs.readFileSync(rcFile, 'utf-8');
725
+ }
726
+ } catch {
727
+ return { state: 'read-failed', rcFile };
728
+ }
729
+
730
+ const legacyCleanup = stripAuraLegacyAliasLines(content);
731
+ const withoutLegacy = legacyCleanup.content;
732
+ const start = withoutLegacy.indexOf(AURA_RC_BLOCK_START);
733
+ const end = withoutLegacy.indexOf(AURA_RC_BLOCK_END);
734
+
735
+ let nextContent = withoutLegacy;
736
+ let wroteManagedBlock = false;
737
+ if (start !== -1 && end !== -1 && end > start) {
738
+ const endWithMarker = end + AURA_RC_BLOCK_END.length;
739
+ const nextChar = withoutLegacy[endWithMarker] === '\n' ? endWithMarker + 1 : endWithMarker;
740
+ nextContent = `${withoutLegacy.slice(0, start)}${managedBlock}${withoutLegacy.slice(nextChar)}`;
741
+ wroteManagedBlock = true;
742
+ } else {
743
+ nextContent = `${withoutLegacy}${withoutLegacy.trim() ? '\n\n' : ''}${managedBlock}`;
744
+ wroteManagedBlock = true;
745
+ }
746
+
747
+ nextContent = `${nextContent.replace(/\n+$/, '')}\n`;
748
+ const originalNormalized = `${content.replace(/\r\n/g, '\n').replace(/\n+$/, '')}\n`;
749
+ if (nextContent === originalNormalized) {
750
+ return { state: 'already-present', rcFile };
751
+ }
752
+
753
+ try {
754
+ fs.writeFileSync(rcFile, nextContent);
755
+ if (wroteManagedBlock && legacyCleanup.removed) {
756
+ return { state: 'installed-and-migrated', rcFile };
757
+ }
758
+ return { state: 'installed', rcFile };
759
+ } catch {
760
+ return { state: 'write-failed', rcFile };
761
+ }
762
+ }
763
+
764
+ function cleanupRcFallbacksInRc() {
765
+ const rcFile = resolveShellAliasTarget();
766
+ if (!rcFile) return { state: 'unsupported-shell' };
767
+
768
+ let content = '';
769
+ try {
770
+ if (fs.existsSync(rcFile)) {
771
+ content = fs.readFileSync(rcFile, 'utf-8');
772
+ } else {
773
+ return { state: 'not-found', rcFile };
774
+ }
775
+ } catch {
776
+ return { state: 'read-failed', rcFile };
777
+ }
778
+
779
+ const strippedLegacy = stripAuraLegacyAliasLines(content);
780
+ const strippedBlock = removeManagedRcFallbackBlock(strippedLegacy.content);
781
+ const removed = strippedLegacy.removed || strippedBlock.removed;
782
+
783
+ if (!removed) return { state: 'not-found', rcFile };
784
+
785
+ const nextContent = `${strippedBlock.content.replace(/\n+$/, '')}\n`;
786
+ try {
787
+ fs.writeFileSync(rcFile, nextContent);
788
+ return { state: 'removed', rcFile };
789
+ } catch {
790
+ return { state: 'write-failed', rcFile };
791
+ }
792
+ }
793
+
794
+ function maybeAutoInstallAuraAlias() {
795
+ if (!shouldRunOnboardingAutoconfig()) return;
796
+
797
+ const forceAutoInstall = process.env.AURA_AUTO_ALIAS_INSTALL_FORCE === '1';
798
+ const verbose = shouldLogBootstrapDetails();
799
+ const preferredCli = resolvePreferredCliInvocation();
800
+ const portableCli = resolvePortableCliInvocation();
801
+ const auraAliasLine = renderFunctionLine('aura', portableCli.runCommand);
802
+ const auramaxxAliasLine = renderFunctionLine('auramaxx', portableCli.runCommand);
803
+ const isInteractiveShell = process.stdout.isTTY && process.env.CI !== 'true';
804
+ if (isCliAgentEnvironment() && !forceAutoInstall && !isInteractiveShell) return;
805
+
806
+ if (process.env.AURA_AUTO_ALIAS_INSTALL === '0') {
807
+ if (verbose) {
808
+ console.log('Aura command auto-setup skipped (AURA_AUTO_ALIAS_INSTALL=0).');
809
+ console.log(`Use \`${preferredCli.runCommand}\` directly or add shell fallback functions:`);
810
+ console.log(` ${auraAliasLine}`);
811
+ console.log(` ${auramaxxAliasLine}\n`);
812
+ }
813
+ return;
814
+ }
815
+
816
+ const auraPathBefore = findCommandInPath('aura');
817
+ const auramaxxPathBefore = findCommandInPath('auramaxx');
818
+ let auraPath = auraPathBefore;
819
+ let auramaxxPath = auramaxxPathBefore;
820
+ let auraShimInstalledPath = null;
821
+ let auramaxxShimInstalledPath = null;
822
+
823
+ if (!auraPath) {
824
+ auraShimInstalledPath = installCommandShim('aura');
825
+ auraPath = findCommandInPath('aura');
826
+ }
827
+
828
+ if (!auramaxxPath) {
829
+ auramaxxShimInstalledPath = installCommandShim('auramaxx');
830
+ auramaxxPath = findCommandInPath('auramaxx');
831
+ }
832
+
833
+ const interactiveShell = forceAutoInstall || isInteractiveShell;
834
+
835
+ if (auraShimInstalledPath || auramaxxShimInstalledPath) {
836
+ logProgress('CLI… ✓');
837
+ }
838
+
839
+ if (verbose && auraShimInstalledPath) {
840
+ console.log(`Installed Aura command shim: ${auraShimInstalledPath}`);
841
+ }
842
+
843
+ if (verbose && auramaxxShimInstalledPath) {
844
+ console.log(`Installed AuraMaxx command shim: ${auramaxxShimInstalledPath}`);
845
+ }
846
+
847
+ const hadCommandsBefore = Boolean(auraPathBefore && auramaxxPathBefore);
848
+ const hasCommandsNow = Boolean(auraPath && auramaxxPath);
849
+ if (auraPath && auramaxxPath) {
850
+ const cleanupResult = interactiveShell ? cleanupRcFallbacksInRc() : { state: 'not-interactive' };
851
+ if (verbose && cleanupResult.state === 'removed') {
852
+ console.log(`Removed shell fallback aliases/functions from ${cleanupResult.rcFile}.`);
853
+ } else if (verbose && cleanupResult.state === 'write-failed') {
854
+ console.log(`Failed to clean shell fallback aliases/functions in ${cleanupResult.rcFile}.`);
855
+ }
856
+ if (verbose && hadCommandsBefore) {
857
+ console.log('Aura commands already available on PATH; skipped shell fallback install.');
858
+ }
859
+ return;
860
+ }
861
+
862
+ const aliasResult = interactiveShell ? installManagedRcFallback() : { state: 'not-interactive' };
863
+
864
+ if (verbose && (aliasResult.state === 'installed' || aliasResult.state === 'installed-and-migrated')) {
865
+ if (aliasResult.state === 'installed-and-migrated') {
866
+ console.log(`Updated ${aliasResult.rcFile} with managed Aura fallback block and cleaned legacy aliases.`);
867
+ } else {
868
+ console.log(`Installed managed Aura fallback block in ${aliasResult.rcFile}.`);
869
+ }
870
+ console.log(`Run 'source ${aliasResult.rcFile}' or open a new shell to activate it.`);
871
+ } else if (verbose && aliasResult.state === 'already-present') {
872
+ console.log(`Aura shell fallback block already configured in ${aliasResult.rcFile}.`);
873
+ } else if (verbose && aliasResult.state === 'unsupported-shell') {
874
+ console.log('Aura shell fallback auto-install skipped (unsupported shell).');
875
+ } else if (aliasResult.state === 'write-failed' || aliasResult.state === 'read-failed') {
876
+ console.log(`Aura shell fallback auto-install failed for ${aliasResult.rcFile}.`);
877
+ } else if (verbose && aliasResult.state === 'not-interactive') {
878
+ console.log('Aura shell fallback auto-install skipped (non-interactive shell).');
879
+ }
880
+
881
+ if (verbose) {
882
+ console.log('To use Aura immediately in this shell, run:');
883
+ console.log(` ${auraAliasLine}`);
884
+ console.log(` ${auramaxxAliasLine}`);
885
+ console.log(`If PATH install is blocked, use \`${portableCli.runCommand}\` directly.\n`);
886
+ }
887
+ }
888
+
889
+ function maybeAutoInstallSkills() {
890
+ if (process.env.AURA_AUTO_SKILL_INSTALL === '0') return;
891
+
892
+ const inferredInitOrStart = inferredCommand && (cmd === 'init' || cmd === 'start');
893
+ const explicitStart = !inferredCommand && cmd === 'start';
894
+ if (!inferredInitOrStart && !explicitStart) return;
895
+
896
+ // Delegate to skill.ts — single source of truth for install + heartbeat patching
897
+ const verbose = shouldLogBootstrapDetails();
898
+ const ok = runCommand('skill', ['--all', '--yes'], true, !verbose);
899
+ if (!ok && !verbose) {
900
+ logProgress('Skills… ✗');
901
+ } else if (!verbose) {
902
+ logProgress('Skills… ✓');
903
+ }
904
+ }
905
+
906
+ function maybeAutoInstallService() {
907
+ if (process.env.AURA_AUTO_SERVICE_INSTALL === '0') return;
908
+ if (process.platform !== 'darwin' && process.platform !== 'linux') return;
909
+
910
+ const inferredInitOrStart = inferredCommand && (cmd === 'init' || cmd === 'start');
911
+ const explicitStart = !inferredCommand && cmd === 'start';
912
+ if (!inferredInitOrStart && !explicitStart) return;
913
+
914
+ // Check if plist/unit already exists — skip if so
915
+ const plistPath = path.join(os.homedir(), 'Library', 'LaunchAgents', 'com.auramaxx.server.plist');
916
+ const systemdPath = path.join(os.homedir(), '.config', 'systemd', 'user', 'auramaxx.service');
917
+ const serviceFilePath = process.platform === 'darwin' ? plistPath : systemdPath;
918
+ if (fs.existsSync(serviceFilePath)) return;
919
+
920
+ // If no vault yet (first-run init), write the plist but don't load it.
921
+ // RunAtLoad:true means launchd will pick it up on next login, by which
922
+ // time the vault will exist. If vault exists, activate immediately.
923
+ const dataDir = process.env.WALLET_DATA_DIR || path.join(os.homedir(), '.auramaxx');
924
+ const state = getDataDirState(dataDir);
925
+ const installArgs = state.hasVaultFiles ? ['install'] : ['install', '--no-activate'];
926
+
927
+ const verbose = shouldLogBootstrapDetails();
928
+ const ok = runCommand('service', installArgs, true, !verbose);
929
+ if (ok) {
930
+ logProgress('Service… ✓');
931
+ } else if (verbose) {
932
+ console.log('Service auto-install skipped or failed.');
933
+ }
934
+ }
935
+
936
+ function maybeInitFeatureFlags() {
937
+ if (!shouldRunOnboardingAutoconfig()) return;
938
+ const flagsPath = path.join(root, '.aura', 'features.json');
939
+ if (fs.existsSync(flagsPath)) return;
940
+ try {
941
+ fs.mkdirSync(path.join(root, '.aura'), { recursive: true });
942
+ fs.writeFileSync(flagsPath, JSON.stringify({ DEMO_FEATURE: false }, null, 2) + '\n');
943
+ } catch {}
944
+ }
945
+
946
+ function maybeAutoInstallMcp() {
947
+ if (process.env.AURA_AUTO_MCP_INSTALL === '0') return;
948
+ const verbose = shouldLogBootstrapDetails();
949
+
950
+ // CLI agents should use direct CLI/socket and not auto-install MCP into CLI clients.
951
+ // Desktop users can still force auto-install with AURA_AUTO_MCP_INSTALL_FORCE=1.
952
+ const forceAutoInstall = process.env.AURA_AUTO_MCP_INSTALL_FORCE === '1';
953
+ const isCliAgent = Boolean(
954
+ process.env.CODEX_CI ||
955
+ process.env.CODEX_SANDBOX ||
956
+ process.env.CLAUDE_CODE ||
957
+ process.env.CLAUDECODE ||
958
+ process.env.AURA_CLI_AGENT
959
+ );
960
+ if (isCliAgent && !forceAutoInstall) return;
961
+
962
+ // Keep one-command onboarding for bare `npx auramaxx` (init/start),
963
+ // and make explicit `start` behave the same way.
964
+ const inferredInitOrStart = inferredCommand && (cmd === 'init' || cmd === 'start');
965
+ const explicitStart = !inferredCommand && cmd === 'start';
966
+ if (!inferredInitOrStart && !explicitStart) return;
967
+
968
+ if (verbose) {
969
+ console.log('Auto-configuring MCP integrations (best effort)...');
970
+ }
971
+ const ok = runCommand('mcp', ['--install'], true, !verbose);
972
+ if (ok) {
973
+ logProgress('MCP… ✓');
974
+ } else {
975
+ console.log('MCP auto-config skipped. Run `npx auramaxx mcp --install` manually.');
976
+ }
977
+ }
978
+
979
+ async function main() {
980
+ if (!cmd) {
981
+ inferredCommand = true;
982
+ cmd = resolveDefaultCommand();
983
+ if (cmd === 'start') {
984
+ const repaired = await maybeHandleBrokenLocalState();
985
+ if (repaired) cmd = repaired;
986
+ }
987
+ if (cmd !== 'start') {
988
+ console.log(`No command provided; running '${cmd}'.`);
989
+ }
990
+ }
991
+
992
+ const inferredStartFlags = new Set(['--debug', '--headless', '--background', '--daemon', '-d']);
993
+ if (cmd && inferredStartFlags.has(cmd)) {
994
+ const defaultCommand = resolveDefaultCommand();
995
+ if (defaultCommand === 'start') {
996
+ inferredCommand = true;
997
+ args.unshift(cmd);
998
+ cmd = 'start';
999
+ }
1000
+ }
1001
+
1002
+ if (
1003
+ cmd === '--json'
1004
+ || ((cmd === '--help' || cmd === '-h' || cmd === 'help') && args.includes('--json'))
1005
+ ) {
1006
+ showHelpJson();
1007
+ process.exit(0);
1008
+ }
1009
+
1010
+ if (cmd === '--help' || cmd === '-h' || cmd === 'help') {
1011
+ const showAll = args.includes('--all');
1012
+ showHelp(showAll);
1013
+ process.exit(0);
1014
+ }
1015
+
1016
+ if (cmd && VAULT_ALIASES[cmd]) {
1017
+ args.unshift(VAULT_ALIASES[cmd]);
1018
+ cmd = 'vault';
1019
+ }
1020
+
1021
+ if (!COMMANDS[cmd]) {
1022
+ console.error(`Unknown command: ${cmd}\n`);
1023
+ console.error(`Run 'aura --help' or 'npx auramaxx --help' to see available commands.`);
1024
+ process.exit(1);
1025
+ }
1026
+
1027
+ // Start is canonical: if no wallet exists yet, transparently route through init/setup.
1028
+ if (cmd === 'start') {
1029
+ const dataDir = process.env.WALLET_DATA_DIR || path.join(os.homedir(), '.auramaxx');
1030
+ const state = getDataDirState(dataDir);
1031
+ if (!state.hasVaultFiles) {
1032
+ cmd = 'init';
1033
+ if (!inferredCommand) {
1034
+ console.log("No local vault detected; running 'start' bootstrap via 'init' to complete first-run setup.");
1035
+ }
1036
+ }
1037
+ }
1038
+
1039
+ maybePrintUpdateNotice();
1040
+ maybeAutoInstallAuraAlias();
1041
+ maybeAutoInstallSkills();
1042
+ maybeAutoInstallMcp();
1043
+ maybeAutoInstallService();
1044
+ maybeInitFeatureFlags();
1045
+
1046
+ const runner = buildRunner(cmd, args);
1047
+
1048
+ try {
1049
+ execFileSync(runner.command, runner.args, {
1050
+ cwd: root,
1051
+ stdio: 'inherit',
1052
+ env: process.env,
1053
+ });
1054
+ } catch (error) {
1055
+ // tsx already printed the error, just exit with its code
1056
+ process.exit(error.status || 1);
1057
+ }
1058
+ }
1059
+
1060
+ main().catch((error) => {
1061
+ console.error(error?.message || String(error));
1062
+ process.exit(1);
1063
+ });