insforge 0.3.3 → 1.2.10

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 (507) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.cursor/rules/cursor-rules.mdc +94 -0
  3. package/.dockerignore +3 -0
  4. package/.env.example +33 -4
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +13 -60
  6. package/.github/ISSUE_TEMPLATE/config.yml +2 -2
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +10 -63
  8. package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
  9. package/.github/workflows/build-image.yml +2 -1
  10. package/.github/workflows/e2e.yml +63 -0
  11. package/CHANGELOG.md +41 -0
  12. package/CLAUDE_PLUGIN.md +104 -0
  13. package/CODE_OF_CONDUCT.md +128 -0
  14. package/CONTRIBUTING.md +1 -1
  15. package/Dockerfile +4 -1
  16. package/README.md +66 -18
  17. package/assets/mcpInstallv2.png +0 -0
  18. package/assets/sampleResponse.png +0 -0
  19. package/auth/index.html +13 -0
  20. package/auth/package.json +28 -0
  21. package/auth/public/favicon.ico +0 -0
  22. package/auth/src/App.tsx +33 -0
  23. package/auth/src/components/ErrorCard.tsx +37 -0
  24. package/auth/src/components/Layout.tsx +13 -0
  25. package/auth/src/index.css +19 -0
  26. package/auth/src/lib/broadcastService.ts +115 -0
  27. package/auth/src/lib/utils.ts +11 -0
  28. package/auth/src/main.tsx +22 -0
  29. package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
  30. package/auth/src/pages/ResetPasswordPage.tsx +11 -0
  31. package/auth/src/pages/SignInPage.tsx +57 -0
  32. package/auth/src/pages/SignUpPage.tsx +57 -0
  33. package/auth/src/pages/VerifyEmailPage.tsx +20 -0
  34. package/auth/src/vite-env.d.ts +10 -0
  35. package/auth/tsconfig.json +32 -0
  36. package/auth/tsconfig.node.json +11 -0
  37. package/auth/vite.config.ts +25 -0
  38. package/backend/package.json +9 -9
  39. package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
  40. package/backend/src/api/middlewares/rate-limiters.ts +127 -0
  41. package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +20 -24
  42. package/backend/src/api/routes/auth/index.routes.ts +570 -0
  43. package/backend/src/api/routes/auth/oauth.routes.ts +448 -0
  44. package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +107 -65
  45. package/backend/src/api/routes/database/index.routes.ts +13 -0
  46. package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +22 -8
  47. package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +20 -23
  48. package/backend/src/api/routes/docs/index.routes.ts +76 -0
  49. package/backend/src/api/routes/functions/index.routes.ts +188 -0
  50. package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
  51. package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +21 -31
  52. package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
  53. package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +34 -53
  54. package/backend/src/api/routes/usage/index.routes.ts +89 -0
  55. package/backend/src/infra/config/app.config.ts +51 -0
  56. package/backend/src/{core/database/manager.ts → infra/database/database.manager.ts} +76 -85
  57. package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
  58. package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
  59. package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
  60. package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
  61. package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
  62. package/backend/src/infra/security/token.manager.ts +125 -0
  63. package/backend/src/{core/socket/socket.ts → infra/socket/socket.manager.ts} +15 -15
  64. package/backend/src/providers/ai/openrouter.provider.ts +377 -0
  65. package/backend/src/providers/email/base.provider.ts +41 -0
  66. package/backend/src/providers/email/cloud.provider.ts +187 -0
  67. package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
  68. package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
  69. package/backend/src/providers/logs/local.provider.ts +185 -0
  70. package/backend/src/providers/oauth/base.provider.ts +29 -0
  71. package/backend/src/providers/oauth/discord.provider.ts +195 -0
  72. package/backend/src/providers/oauth/facebook.provider.ts +194 -0
  73. package/backend/src/providers/oauth/github.provider.ts +208 -0
  74. package/backend/src/providers/oauth/google.provider.ts +249 -0
  75. package/backend/src/providers/oauth/index.ts +7 -0
  76. package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
  77. package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
  78. package/backend/src/providers/oauth/x.provider.ts +202 -0
  79. package/backend/src/providers/storage/base.provider.ts +29 -0
  80. package/backend/src/providers/storage/local.provider.ts +103 -0
  81. package/backend/src/providers/storage/s3.provider.ts +313 -0
  82. package/backend/src/server.ts +70 -74
  83. package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
  84. package/backend/src/services/ai/ai-model.service.ts +60 -0
  85. package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
  86. package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
  87. package/backend/src/services/ai/helpers.ts +64 -0
  88. package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
  89. package/backend/src/services/ai/index.ts +13 -0
  90. package/backend/src/services/auth/auth-config.service.ts +250 -0
  91. package/backend/src/services/auth/auth-otp.service.ts +424 -0
  92. package/backend/src/services/auth/auth.service.ts +1136 -0
  93. package/backend/src/services/auth/index.ts +4 -0
  94. package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
  95. package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
  96. package/backend/src/services/database/database-table.service.ts +811 -0
  97. package/backend/src/services/email/email.service.ts +75 -0
  98. package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
  99. package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
  100. package/backend/src/services/logs/log.service.ts +73 -0
  101. package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
  102. package/backend/src/services/storage/storage.service.ts +617 -0
  103. package/backend/src/services/usage/usage.service.ts +149 -0
  104. package/backend/src/types/auth.ts +66 -2
  105. package/backend/src/types/email.ts +8 -0
  106. package/backend/src/types/error-constants.ts +4 -0
  107. package/backend/src/types/logs.ts +0 -29
  108. package/backend/src/{core/socket/types.ts → types/socket.ts} +5 -6
  109. package/backend/src/utils/environment.ts +9 -3
  110. package/backend/src/utils/logger.ts +20 -2
  111. package/backend/src/utils/seed.ts +150 -57
  112. package/backend/src/utils/sql-parser.ts +1 -1
  113. package/backend/src/utils/utils.ts +114 -0
  114. package/backend/src/utils/validations.ts +40 -4
  115. package/backend/tests/local/test-ai-config.sh +129 -0
  116. package/backend/tests/local/test-ai-usage.sh +80 -0
  117. package/backend/tests/local/test-auth-router.sh +1 -1
  118. package/backend/tests/local/test-e2e.sh +1 -1
  119. package/backend/tests/local/test-functions.sh +123 -0
  120. package/backend/tests/local/test-logs.sh +132 -0
  121. package/backend/tests/local/test-public-bucket.sh +3 -3
  122. package/backend/tests/local/test-secrets.sh +14 -12
  123. package/backend/tests/local/test-traditional-rest.sh +2 -2
  124. package/backend/tests/manual/test-rawsql-modes.sh +244 -0
  125. package/backend/tests/test-config.sh +37 -1
  126. package/backend/tests/unit/cloud-token.test.ts +48 -0
  127. package/backend/tests/unit/constant.test.ts +8 -0
  128. package/backend/tests/unit/email.test.ts +372 -0
  129. package/backend/tests/unit/environment.test.ts +59 -0
  130. package/backend/tests/unit/helpers.test.ts +63 -0
  131. package/backend/tests/unit/logger.test.ts +22 -0
  132. package/backend/tests/unit/rate-limit.test.ts +154 -0
  133. package/backend/tests/unit/response.test.ts +58 -0
  134. package/backend/tests/unit/sql-parser.test.ts +74 -0
  135. package/backend/tests/unit/uuid.test.ts +21 -0
  136. package/backend/tests/unit/validations.test.ts +80 -0
  137. package/backend/tsconfig.json +1 -1
  138. package/backend/vitest.config.ts +11 -0
  139. package/claude-plugin/.claude-plugin/plugin.json +24 -0
  140. package/claude-plugin/README.md +133 -0
  141. package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
  142. package/docker-compose.prod.yml +60 -4
  143. package/docker-compose.yml +65 -4
  144. package/docker-init/db/db-init.sql +6 -34
  145. package/docker-init/logs/vector.yml +236 -0
  146. package/docs/README.md +44 -0
  147. package/docs/changelog.mdx +67 -0
  148. package/docs/core-concepts/ai/architecture.mdx +373 -0
  149. package/docs/core-concepts/ai/sdk.mdx +213 -0
  150. package/docs/core-concepts/authentication/architecture.mdx +278 -0
  151. package/docs/core-concepts/authentication/sdk.mdx +414 -0
  152. package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
  153. package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
  154. package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
  155. package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
  156. package/docs/core-concepts/database/architecture.mdx +256 -0
  157. package/docs/core-concepts/database/sdk.mdx +382 -0
  158. package/docs/core-concepts/functions/architecture.mdx +105 -0
  159. package/docs/core-concepts/functions/sdk.mdx +184 -0
  160. package/docs/core-concepts/storage/architecture.mdx +243 -0
  161. package/docs/core-concepts/storage/sdk.mdx +253 -0
  162. package/docs/deployment/README.md +94 -0
  163. package/docs/deployment/deploy-to-aws-ec2.md +565 -0
  164. package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
  165. package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
  166. package/docs/deployment/deploy-to-render.md +441 -0
  167. package/docs/docs.json +210 -0
  168. package/docs/examples/framework-guides/nextjs.mdx +131 -0
  169. package/docs/examples/framework-guides/nuxt.mdx +165 -0
  170. package/docs/examples/framework-guides/react.mdx +165 -0
  171. package/docs/examples/framework-guides/svelte.mdx +153 -0
  172. package/docs/examples/framework-guides/vue.mdx +159 -0
  173. package/docs/examples/overview.mdx +67 -0
  174. package/docs/favicon.svg +19 -0
  175. package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
  176. package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
  177. package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
  178. package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
  179. package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
  180. package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
  181. package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
  182. package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
  183. package/docs/images/checks-passed.png +0 -0
  184. package/docs/images/dashboard-connect-expanded.png +0 -0
  185. package/docs/images/dashboard-connect.png +0 -0
  186. package/docs/images/hero-dark.png +0 -0
  187. package/docs/images/hero-light.png +0 -0
  188. package/docs/images/icons/ai.svg +4 -0
  189. package/docs/images/icons/auth.svg +1 -0
  190. package/docs/images/icons/database.svg +1 -0
  191. package/docs/images/icons/function.svg +1 -0
  192. package/docs/images/icons/storage.svg +1 -0
  193. package/docs/images/logos/nextjs.svg +4 -0
  194. package/docs/images/logos/nuxt.svg +4 -0
  195. package/docs/images/logos/react.svg +5 -0
  196. package/docs/images/logos/svelte.svg +4 -0
  197. package/docs/images/logos/vue.svg +5 -0
  198. package/docs/images/mcp-install.png +0 -0
  199. package/docs/images/onboarding-mcp.png +0 -0
  200. package/docs/insforge-instructions-sdk.md +55 -374
  201. package/docs/introduction.mdx +45 -0
  202. package/docs/logo/dark.svg +22 -0
  203. package/docs/logo/light.svg +20 -0
  204. package/docs/partnership.mdx +647 -0
  205. package/docs/quickstart.mdx +83 -0
  206. package/docs/showcase/2048-arena.png +0 -0
  207. package/docs/showcase/framegen-cloud.png +0 -0
  208. package/docs/showcase/line-connect-race.png +0 -0
  209. package/docs/showcase/moment-vibe.png +0 -0
  210. package/docs/showcase/national-flags.png +0 -0
  211. package/docs/showcase/pokemon-vibe.png +0 -0
  212. package/docs/showcase/pure-browse-buy.png +0 -0
  213. package/docs/showcase.mdx +52 -0
  214. package/docs/snippets/sdk-installation.mdx +22 -0
  215. package/docs/snippets/service-icons.mdx +27 -0
  216. package/eslint.config.js +10 -3
  217. package/frontend/package.json +10 -4
  218. package/frontend/src/App.tsx +13 -82
  219. package/frontend/src/assets/icons/connected.svg +3 -0
  220. package/frontend/src/assets/icons/loader.svg +9 -0
  221. package/frontend/src/assets/logos/apple.svg +4 -0
  222. package/frontend/src/assets/logos/discord.svg +1 -1
  223. package/frontend/src/assets/logos/facebook.svg +3 -0
  224. package/frontend/src/assets/logos/instagram.svg +2 -0
  225. package/frontend/src/assets/logos/linkedin.svg +3 -0
  226. package/frontend/src/assets/logos/microsoft.svg +1 -0
  227. package/frontend/src/assets/logos/spotify.svg +17 -0
  228. package/frontend/src/assets/logos/tiktok.svg +6 -0
  229. package/frontend/src/assets/logos/x.svg +3 -0
  230. package/frontend/src/components/Checkbox.tsx +27 -29
  231. package/frontend/src/components/CodeBlock.tsx +55 -2
  232. package/frontend/src/components/CodeEditor.tsx +92 -0
  233. package/frontend/src/components/ConfirmDialog.tsx +1 -1
  234. package/frontend/src/components/ConnectCTA.tsx +38 -0
  235. package/frontend/src/components/CopyButton.tsx +52 -15
  236. package/frontend/src/components/ErrorState.tsx +1 -2
  237. package/frontend/src/components/FeatureSidebar.tsx +6 -6
  238. package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
  239. package/frontend/src/components/JsonHighlight.tsx +21 -9
  240. package/frontend/src/components/ProjectInfoModal.tsx +128 -0
  241. package/frontend/src/components/PromptDialog.tsx +1 -4
  242. package/frontend/src/components/SearchInput.tsx +1 -2
  243. package/frontend/src/components/Stepper.tsx +53 -0
  244. package/frontend/src/components/ThemeToggle.tsx +3 -3
  245. package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
  246. package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
  247. package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
  248. package/frontend/src/components/datagrid/index.ts +23 -0
  249. package/frontend/src/components/index.ts +23 -30
  250. package/frontend/src/components/layout/AppHeader.tsx +133 -92
  251. package/frontend/src/components/layout/AppSidebar.tsx +80 -170
  252. package/frontend/src/components/layout/Layout.tsx +12 -23
  253. package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
  254. package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
  255. package/frontend/src/components/layout/index.ts +5 -0
  256. package/frontend/src/components/radix/Tooltip.tsx +24 -13
  257. package/frontend/src/components/radix/index.ts +22 -0
  258. package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
  259. package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
  260. package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
  261. package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
  262. package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
  263. package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
  264. package/frontend/src/features/ai/components/index.ts +6 -0
  265. package/frontend/src/features/ai/helpers.ts +57 -71
  266. package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
  267. package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
  268. package/frontend/src/features/ai/page/AIPage.tsx +67 -79
  269. package/frontend/src/features/ai/services/ai.service.ts +5 -5
  270. package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
  271. package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +53 -30
  272. package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
  273. package/frontend/src/features/auth/components/UsersDataGrid.tsx +44 -14
  274. package/frontend/src/features/auth/components/index.ts +5 -0
  275. package/frontend/src/features/auth/helpers.tsx +200 -0
  276. package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
  277. package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
  278. package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
  279. package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
  280. package/frontend/src/features/auth/index.ts +3 -2
  281. package/frontend/src/features/auth/page/AuthMethodsPage.tsx +275 -0
  282. package/frontend/src/features/auth/page/ConfigurationPage.tsx +395 -0
  283. package/frontend/src/features/auth/page/UsersPage.tsx +285 -0
  284. package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
  285. package/frontend/src/features/auth/services/config.service.ts +19 -0
  286. package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
  287. package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
  288. package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
  289. package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
  290. package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
  291. package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
  292. package/frontend/src/features/dashboard/components/index.ts +4 -0
  293. package/frontend/src/features/dashboard/page/DashboardPage.tsx +187 -169
  294. package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
  295. package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
  296. package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
  297. package/frontend/src/features/dashboard/prompts/index.ts +31 -0
  298. package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
  299. package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
  300. package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
  301. package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
  302. package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
  303. package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
  304. package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
  305. package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
  306. package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
  307. package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
  308. package/frontend/src/features/database/components/TableForm.tsx +28 -15
  309. package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
  310. package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
  311. package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
  312. package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
  313. package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
  314. package/frontend/src/features/database/components/index.ts +19 -0
  315. package/frontend/src/features/database/constants.ts +28 -2
  316. package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
  317. package/frontend/src/features/database/helpers.ts +2 -2
  318. package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
  319. package/frontend/src/features/database/hooks/useFullMetadata.ts +18 -0
  320. package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
  321. package/frontend/src/features/database/hooks/useRecords.ts +139 -0
  322. package/frontend/src/features/database/hooks/useTables.ts +131 -0
  323. package/frontend/src/features/database/index.ts +6 -1
  324. package/frontend/src/features/database/page/FunctionsPage.tsx +211 -0
  325. package/frontend/src/features/database/page/IndexesPage.tsx +240 -0
  326. package/frontend/src/features/database/page/PoliciesPage.tsx +248 -0
  327. package/frontend/src/features/database/page/SQLEditorPage.tsx +382 -0
  328. package/frontend/src/features/database/page/{DatabasePage.tsx → TablesPage.tsx} +186 -185
  329. package/frontend/src/features/database/page/TemplatesPage.tsx +39 -0
  330. package/frontend/src/features/database/page/TriggersPage.tsx +242 -0
  331. package/frontend/src/features/database/services/advance.service.ts +66 -0
  332. package/frontend/src/features/database/services/{database.service.ts → record.service.ts} +67 -64
  333. package/frontend/src/features/database/services/table.service.ts +64 -0
  334. package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
  335. package/frontend/src/features/database/templates/crm-system.ts +528 -0
  336. package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
  337. package/frontend/src/features/database/templates/index.ts +34 -0
  338. package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
  339. package/frontend/src/features/database/templates/notion-clone.ts +483 -0
  340. package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
  341. package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
  342. package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
  343. package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
  344. package/frontend/src/features/functions/components/index.ts +5 -0
  345. package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
  346. package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
  347. package/frontend/src/features/functions/page/FunctionsPage.tsx +160 -17
  348. package/frontend/src/features/functions/{components/SecretsContent.tsx → page/SecretsPage.tsx} +8 -12
  349. package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
  350. package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
  351. package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
  352. package/frontend/src/features/login/page/CloudLoginPage.tsx +79 -54
  353. package/frontend/src/features/login/page/LoginPage.tsx +16 -23
  354. package/frontend/src/features/login/services/partnership.service.ts +65 -0
  355. package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
  356. package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
  357. package/frontend/src/features/logs/components/index.ts +2 -0
  358. package/frontend/src/features/logs/helpers.ts +24 -0
  359. package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
  360. package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
  361. package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
  362. package/frontend/src/features/logs/hooks/useMcpUsage.ts +181 -0
  363. package/frontend/src/features/logs/index.ts +8 -2
  364. package/frontend/src/features/logs/page/AuditsPage.tsx +91 -38
  365. package/frontend/src/features/logs/page/LogsPage.tsx +152 -0
  366. package/frontend/src/features/logs/page/MCPLogsPage.tsx +84 -0
  367. package/frontend/src/features/logs/services/audit.service.ts +63 -0
  368. package/frontend/src/features/logs/services/log.service.ts +15 -110
  369. package/frontend/src/features/logs/services/usage.service.ts +31 -0
  370. package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
  371. package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
  372. package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
  373. package/frontend/src/features/onboard/components/index.ts +4 -0
  374. package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
  375. package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
  376. package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
  377. package/frontend/src/features/onboard/index.ts +13 -3
  378. package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
  379. package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
  380. package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
  381. package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
  382. package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
  383. package/frontend/src/features/storage/components/index.ts +12 -0
  384. package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
  385. package/frontend/src/features/storage/page/StoragePage.tsx +41 -115
  386. package/frontend/src/features/storage/services/storage.service.ts +22 -1
  387. package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
  388. package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
  389. package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
  390. package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
  391. package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
  392. package/frontend/src/features/visualizer/page/VisualizerPage.tsx +33 -29
  393. package/frontend/src/index.css +1 -0
  394. package/frontend/src/lib/analytics/posthog.tsx +27 -0
  395. package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
  396. package/frontend/src/lib/contexts/SocketContext.tsx +5 -6
  397. package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
  398. package/frontend/src/lib/hooks/useToast.tsx +6 -2
  399. package/frontend/src/lib/routing/AppRoutes.tsx +84 -0
  400. package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
  401. package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
  402. package/frontend/src/lib/utils/menuItems.ts +183 -0
  403. package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
  404. package/frontend/src/lib/utils/utils.ts +19 -1
  405. package/frontend/src/vite-env.d.ts +1 -0
  406. package/frontend/vite.config.ts +5 -3
  407. package/functions/server.ts +28 -3
  408. package/functions/worker-template.js +15 -4
  409. package/i18n/README.ar.md +130 -0
  410. package/i18n/README.de.md +130 -0
  411. package/i18n/README.es.md +154 -0
  412. package/i18n/README.fr.md +134 -0
  413. package/i18n/README.hi.md +129 -0
  414. package/i18n/README.ja.md +174 -0
  415. package/i18n/README.ko.md +137 -0
  416. package/i18n/README.pt-BR.md +131 -0
  417. package/i18n/README.ru.md +129 -0
  418. package/i18n/README.zh-CN.md +133 -0
  419. package/openapi/ai.yaml +31 -4
  420. package/openapi/auth.yaml +827 -146
  421. package/package.json +16 -7
  422. package/shared-schemas/package.json +1 -1
  423. package/shared-schemas/src/ai-api.schema.ts +34 -58
  424. package/shared-schemas/src/ai.schema.ts +5 -0
  425. package/shared-schemas/src/auth-api.schema.ts +154 -8
  426. package/shared-schemas/src/auth.schema.ts +42 -6
  427. package/shared-schemas/src/cloud-events.schema.ts +57 -0
  428. package/shared-schemas/src/database-api.schema.ts +3 -3
  429. package/shared-schemas/src/database.schema.ts +1 -1
  430. package/shared-schemas/src/index.ts +1 -0
  431. package/shared-schemas/src/logs-api.schema.ts +7 -1
  432. package/shared-schemas/src/logs.schema.ts +26 -0
  433. package/shared-schemas/src/metadata.schema.ts +9 -4
  434. package/test-gemini.sh +35 -0
  435. package/test-usage-admin.sh +57 -0
  436. package/test-usage.sh +50 -0
  437. package/zeabur/README.md +13 -0
  438. package/zeabur/template.yml +1032 -0
  439. package/.github/workflows/deploy-aws.yml +0 -130
  440. package/backend/src/api/routes/agent.ts +0 -29
  441. package/backend/src/api/routes/auth.oauth.ts +0 -482
  442. package/backend/src/api/routes/auth.ts +0 -386
  443. package/backend/src/api/routes/docs.ts +0 -66
  444. package/backend/src/api/routes/functions.ts +0 -183
  445. package/backend/src/api/routes/openapi.ts +0 -82
  446. package/backend/src/api/routes/usage.ts +0 -96
  447. package/backend/src/core/ai/client.ts +0 -242
  448. package/backend/src/core/ai/model.ts +0 -117
  449. package/backend/src/core/auth/auth.ts +0 -780
  450. package/backend/src/core/database/table.ts +0 -772
  451. package/backend/src/core/documentation/agent.ts +0 -689
  452. package/backend/src/core/documentation/openapi.ts +0 -856
  453. package/backend/src/core/logs/analytics.ts +0 -76
  454. package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
  455. package/backend/src/core/storage/storage.ts +0 -923
  456. package/backend/src/utils/cloud-token.ts +0 -39
  457. package/backend/src/utils/helpers.ts +0 -49
  458. package/backend/src/utils/uuid.ts +0 -9
  459. package/backend/tests/manual/test-better-auth.sh +0 -303
  460. package/docker-init/db/logs.sql +0 -9
  461. package/frontend/README.md +0 -112
  462. package/frontend/src/components/datagrid/index.tsx +0 -20
  463. package/frontend/src/components/layout/CloudLayout.tsx +0 -95
  464. package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
  465. package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
  466. package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
  467. package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
  468. package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
  469. package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
  470. package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
  471. package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
  472. package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
  473. package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
  474. package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
  475. package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
  476. package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
  477. package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
  478. package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
  479. package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
  480. package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
  481. package/frontend/src/features/metadata/index.ts +0 -0
  482. package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
  483. package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
  484. package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
  485. package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
  486. package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
  487. package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
  488. package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
  489. package/frontend/src/features/onboard/types.ts +0 -8
  490. package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
  491. package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
  492. /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
  493. /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
  494. /package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +0 -0
  495. /package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +0 -0
  496. /package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +0 -0
  497. /package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +0 -0
  498. /package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +0 -0
  499. /package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +0 -0
  500. /package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +0 -0
  501. /package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +0 -0
  502. /package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +0 -0
  503. /package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +0 -0
  504. /package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +0 -0
  505. /package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +0 -0
  506. /package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +0 -0
  507. /package/frontend/src/{features/metadata → lib}/services/metadata.service.ts +0 -0
@@ -0,0 +1,68 @@
1
+ import { format } from 'date-fns';
2
+ import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components';
3
+ import { useMcpUsage } from '@/features/logs/hooks/useMcpUsage';
4
+ import { cn } from '@/lib/utils/utils';
5
+
6
+ const formatConnectionTime = (timestamp: string) => {
7
+ return format(new Date(timestamp), 'MMM dd, yyyy, h:mm a');
8
+ };
9
+
10
+ interface McpConnectionStatusProps {
11
+ onConnectClick: () => void;
12
+ }
13
+
14
+ export function McpConnectionStatus({ onConnectClick }: McpConnectionStatusProps) {
15
+ const { hasCompletedOnboarding, latestRecord, isLoading } = useMcpUsage();
16
+
17
+ // Don't render while loading
18
+ if (isLoading) {
19
+ return null;
20
+ }
21
+
22
+ // When not connected, show "Connect" with gray dot
23
+ if (!hasCompletedOnboarding) {
24
+ return (
25
+ <Button
26
+ variant="outline"
27
+ onClick={onConnectClick}
28
+ className="h-9 px-4 gap-2 bg-white dark:bg-transparent text-gray-900 dark:text-white border-gray-300 dark:border-neutral-600 hover:bg-gray-100 dark:hover:bg-neutral-900 rounded-full"
29
+ >
30
+ <div className="w-2 h-2 rounded-full bg-neutral-400" />
31
+ <span className="text-sm">Connect</span>
32
+ </Button>
33
+ );
34
+ }
35
+
36
+ // When connected, show "Connected" with green dot and tooltip
37
+ return (
38
+ <TooltipProvider>
39
+ <Tooltip>
40
+ <TooltipTrigger asChild>
41
+ <Button
42
+ variant="outline"
43
+ onClick={onConnectClick}
44
+ className="h-9 px-4 gap-2 bg-white dark:bg-transparent text-gray-900 dark:text-white border-gray-300 dark:border-neutral-600 hover:bg-gray-100 dark:hover:bg-neutral-900 rounded-full"
45
+ >
46
+ <div className="w-2 h-2 rounded-full bg-emerald-400" />
47
+ <span className="text-sm">Connected</span>
48
+ </Button>
49
+ </TooltipTrigger>
50
+ <TooltipContent
51
+ side="bottom"
52
+ sideOffset={8}
53
+ className={cn(
54
+ 'bg-white dark:bg-neutral-800 border border-gray-200 dark:border-neutral-700',
55
+ 'text-gray-700 dark:text-neutral-300 p-3 max-w-[280px]'
56
+ )}
57
+ >
58
+ <p className="text-sm">
59
+ Last MCP call was at{' '}
60
+ <span className="text-gray-900 dark:text-white font-medium">
61
+ {latestRecord ? formatConnectionTime(latestRecord.created_at) : 'Unknown'}
62
+ </span>
63
+ </p>
64
+ </TooltipContent>
65
+ </Tooltip>
66
+ </TooltipProvider>
67
+ );
68
+ }
@@ -0,0 +1,267 @@
1
+ import { useState, useMemo } from 'react';
2
+ import { ChevronDown, HelpCircle } from 'lucide-react';
3
+ import {
4
+ Dialog,
5
+ DialogContent,
6
+ DialogTitle,
7
+ Button,
8
+ CopyButton,
9
+ CodeBlock,
10
+ Tooltip,
11
+ TooltipContent,
12
+ TooltipProvider,
13
+ TooltipTrigger,
14
+ } from '@/components';
15
+ import { VideoDemoModal } from './VideoDemoModal';
16
+ import { CursorDeeplinkGenerator } from './mcp/CursorDeeplinkGenerator';
17
+ import { MCP_AGENTS, GenerateInstallCommand, createMCPConfig, type MCPAgent } from './mcp/helpers';
18
+ import { useApiKey } from '@/lib/hooks/useMetadata';
19
+ import { cn, getBackendUrl } from '@/lib/utils/utils';
20
+ import DiscordIcon from '@/assets/logos/discord.svg?react';
21
+
22
+ const ONBOARDING_SKIPPED_KEY = 'insforge_onboarding_skipped';
23
+
24
+ export function getOnboardingSkipped(): boolean {
25
+ return localStorage.getItem(ONBOARDING_SKIPPED_KEY) === 'true';
26
+ }
27
+
28
+ export function setOnboardingSkipped(skipped: boolean): void {
29
+ if (skipped) {
30
+ localStorage.setItem(ONBOARDING_SKIPPED_KEY, 'true');
31
+ } else {
32
+ localStorage.removeItem(ONBOARDING_SKIPPED_KEY);
33
+ }
34
+ }
35
+
36
+ interface OnboardingModalProps {
37
+ open: boolean;
38
+ onOpenChange: (open: boolean) => void;
39
+ }
40
+
41
+ export function OnboardingModal({ open, onOpenChange }: OnboardingModalProps) {
42
+ const [selectedAgent, setSelectedAgent] = useState<MCPAgent>(MCP_AGENTS[0]);
43
+ const [isDropdownOpen, setIsDropdownOpen] = useState(false);
44
+ const [isVideoTooltipOpen, setIsVideoTooltipOpen] = useState(false);
45
+
46
+ const { apiKey, isLoading } = useApiKey();
47
+ const appUrl = getBackendUrl();
48
+
49
+ const displayApiKey = isLoading ? 'ik_' + '*'.repeat(32) : apiKey || '';
50
+
51
+ const installCommand = useMemo(() => {
52
+ return GenerateInstallCommand(selectedAgent, displayApiKey);
53
+ }, [selectedAgent, displayApiKey]);
54
+
55
+ const mcpJsonConfig = useMemo(() => {
56
+ const config = createMCPConfig(displayApiKey, 'macos-linux', appUrl);
57
+ return JSON.stringify(config, null, 2);
58
+ }, [displayApiKey, appUrl]);
59
+
60
+ const testPrompt =
61
+ "I'm using InsForge as my backend platform, fetch InsForge instruction doc to learn more about InsForge";
62
+
63
+ const handleSkipOnboarding = () => {
64
+ setOnboardingSkipped(true);
65
+ onOpenChange(false);
66
+ };
67
+
68
+ const handleModalClose = (nextOpen: boolean) => {
69
+ if (!nextOpen) {
70
+ handleSkipOnboarding();
71
+ }
72
+ };
73
+
74
+ return (
75
+ <Dialog open={open} onOpenChange={handleModalClose}>
76
+ <TooltipProvider>
77
+ <DialogContent className="max-w-[640px] bg-white dark:bg-neutral-800 dark:border-neutral-700 p-6 gap-10">
78
+ <DialogTitle className="sr-only">Connect Project</DialogTitle>
79
+
80
+ {/* Header Section */}
81
+ <div className="flex flex-col gap-6">
82
+ <div className="flex flex-col gap-3">
83
+ <h3 className="text-gray-900 dark:text-white text-2xl font-semibold leading-8 tracking-[-0.144px]">
84
+ Connect Project
85
+ </h3>
86
+ <div className="flex items-center gap-1">
87
+ <p className="text-gray-500 dark:text-neutral-400 text-base leading-7">
88
+ Connect your AI agent by installing the MCP server. The installation completes
89
+ automatically when we receive the first MCP call.
90
+ </p>
91
+ <Tooltip>
92
+ <TooltipTrigger asChild>
93
+ <div
94
+ onMouseEnter={() => setIsVideoTooltipOpen(true)}
95
+ onMouseLeave={() => setIsVideoTooltipOpen(false)}
96
+ className="cursor-help"
97
+ >
98
+ <HelpCircle className="w-5 h-5 text-gray-400 dark:text-neutral-400 shrink-0" />
99
+ </div>
100
+ </TooltipTrigger>
101
+ <TooltipContent
102
+ portal
103
+ side="bottom"
104
+ sideOffset={10}
105
+ className="p-0 bg-transparent border-0 shadow-none z-[100]"
106
+ >
107
+ <VideoDemoModal open={isVideoTooltipOpen} className="w-[580px]" />
108
+ </TooltipContent>
109
+ </Tooltip>
110
+ </div>
111
+ </div>
112
+
113
+ {/* Agent Selector Dropdown */}
114
+ <div className="relative">
115
+ <button
116
+ onClick={() => setIsDropdownOpen(!isDropdownOpen)}
117
+ className="w-40 bg-gray-100 dark:bg-[rgba(0,0,0,0.12)] border border-gray-300 dark:border-[rgba(255,255,255,0.24)] rounded flex items-center justify-between px-2 py-1"
118
+ >
119
+ <div className="flex items-center gap-2">
120
+ {selectedAgent.logo && (
121
+ <div className="w-6 h-6 flex items-center justify-center">
122
+ {selectedAgent.logo}
123
+ </div>
124
+ )}
125
+ <span className="text-gray-900 dark:text-white text-sm font-medium">
126
+ {selectedAgent.displayName}
127
+ </span>
128
+ </div>
129
+ <ChevronDown className="w-5 h-5 text-gray-400 dark:text-neutral-400" />
130
+ </button>
131
+
132
+ {/* Dropdown Menu */}
133
+ {isDropdownOpen && (
134
+ <div className="absolute top-full left-0 mt-1 w-40 bg-white dark:bg-neutral-800 border border-gray-200 dark:border-neutral-700 rounded shadow-lg z-50">
135
+ {MCP_AGENTS.map((agent) => (
136
+ <button
137
+ key={agent.id}
138
+ onClick={() => {
139
+ setSelectedAgent(agent);
140
+ setIsDropdownOpen(false);
141
+ }}
142
+ className="w-full flex items-center gap-2 px-2 py-2 text-gray-900 dark:text-white text-sm hover:bg-gray-100 dark:hover:bg-neutral-700 transition-colors"
143
+ >
144
+ {agent.logo && (
145
+ <div className="w-6 h-6 flex items-center justify-center">{agent.logo}</div>
146
+ )}
147
+ <span className="font-medium">{agent.displayName}</span>
148
+ </button>
149
+ ))}
150
+ </div>
151
+ )}
152
+ </div>
153
+
154
+ {/* Step 1 - Conditional based on agent */}
155
+ {selectedAgent.id === 'cursor' ? (
156
+ <div className="flex flex-col gap-3">
157
+ <p className="text-gray-900 dark:text-white text-sm">
158
+ <span className="font-semibold leading-5">Step 1</span>
159
+ <span className="leading-6"> - Install in one click</span>
160
+ </p>
161
+ <div className="w-fit">
162
+ <CursorDeeplinkGenerator apiKey={displayApiKey} os="macos-linux" />
163
+ </div>
164
+ </div>
165
+ ) : selectedAgent.id === 'mcp' ? (
166
+ <div className="flex flex-col gap-3">
167
+ <p className="text-gray-900 dark:text-white text-sm">
168
+ <span className="font-semibold leading-5">Step 1</span>
169
+ <span className="leading-6">
170
+ {' '}
171
+ - Copy the configuration below and add it to your AI assistant.
172
+ </span>
173
+ </p>
174
+ <div className="bg-gray-100 dark:bg-neutral-900 rounded overflow-hidden flex flex-col h-[320px] w-full">
175
+ {/* Header - fixed at top */}
176
+ <div className="bg-gray-100 dark:bg-neutral-900 flex items-center justify-between p-3">
177
+ <div className="bg-gray-200 dark:bg-neutral-700 rounded px-2">
178
+ <span className="text-gray-700 dark:text-neutral-50 text-xs">
179
+ MCP Configuration
180
+ </span>
181
+ </div>
182
+ <CopyButton
183
+ text={mcpJsonConfig}
184
+ showText={false}
185
+ className="h-6 w-6 p-1 bg-white dark:bg-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-600 border-none rounded-md shadow-sm min-w-0 text-black dark:text-white"
186
+ />
187
+ </div>
188
+ {/* Scrollable content */}
189
+ <div className="flex-1 overflow-auto p-3">
190
+ <pre className="text-gray-700 dark:text-neutral-300 text-sm leading-6 m-0 whitespace-pre-wrap break-all">
191
+ <code>{mcpJsonConfig}</code>
192
+ </pre>
193
+ </div>
194
+ </div>
195
+ </div>
196
+ ) : (
197
+ <div className="flex flex-col gap-3">
198
+ <p className="text-gray-900 dark:text-white text-sm">
199
+ <span className="font-semibold leading-5">Step 1</span>
200
+ <span className="leading-6"> - Install in one click</span>
201
+ </p>
202
+ <CodeBlock
203
+ code={installCommand}
204
+ label="Terminal Command"
205
+ className={cn(isLoading && 'animate-pulse')}
206
+ />
207
+ </div>
208
+ )}
209
+
210
+ {/* Step 2 */}
211
+ <div className="flex flex-col gap-3">
212
+ <p className="text-gray-900 dark:text-white text-sm">
213
+ <span className="font-semibold leading-5">Step 2</span>
214
+ <span className="leading-6">
215
+ {' '}
216
+ - Send the prompt below in your agent&apos;s chat
217
+ </span>
218
+ </p>
219
+ <CodeBlock
220
+ code={testPrompt}
221
+ label="prompt"
222
+ className="bg-gray-100 dark:bg-neutral-900"
223
+ />
224
+ </div>
225
+ </div>
226
+
227
+ {/* Help Section */}
228
+ <div className="flex items-end justify-between">
229
+ <div className="flex flex-col gap-2">
230
+ <div className="flex items-center gap-2">
231
+ <span className="text-gray-500 dark:text-neutral-400 text-sm leading-6">
232
+ Need help?
233
+ </span>
234
+ </div>
235
+ <div className="flex items-center gap-2">
236
+ <span className="text-gray-500 dark:text-neutral-400 text-sm leading-6">
237
+ Join our
238
+ </span>
239
+ <a
240
+ href="https://discord.gg/DvBtaEc9Jz"
241
+ target="_blank"
242
+ rel="noopener noreferrer"
243
+ className="inline-flex items-center gap-1 hover:underline"
244
+ >
245
+ <DiscordIcon className="w-5 h-5 text-indigo-500 dark:text-indigo-400" />
246
+ <span className="text-indigo-500 dark:text-indigo-400 text-sm leading-6 font-medium">
247
+ Discord
248
+ </span>
249
+ </a>
250
+ <span className="text-gray-500 dark:text-neutral-400 text-sm leading-6">
251
+ for live support
252
+ </span>
253
+ </div>
254
+ </div>
255
+ <Button
256
+ variant="outline"
257
+ onClick={handleSkipOnboarding}
258
+ className="px-3 h-8 bg-gray-100 dark:bg-neutral-700 hover:bg-gray-200 dark:hover:bg-neutral-600 text-gray-700 dark:text-white border-gray-300 dark:border-neutral-600 text-sm font-medium"
259
+ >
260
+ I&apos;ll connect later
261
+ </Button>
262
+ </div>
263
+ </DialogContent>
264
+ </TooltipProvider>
265
+ </Dialog>
266
+ );
267
+ }
@@ -0,0 +1,38 @@
1
+ import { cn } from '@/lib/utils/utils';
2
+
3
+ export interface VideoDemoModalProps {
4
+ open: boolean;
5
+ className?: string;
6
+ }
7
+
8
+ export function VideoDemoModal({ open, className }: VideoDemoModalProps) {
9
+ if (!open) {
10
+ return null;
11
+ }
12
+
13
+ return (
14
+ <div
15
+ className={cn(
16
+ 'bg-gray-100 dark:bg-[#3A3A3A] border border-gray-200 dark:border-neutral-700 rounded-lg p-3 flex flex-col gap-2.5',
17
+ className
18
+ )}
19
+ >
20
+ <p className="text-gray-900 dark:text-white text-sm leading-6">
21
+ InsForge MCP lets your coding agent build and control your backend
22
+ </p>
23
+ <div className="w-full aspect-video rounded overflow-hidden bg-neutral-800">
24
+ <video
25
+ autoPlay
26
+ muted
27
+ loop
28
+ playsInline
29
+ className="w-full h-full object-cover"
30
+ controlsList="nodownload"
31
+ >
32
+ <source src="https://insforge.dev/assets/videos/database.mp4" type="video/mp4" />
33
+ Your browser does not support the video tag.
34
+ </video>
35
+ </div>
36
+ </div>
37
+ );
38
+ }
@@ -0,0 +1,4 @@
1
+ export * from './mcp';
2
+ export { McpConnectionStatus } from './McpConnectionStatus';
3
+ export { OnboardingModal, getOnboardingSkipped, setOnboardingSkipped } from './OnboardingModal';
4
+ export { VideoDemoModal } from './VideoDemoModal';
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'react';
2
- import { createMCPServerConfig, type PlatformType } from './mcp-helper';
2
+ import { createMCPServerConfig, type PlatformType } from './helpers';
3
3
  import CursorLogo from '@/assets/logos/cursor.svg?react';
4
4
  import { getBackendUrl } from '@/lib/utils/utils';
5
5
 
@@ -26,7 +26,7 @@ export function CursorDeeplinkGenerator({
26
26
  return (
27
27
  <button
28
28
  onClick={handleOpenInCursor}
29
- className="bg-black py-2 px-4 flex items-center justify-center gap-2.5 rounded-md text-white text-sm font-medium"
29
+ className="h-8 bg-black dark:bg-white px-4 flex items-center justify-center gap-2.5 rounded text-white dark:text-black text-sm font-medium"
30
30
  >
31
31
  <CursorLogo className="h-6 w-6" />
32
32
  <span>Add to Cursor</span>
@@ -21,11 +21,6 @@ export const GenerateInstallCommand = (agent: MCPAgent, apiKey: string) => {
21
21
  };
22
22
 
23
23
  export const MCP_AGENTS: MCPAgent[] = [
24
- {
25
- id: 'trae',
26
- displayName: 'Trae',
27
- logo: <TraeLogo className="w-6 h-6" />,
28
- },
29
24
  {
30
25
  id: 'cursor',
31
26
  displayName: 'Cursor',
@@ -37,15 +32,20 @@ export const MCP_AGENTS: MCPAgent[] = [
37
32
  logo: <ClaudeLogo className="w-6 h-6" />,
38
33
  },
39
34
  {
40
- id: 'windsurf',
41
- displayName: 'Windsurf',
42
- logo: <WindsurfLogo className="w-6 h-6 dark:text-white" />,
35
+ id: 'trae',
36
+ displayName: 'Trae',
37
+ logo: <TraeLogo className="w-5 h-5" />,
43
38
  },
44
39
  {
45
40
  id: 'cline',
46
41
  displayName: 'Cline',
47
42
  logo: <ClineLogo className="w-6 h-6 dark:text-white" />,
48
43
  },
44
+ {
45
+ id: 'windsurf',
46
+ displayName: 'Windsurf',
47
+ logo: <WindsurfLogo className="w-6 h-6 dark:text-white" />,
48
+ },
49
49
  {
50
50
  id: 'roocode',
51
51
  displayName: 'Roo Code',
@@ -1,4 +1,3 @@
1
- export { McpInstallation } from './McpInstallation';
2
1
  export { CursorDeeplinkGenerator } from './CursorDeeplinkGenerator';
3
- export type { MCPAgent, PlatformType } from './mcp-helper';
4
- export { MCP_AGENTS, createMCPConfig, createMCPServerConfig } from './mcp-helper';
2
+ export type { MCPAgent, PlatformType } from './helpers';
3
+ export { MCP_AGENTS, createMCPConfig, createMCPServerConfig } from './helpers';
@@ -1,3 +1,13 @@
1
- export { OnboardStep } from './types';
2
- export { StepContent } from './components/StepContent';
3
- export { TestConnectionStep } from './components/TestConnectionStep';
1
+ // Onboard components
2
+ export { McpConnectionStatus } from './components/McpConnectionStatus';
3
+ export {
4
+ OnboardingModal,
5
+ getOnboardingSkipped,
6
+ setOnboardingSkipped,
7
+ } from './components/OnboardingModal';
8
+ export { VideoDemoModal } from './components/VideoDemoModal';
9
+
10
+ // MCP helpers
11
+ export { CursorDeeplinkGenerator } from './components/mcp/CursorDeeplinkGenerator';
12
+ export type { MCPAgent, PlatformType } from './components/mcp/helpers';
13
+ export { MCP_AGENTS, createMCPConfig, createMCPServerConfig } from './components/mcp/helpers';
@@ -1,4 +1,5 @@
1
1
  import { Folder } from 'lucide-react';
2
+ import { ConnectCTA } from '@/components/ConnectCTA';
2
3
 
3
4
  interface BucketEmptyStateProps {
4
5
  searchTerm: string;
@@ -6,14 +7,16 @@ interface BucketEmptyStateProps {
6
7
 
7
8
  export function BucketEmptyState({ searchTerm }: BucketEmptyStateProps) {
8
9
  return (
9
- <div className="flex flex-col items-center justify-center py-8 px-4 text-center">
10
- <Folder className="h-10 w-10 text-gray-400 dark:text-zinc-300 mb-2.5" />
11
- <p className="text-sm text-gray-600 dark:text-zinc-300 font-medium">
10
+ <div className="flex flex-col items-center justify-center py-4 text-center">
11
+ <Folder className="h-10 w-10 text-gray-400 dark:text-neutral-600 mb-3" />
12
+ <p className="text-sm text-gray-600 dark:text-neutral-400 font-medium">
12
13
  {searchTerm ? 'No buckets found' : 'No buckets yet'}
13
14
  </p>
14
- <p className="text-xs text-gray-500 dark:text-zinc-300 mt-2.5">
15
- {searchTerm ? 'Try a different search term' : 'Create your first bucket to get started'}
16
- </p>
15
+ {!searchTerm && (
16
+ <p className="text-xs text-gray-500 dark:text-neutral-400 font-medium mt-1 mx-10">
17
+ <ConnectCTA fallback="Create your first bucket to get started" />
18
+ </p>
19
+ )}
17
20
  </div>
18
21
  );
19
22
  }
@@ -1,19 +1,17 @@
1
1
  import React, { useState, useEffect } from 'react';
2
- import { useMutation } from '@tanstack/react-query';
3
- import { storageService } from '@/features/storage/services/storage.service';
2
+ import { useStorage } from '@/features/storage/hooks/useStorage';
4
3
  import {
4
+ Button,
5
5
  Dialog,
6
6
  DialogContent,
7
7
  DialogDescription,
8
8
  DialogFooter,
9
9
  DialogHeader,
10
10
  DialogTitle,
11
- } from '@/components/radix/Dialog';
12
- import { Button } from '@/components/radix/Button';
13
- import { Input } from '@/components/radix/Input';
14
- import { Label } from '@/components/radix/Label';
15
- import { Switch } from '@/components/radix/Switch';
16
- import { useToast } from '@/lib/hooks/useToast';
11
+ Input,
12
+ Label,
13
+ Switch,
14
+ } from '@/components';
17
15
 
18
16
  interface BucketFormDialogProps {
19
17
  open: boolean;
@@ -35,7 +33,8 @@ export function BucketFormDialog({
35
33
  const [bucketName, setBucketName] = useState(initialBucketName);
36
34
  const [isPublic, setIsPublic] = useState(initialIsPublic);
37
35
  const [error, setError] = useState('');
38
- const { showToast } = useToast();
36
+
37
+ const { createBucket, editBucket, isCreatingBucket, isEditingBucket } = useStorage();
39
38
 
40
39
  useEffect(() => {
41
40
  if (open) {
@@ -50,33 +49,7 @@ export function BucketFormDialog({
50
49
  }
51
50
  }, [open, mode, initialBucketName, initialIsPublic]);
52
51
 
53
- const createBucketMutation = useMutation({
54
- mutationFn: ({ name, isPublic }: { name: string; isPublic: boolean }) =>
55
- storageService.createBucket(name, isPublic),
56
- onSuccess: () => {
57
- onSuccess(bucketName);
58
- showToast('Bucket created successfully', 'success');
59
- handleClose();
60
- },
61
- onError: (error: Error) => {
62
- setError(error.message || 'Failed to create bucket');
63
- },
64
- });
65
-
66
- const editBucketMutation = useMutation({
67
- mutationFn: ({ name, isPublic }: { name: string; isPublic: boolean }) =>
68
- storageService.editBucket(name, { isPublic: isPublic }),
69
- onSuccess: () => {
70
- onSuccess();
71
- showToast('Bucket updated successfully', 'success');
72
- handleClose();
73
- },
74
- onError: (error: Error) => {
75
- setError(error.message || 'Failed to update bucket');
76
- },
77
- });
78
-
79
- const handleSubmit = (e: React.FormEvent) => {
52
+ const handleSubmit = async (e: React.FormEvent): Promise<void> => {
80
53
  e.preventDefault();
81
54
 
82
55
  if (mode === 'create') {
@@ -84,9 +57,21 @@ export function BucketFormDialog({
84
57
  setError('Bucket name is required');
85
58
  return;
86
59
  }
87
- createBucketMutation.mutate({ name: bucketName.trim(), isPublic });
60
+ try {
61
+ await createBucket({ bucketName: bucketName.trim(), isPublic });
62
+ onSuccess(bucketName);
63
+ handleClose();
64
+ } catch (error) {
65
+ setError(error instanceof Error ? error.message : 'Failed to create bucket');
66
+ }
88
67
  } else {
89
- editBucketMutation.mutate({ name: bucketName, isPublic });
68
+ try {
69
+ await editBucket({ bucketName, config: { isPublic } });
70
+ onSuccess();
71
+ handleClose();
72
+ } catch (error) {
73
+ setError(error instanceof Error ? error.message : 'Failed to update bucket');
74
+ }
90
75
  }
91
76
  };
92
77
 
@@ -94,8 +79,7 @@ export function BucketFormDialog({
94
79
  onOpenChange(false);
95
80
  };
96
81
 
97
- const isLoading =
98
- mode === 'create' ? createBucketMutation.isPending : editBucketMutation.isPending;
82
+ const isLoading = mode === 'create' ? isCreatingBucket : isEditingBucket;
99
83
  const submitButtonText =
100
84
  mode === 'create'
101
85
  ? isLoading
@@ -108,7 +92,7 @@ export function BucketFormDialog({
108
92
  return (
109
93
  <Dialog open={open} onOpenChange={handleClose}>
110
94
  <DialogContent className="w-[480px] p-0 border-zinc-200 shadow-[0px_1px_3px_0px_rgba(0,0,0,0.1)]">
111
- <form onSubmit={handleSubmit} className="flex flex-col">
95
+ <form onSubmit={(e) => void handleSubmit(e)} className="flex flex-col">
112
96
  <DialogHeader className="px-6 py-3 flex flex-col gap-1 justify-start border-b border-zinc-200 dark:border-neutral-700">
113
97
  <DialogTitle className="text-lg font-semibold text-zinc-950 dark:text-white">
114
98
  {mode === 'create' ? 'Create New Bucket' : 'Edit Bucket'}
@@ -1,11 +1,8 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { Download, ExternalLink } from 'lucide-react';
3
- import { Dialog, DialogContent } from '@/components/radix/Dialog';
4
- import { Button } from '@/components/radix/Button';
5
- import { LoadingState } from '@/components';
6
- import { storageService } from '@/features/storage/services/storage.service';
3
+ import { Button, Dialog, DialogContent, LoadingState, TypeBadge } from '@/components';
4
+ import { useStorage } from '@/features/storage/hooks/useStorage';
7
5
  import { StorageFileSchema } from '@insforge/shared-schemas';
8
- import { TypeBadge } from '@/components/TypeBadge';
9
6
 
10
7
  interface FilePreviewDialogProps {
11
8
  open: boolean;
@@ -19,6 +16,8 @@ export function FilePreviewDialog({ open, onOpenChange, file, bucket }: FilePrev
19
16
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
20
17
  const [error, setError] = useState<string | null>(null);
21
18
 
19
+ const { downloadObject } = useStorage();
20
+
22
21
  // Reset state when file changes
23
22
  useEffect(() => {
24
23
  if (!file || !open) {
@@ -27,7 +26,9 @@ export function FilePreviewDialog({ open, onOpenChange, file, bucket }: FilePrev
27
26
  return;
28
27
  }
29
28
 
30
- const loadPreview = () => {
29
+ let currentUrl: string | null = null;
30
+
31
+ const loadPreview = async () => {
31
32
  if (!file) {
32
33
  return;
33
34
  }
@@ -37,7 +38,10 @@ export function FilePreviewDialog({ open, onOpenChange, file, bucket }: FilePrev
37
38
 
38
39
  try {
39
40
  const fileBucket = file.bucket || bucket;
40
- const url = storageService.getDownloadUrl(fileBucket, file.key);
41
+ // Fetch file with authentication and create blob URL
42
+ const blob = await downloadObject(fileBucket, file.key);
43
+ const url = URL.createObjectURL(blob);
44
+ currentUrl = url;
41
45
  setPreviewUrl(url);
42
46
  } catch (err) {
43
47
  const errorMessage = err instanceof Error ? err.message : 'Failed to load preview';
@@ -48,7 +52,14 @@ export function FilePreviewDialog({ open, onOpenChange, file, bucket }: FilePrev
48
52
  };
49
53
 
50
54
  void loadPreview();
51
- }, [file, open, bucket]);
55
+
56
+ // Cleanup: Revoke blob URL when component unmounts or file changes
57
+ return () => {
58
+ if (currentUrl) {
59
+ URL.revokeObjectURL(currentUrl);
60
+ }
61
+ };
62
+ }, [file, open, bucket, downloadObject]);
52
63
 
53
64
  const handleDownload = () => {
54
65
  if (!file || !previewUrl) {
@@ -250,6 +261,7 @@ function TextPreview({ url }: { url: string }) {
250
261
  const loadTextContent = async () => {
251
262
  try {
252
263
  setLoading(true);
264
+ // Fetch the blob URL (which is already authenticated)
253
265
  const response = await fetch(url);
254
266
  if (!response.ok) {
255
267
  throw new Error('Failed to load text content');