insforge 0.3.2 → 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.
- package/.claude-plugin/marketplace.json +20 -0
- package/.cursor/rules/cursor-rules.mdc +94 -0
- package/.dockerignore +3 -0
- package/.env.example +33 -4
- package/.github/ISSUE_TEMPLATE/bug_report.yml +13 -60
- package/.github/ISSUE_TEMPLATE/config.yml +2 -2
- package/.github/ISSUE_TEMPLATE/feature_request.yml +10 -63
- package/.github/PULL_REQUEST_TEMPLATE.md +7 -0
- package/.github/workflows/build-image.yml +2 -1
- package/.github/workflows/e2e.yml +63 -0
- package/CHANGELOG.md +41 -0
- package/CLAUDE_PLUGIN.md +104 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/CONTRIBUTING.md +1 -1
- package/Dockerfile +4 -1
- package/README.md +66 -18
- package/assets/mcpInstallv2.png +0 -0
- package/assets/sampleResponse.png +0 -0
- package/auth/index.html +13 -0
- package/auth/package.json +28 -0
- package/auth/public/favicon.ico +0 -0
- package/auth/src/App.tsx +33 -0
- package/auth/src/components/ErrorCard.tsx +37 -0
- package/auth/src/components/Layout.tsx +13 -0
- package/auth/src/index.css +19 -0
- package/auth/src/lib/broadcastService.ts +115 -0
- package/auth/src/lib/utils.ts +11 -0
- package/auth/src/main.tsx +22 -0
- package/auth/src/pages/ForgotPasswordPage.tsx +11 -0
- package/auth/src/pages/ResetPasswordPage.tsx +11 -0
- package/auth/src/pages/SignInPage.tsx +57 -0
- package/auth/src/pages/SignUpPage.tsx +57 -0
- package/auth/src/pages/VerifyEmailPage.tsx +20 -0
- package/auth/src/vite-env.d.ts +10 -0
- package/auth/tsconfig.json +32 -0
- package/auth/tsconfig.node.json +11 -0
- package/auth/vite.config.ts +25 -0
- package/backend/package.json +9 -9
- package/backend/src/api/{middleware → middlewares}/auth.ts +8 -9
- package/backend/src/api/middlewares/rate-limiters.ts +127 -0
- package/backend/src/api/routes/{ai.ts → ai/index.routes.ts} +20 -24
- package/backend/src/api/routes/auth/index.routes.ts +570 -0
- package/backend/src/api/routes/auth/oauth.routes.ts +448 -0
- package/backend/src/api/routes/{database.advance.ts → database/advance.routes.ts} +107 -65
- package/backend/src/api/routes/database/index.routes.ts +13 -0
- package/backend/src/api/routes/{database.records.ts → database/records.routes.ts} +22 -8
- package/backend/src/api/routes/{database.tables.ts → database/tables.routes.ts} +20 -23
- package/backend/src/api/routes/docs/index.routes.ts +76 -0
- package/backend/src/api/routes/functions/index.routes.ts +188 -0
- package/backend/src/api/routes/{logs.ts → logs/index.routes.ts} +25 -30
- package/backend/src/api/routes/{metadata.ts → metadata/index.routes.ts} +21 -31
- package/backend/src/api/routes/{secrets.ts → secrets/index.routes.ts} +27 -22
- package/backend/src/api/routes/{storage.ts → storage/index.routes.ts} +34 -53
- package/backend/src/api/routes/usage/index.routes.ts +89 -0
- package/backend/src/infra/config/app.config.ts +51 -0
- package/backend/src/{core/database/manager.ts → infra/database/database.manager.ts} +76 -85
- package/backend/src/infra/database/migrations/013_create-auth-schema-functions.sql +44 -0
- package/backend/src/infra/database/migrations/014_add-updated-at-trigger-user-table.sql +8 -0
- package/backend/src/infra/database/migrations/015_create-auth-config-and-email-otp-tables.sql +60 -0
- package/backend/src/infra/database/migrations/016_update-auth-config-and-email-otp.sql +24 -0
- package/backend/src/{core/secrets/encryption.ts → infra/security/encryption.manager.ts} +3 -2
- package/backend/src/infra/security/token.manager.ts +125 -0
- package/backend/src/{core/socket/socket.ts → infra/socket/socket.manager.ts} +15 -15
- package/backend/src/providers/ai/openrouter.provider.ts +377 -0
- package/backend/src/providers/email/base.provider.ts +41 -0
- package/backend/src/providers/email/cloud.provider.ts +187 -0
- package/backend/src/{core/logs/providers → providers/logs}/base.provider.ts +11 -11
- package/backend/src/{core/logs/providers → providers/logs}/cloudwatch.provider.ts +61 -38
- package/backend/src/providers/logs/local.provider.ts +185 -0
- package/backend/src/providers/oauth/base.provider.ts +29 -0
- package/backend/src/providers/oauth/discord.provider.ts +195 -0
- package/backend/src/providers/oauth/facebook.provider.ts +194 -0
- package/backend/src/providers/oauth/github.provider.ts +208 -0
- package/backend/src/providers/oauth/google.provider.ts +249 -0
- package/backend/src/providers/oauth/index.ts +7 -0
- package/backend/src/providers/oauth/linkedin.provider.ts +240 -0
- package/backend/src/providers/oauth/microsoft.provider.ts +169 -0
- package/backend/src/providers/oauth/x.provider.ts +202 -0
- package/backend/src/providers/storage/base.provider.ts +29 -0
- package/backend/src/providers/storage/local.provider.ts +103 -0
- package/backend/src/providers/storage/s3.provider.ts +313 -0
- package/backend/src/server.ts +70 -74
- package/backend/src/{core/ai/config.ts → services/ai/ai-config.service.ts} +19 -24
- package/backend/src/services/ai/ai-model.service.ts +60 -0
- package/backend/src/{core/ai/usage.ts → services/ai/ai-usage.service.ts} +28 -35
- package/backend/src/{core/ai/chat.ts → services/ai/chat-completion.service.ts} +37 -24
- package/backend/src/services/ai/helpers.ts +64 -0
- package/backend/src/{core/ai/image.ts → services/ai/image-generation.service.ts} +17 -19
- package/backend/src/services/ai/index.ts +13 -0
- package/backend/src/services/auth/auth-config.service.ts +250 -0
- package/backend/src/services/auth/auth-otp.service.ts +424 -0
- package/backend/src/services/auth/auth.service.ts +1136 -0
- package/backend/src/services/auth/index.ts +4 -0
- package/backend/src/{core/auth/oauth.ts → services/auth/oauth-config.service.ts} +106 -52
- package/backend/src/{core/database/advance.ts → services/database/database-advance.service.ts} +97 -131
- package/backend/src/services/database/database-table.service.ts +811 -0
- package/backend/src/services/email/email.service.ts +75 -0
- package/backend/src/{core/functions/functions.ts → services/functions/function.service.ts} +95 -88
- package/backend/src/{core/logs/audit.ts → services/logs/audit.service.ts} +92 -75
- package/backend/src/services/logs/log.service.ts +73 -0
- package/backend/src/{core/secrets/secrets.ts → services/secrets/secret.service.ts} +48 -66
- package/backend/src/services/storage/storage.service.ts +617 -0
- package/backend/src/services/usage/usage.service.ts +149 -0
- package/backend/src/types/auth.ts +66 -2
- package/backend/src/types/email.ts +8 -0
- package/backend/src/types/error-constants.ts +4 -0
- package/backend/src/types/logs.ts +0 -29
- package/backend/src/{core/socket/types.ts → types/socket.ts} +5 -6
- package/backend/src/utils/environment.ts +9 -3
- package/backend/src/utils/logger.ts +20 -2
- package/backend/src/utils/seed.ts +150 -57
- package/backend/src/utils/sql-parser.ts +1 -1
- package/backend/src/utils/utils.ts +114 -0
- package/backend/src/utils/validations.ts +40 -4
- package/backend/tests/local/test-ai-config.sh +129 -0
- package/backend/tests/local/test-ai-usage.sh +80 -0
- package/backend/tests/local/test-auth-router.sh +1 -1
- package/backend/tests/local/test-e2e.sh +1 -1
- package/backend/tests/local/test-functions.sh +123 -0
- package/backend/tests/local/test-logs.sh +132 -0
- package/backend/tests/local/test-public-bucket.sh +3 -3
- package/backend/tests/local/test-secrets.sh +14 -12
- package/backend/tests/local/test-traditional-rest.sh +2 -2
- package/backend/tests/manual/test-rawsql-modes.sh +244 -0
- package/backend/tests/test-config.sh +37 -1
- package/backend/tests/unit/cloud-token.test.ts +48 -0
- package/backend/tests/unit/constant.test.ts +8 -0
- package/backend/tests/unit/email.test.ts +372 -0
- package/backend/tests/unit/environment.test.ts +59 -0
- package/backend/tests/unit/helpers.test.ts +63 -0
- package/backend/tests/unit/logger.test.ts +22 -0
- package/backend/tests/unit/rate-limit.test.ts +154 -0
- package/backend/tests/unit/response.test.ts +58 -0
- package/backend/tests/unit/sql-parser.test.ts +74 -0
- package/backend/tests/unit/uuid.test.ts +21 -0
- package/backend/tests/unit/validations.test.ts +80 -0
- package/backend/tsconfig.json +1 -1
- package/backend/vitest.config.ts +11 -0
- package/claude-plugin/.claude-plugin/plugin.json +24 -0
- package/claude-plugin/README.md +133 -0
- package/claude-plugin/skills/insforge-schema-patterns/SKILL.md +270 -0
- package/docker-compose.prod.yml +60 -4
- package/docker-compose.yml +65 -4
- package/docker-init/db/db-init.sql +6 -34
- package/docker-init/logs/vector.yml +236 -0
- package/docs/README.md +44 -0
- package/docs/changelog.mdx +67 -0
- package/docs/core-concepts/ai/architecture.mdx +373 -0
- package/docs/core-concepts/ai/sdk.mdx +213 -0
- package/docs/core-concepts/authentication/architecture.mdx +278 -0
- package/docs/core-concepts/authentication/sdk.mdx +414 -0
- package/docs/core-concepts/authentication/ui-components/customization.mdx +529 -0
- package/docs/core-concepts/authentication/ui-components/nextjs.mdx +221 -0
- package/docs/core-concepts/authentication/ui-components/react-router.mdx +184 -0
- package/docs/core-concepts/authentication/ui-components/react.mdx +129 -0
- package/docs/core-concepts/database/architecture.mdx +256 -0
- package/docs/core-concepts/database/sdk.mdx +382 -0
- package/docs/core-concepts/functions/architecture.mdx +105 -0
- package/docs/core-concepts/functions/sdk.mdx +184 -0
- package/docs/core-concepts/storage/architecture.mdx +243 -0
- package/docs/core-concepts/storage/sdk.mdx +253 -0
- package/docs/deployment/README.md +94 -0
- package/docs/deployment/deploy-to-aws-ec2.md +565 -0
- package/docs/deployment/deploy-to-azure-virtual-machines.md +313 -0
- package/docs/deployment/deploy-to-google-cloud-compute-engine.md +613 -0
- package/docs/deployment/deploy-to-render.md +441 -0
- package/docs/docs.json +210 -0
- package/docs/examples/framework-guides/nextjs.mdx +131 -0
- package/docs/examples/framework-guides/nuxt.mdx +165 -0
- package/docs/examples/framework-guides/react.mdx +165 -0
- package/docs/examples/framework-guides/svelte.mdx +153 -0
- package/docs/examples/framework-guides/vue.mdx +159 -0
- package/docs/examples/overview.mdx +67 -0
- package/docs/favicon.svg +19 -0
- package/docs/images/changelog/nov-2025/auth-components.webp +0 -0
- package/docs/images/changelog/nov-2025/database-metadata.webp +0 -0
- package/docs/images/changelog/nov-2025/quickstart-prompts.webp +0 -0
- package/docs/images/changelog/nov-2025/sql-editor.webp +0 -0
- package/docs/images/changelog/nov-2025/usage-page.webp +0 -0
- package/docs/images/changelog/october-2025/csv-upload.webp +0 -0
- package/docs/images/changelog/october-2025/logs-feature.webp +0 -0
- package/docs/images/changelog/october-2025/oauth-providers.webp +0 -0
- package/docs/images/checks-passed.png +0 -0
- package/docs/images/dashboard-connect-expanded.png +0 -0
- package/docs/images/dashboard-connect.png +0 -0
- package/docs/images/hero-dark.png +0 -0
- package/docs/images/hero-light.png +0 -0
- package/docs/images/icons/ai.svg +4 -0
- package/docs/images/icons/auth.svg +1 -0
- package/docs/images/icons/database.svg +1 -0
- package/docs/images/icons/function.svg +1 -0
- package/docs/images/icons/storage.svg +1 -0
- package/docs/images/logos/nextjs.svg +4 -0
- package/docs/images/logos/nuxt.svg +4 -0
- package/docs/images/logos/react.svg +5 -0
- package/docs/images/logos/svelte.svg +4 -0
- package/docs/images/logos/vue.svg +5 -0
- package/docs/images/mcp-install.png +0 -0
- package/docs/images/onboarding-mcp.png +0 -0
- package/docs/insforge-instructions-sdk.md +55 -374
- package/docs/introduction.mdx +45 -0
- package/docs/logo/dark.svg +22 -0
- package/docs/logo/light.svg +20 -0
- package/docs/partnership.mdx +647 -0
- package/docs/quickstart.mdx +83 -0
- package/docs/showcase/2048-arena.png +0 -0
- package/docs/showcase/framegen-cloud.png +0 -0
- package/docs/showcase/line-connect-race.png +0 -0
- package/docs/showcase/moment-vibe.png +0 -0
- package/docs/showcase/national-flags.png +0 -0
- package/docs/showcase/pokemon-vibe.png +0 -0
- package/docs/showcase/pure-browse-buy.png +0 -0
- package/docs/showcase.mdx +52 -0
- package/docs/snippets/sdk-installation.mdx +22 -0
- package/docs/snippets/service-icons.mdx +27 -0
- package/eslint.config.js +10 -3
- package/frontend/package.json +10 -4
- package/frontend/src/App.tsx +13 -82
- package/frontend/src/assets/icons/connected.svg +3 -0
- package/frontend/src/assets/icons/loader.svg +9 -0
- package/frontend/src/assets/logos/apple.svg +4 -0
- package/frontend/src/assets/logos/discord.svg +1 -1
- package/frontend/src/assets/logos/facebook.svg +3 -0
- package/frontend/src/assets/logos/instagram.svg +2 -0
- package/frontend/src/assets/logos/linkedin.svg +3 -0
- package/frontend/src/assets/logos/microsoft.svg +1 -0
- package/frontend/src/assets/logos/spotify.svg +17 -0
- package/frontend/src/assets/logos/tiktok.svg +6 -0
- package/frontend/src/assets/logos/x.svg +3 -0
- package/frontend/src/components/Checkbox.tsx +27 -29
- package/frontend/src/components/CodeBlock.tsx +55 -2
- package/frontend/src/components/CodeEditor.tsx +92 -0
- package/frontend/src/components/ConfirmDialog.tsx +1 -1
- package/frontend/src/components/ConnectCTA.tsx +38 -0
- package/frontend/src/components/CopyButton.tsx +52 -15
- package/frontend/src/components/ErrorState.tsx +1 -2
- package/frontend/src/components/FeatureSidebar.tsx +6 -6
- package/frontend/src/components/FeatureSidebarItem.tsx +2 -2
- package/frontend/src/components/JsonHighlight.tsx +21 -9
- package/frontend/src/components/ProjectInfoModal.tsx +128 -0
- package/frontend/src/components/PromptDialog.tsx +1 -4
- package/frontend/src/components/SearchInput.tsx +1 -2
- package/frontend/src/components/Stepper.tsx +53 -0
- package/frontend/src/components/ThemeToggle.tsx +3 -3
- package/frontend/src/components/datagrid/DataGrid.tsx +25 -32
- package/frontend/src/components/datagrid/cell-editors/DateCellEditor.tsx +1 -2
- package/frontend/src/components/datagrid/cell-editors/JsonCellEditor.tsx +2 -4
- package/frontend/src/components/datagrid/index.ts +23 -0
- package/frontend/src/components/index.ts +23 -30
- package/frontend/src/components/layout/AppHeader.tsx +133 -92
- package/frontend/src/components/layout/AppSidebar.tsx +80 -170
- package/frontend/src/components/layout/Layout.tsx +12 -23
- package/frontend/src/components/layout/PrimaryMenu.tsx +187 -0
- package/frontend/src/components/layout/SecondaryMenu.tsx +70 -0
- package/frontend/src/components/layout/index.ts +5 -0
- package/frontend/src/components/radix/Tooltip.tsx +24 -13
- package/frontend/src/components/radix/index.ts +22 -0
- package/frontend/src/features/ai/components/AIConfigCard.tsx +129 -83
- package/frontend/src/features/ai/components/AIEmptyState.tsx +12 -7
- package/frontend/src/features/ai/components/ModalityFilterSidebar.tsx +101 -0
- package/frontend/src/features/ai/components/ModelSelectionDialog.tsx +135 -0
- package/frontend/src/features/ai/components/ModelSelectionGrid.tsx +51 -0
- package/frontend/src/features/ai/components/SystemPromptDialog.tsx +118 -0
- package/frontend/src/features/ai/components/index.ts +6 -0
- package/frontend/src/features/ai/helpers.ts +57 -71
- package/frontend/src/features/ai/hooks/useAIConfigs.ts +39 -113
- package/frontend/src/features/ai/hooks/useAIUsage.ts +0 -2
- package/frontend/src/features/ai/page/AIPage.tsx +67 -79
- package/frontend/src/features/ai/services/ai.service.ts +5 -5
- package/frontend/src/features/auth/components/AuthPreview.tsx +96 -0
- package/frontend/src/features/auth/components/OAuthConfigDialog.tsx +53 -30
- package/frontend/src/features/auth/components/UserFormDialog.tsx +13 -6
- package/frontend/src/features/auth/components/UsersDataGrid.tsx +44 -14
- package/frontend/src/features/auth/components/index.ts +5 -0
- package/frontend/src/features/auth/helpers.tsx +200 -0
- package/frontend/src/features/auth/hooks/useAnonToken.ts +30 -0
- package/frontend/src/features/auth/hooks/useAuthConfig.ts +48 -0
- package/frontend/src/features/auth/hooks/useOAuthConfig.ts +14 -10
- package/frontend/src/features/auth/hooks/useUsers.ts +43 -5
- package/frontend/src/features/auth/index.ts +3 -2
- package/frontend/src/features/auth/page/AuthMethodsPage.tsx +275 -0
- package/frontend/src/features/auth/page/ConfigurationPage.tsx +395 -0
- package/frontend/src/features/auth/page/UsersPage.tsx +285 -0
- package/frontend/src/features/auth/services/anonToken.service.ts +11 -0
- package/frontend/src/features/auth/services/config.service.ts +19 -0
- package/frontend/src/features/auth/services/{oauth.service.ts → oauth-config.service.ts} +4 -4
- package/frontend/src/features/auth/services/{auth.service.ts → user.service.ts} +7 -53
- package/frontend/src/features/dashboard/components/ConnectionSuccessBanner.tsx +35 -0
- package/frontend/src/features/dashboard/components/PromptCard.tsx +21 -0
- package/frontend/src/features/dashboard/components/PromptDialog.tsx +103 -0
- package/frontend/src/features/dashboard/components/StatsCard.tsx +50 -0
- package/frontend/src/features/dashboard/components/index.ts +4 -0
- package/frontend/src/features/dashboard/page/DashboardPage.tsx +187 -169
- package/frontend/src/features/dashboard/prompts/ai-chatbot.ts +13 -0
- package/frontend/src/features/dashboard/prompts/crm-system.ts +13 -0
- package/frontend/src/features/dashboard/prompts/ecommerce-platform.ts +12 -0
- package/frontend/src/features/dashboard/prompts/index.ts +31 -0
- package/frontend/src/features/dashboard/prompts/instagram-clone.ts +11 -0
- package/frontend/src/features/dashboard/prompts/notion-clone.ts +14 -0
- package/frontend/src/features/dashboard/prompts/reddit-clone.ts +12 -0
- package/frontend/src/features/database/components/DatabaseDataGrid.tsx +48 -17
- package/frontend/src/features/database/components/ForeignKeyCell.tsx +15 -34
- package/frontend/src/features/database/components/ForeignKeyPopover.tsx +19 -20
- package/frontend/src/features/database/components/LinkRecordModal.tsx +120 -125
- package/frontend/src/features/database/components/RecordFormDialog.tsx +22 -33
- package/frontend/src/features/database/components/RecordFormField.tsx +45 -47
- package/frontend/src/features/database/components/TableEmptyState.tsx +6 -5
- package/frontend/src/features/database/components/TableForm.tsx +28 -15
- package/frontend/src/features/database/components/TableFormColumn.tsx +2 -3
- package/frontend/src/features/database/components/TableSidebar.tsx +1 -1
- package/frontend/src/features/database/components/TablesEmptyState.tsx +48 -0
- package/frontend/src/features/database/components/TemplateCard.tsx +37 -0
- package/frontend/src/features/database/components/TemplatePreview.tsx +92 -0
- package/frontend/src/features/database/components/index.ts +19 -0
- package/frontend/src/features/database/constants.ts +28 -2
- package/frontend/src/features/database/contexts/SQLEditorContext.tsx +188 -0
- package/frontend/src/features/database/helpers.ts +2 -2
- package/frontend/src/features/database/hooks/useCSVImport.ts +29 -0
- package/frontend/src/features/database/hooks/useFullMetadata.ts +18 -0
- package/frontend/src/features/database/hooks/useRawSQL.ts +55 -0
- package/frontend/src/features/database/hooks/useRecords.ts +139 -0
- package/frontend/src/features/database/hooks/useTables.ts +131 -0
- package/frontend/src/features/database/index.ts +6 -1
- package/frontend/src/features/database/page/FunctionsPage.tsx +211 -0
- package/frontend/src/features/database/page/IndexesPage.tsx +240 -0
- package/frontend/src/features/database/page/PoliciesPage.tsx +248 -0
- package/frontend/src/features/database/page/SQLEditorPage.tsx +382 -0
- package/frontend/src/features/database/page/{DatabasePage.tsx → TablesPage.tsx} +186 -185
- package/frontend/src/features/database/page/TemplatesPage.tsx +39 -0
- package/frontend/src/features/database/page/TriggersPage.tsx +242 -0
- package/frontend/src/features/database/services/advance.service.ts +66 -0
- package/frontend/src/features/database/services/{database.service.ts → record.service.ts} +67 -64
- package/frontend/src/features/database/services/table.service.ts +64 -0
- package/frontend/src/features/database/templates/ai-chatbot.ts +402 -0
- package/frontend/src/features/database/templates/crm-system.ts +528 -0
- package/frontend/src/features/database/templates/ecommerce-platform.ts +553 -0
- package/frontend/src/features/database/templates/index.ts +34 -0
- package/frontend/src/features/database/templates/instagram-clone.ts +222 -0
- package/frontend/src/features/database/templates/notion-clone.ts +483 -0
- package/frontend/src/features/database/templates/reddit-clone.ts +526 -0
- package/frontend/src/features/functions/components/FunctionRow.tsx +2 -1
- package/frontend/src/features/functions/components/FunctionsSidebar.tsx +1 -1
- package/frontend/src/features/functions/components/SecretRow.tsx +1 -1
- package/frontend/src/features/functions/components/index.ts +5 -0
- package/frontend/src/features/functions/hooks/useFunctions.ts +4 -4
- package/frontend/src/features/{secrets → functions}/hooks/useSecrets.ts +5 -5
- package/frontend/src/features/functions/page/FunctionsPage.tsx +160 -17
- package/frontend/src/features/functions/{components/SecretsContent.tsx → page/SecretsPage.tsx} +8 -12
- package/frontend/src/features/functions/services/{functions.service.ts → function.service.ts} +2 -2
- package/frontend/src/features/{secrets/services/secrets.service.ts → functions/services/secret.service.ts} +2 -2
- package/frontend/src/features/login/hooks/usePartnerOrigin.ts +27 -0
- package/frontend/src/features/login/page/CloudLoginPage.tsx +79 -54
- package/frontend/src/features/login/page/LoginPage.tsx +16 -23
- package/frontend/src/features/login/services/partnership.service.ts +65 -0
- package/frontend/src/features/logs/components/LogsDataGrid.tsx +89 -0
- package/frontend/src/features/logs/components/SeverityBadge.tsx +18 -0
- package/frontend/src/features/logs/components/index.ts +2 -0
- package/frontend/src/features/logs/helpers.ts +24 -0
- package/frontend/src/features/logs/hooks/useAuditLogs.ts +4 -4
- package/frontend/src/features/logs/hooks/useLogSources.ts +137 -0
- package/frontend/src/features/logs/hooks/useLogs.ts +163 -0
- package/frontend/src/features/logs/hooks/useMcpUsage.ts +181 -0
- package/frontend/src/features/logs/index.ts +8 -2
- package/frontend/src/features/logs/page/AuditsPage.tsx +91 -38
- package/frontend/src/features/logs/page/LogsPage.tsx +152 -0
- package/frontend/src/features/logs/page/MCPLogsPage.tsx +84 -0
- package/frontend/src/features/logs/services/audit.service.ts +63 -0
- package/frontend/src/features/logs/services/log.service.ts +15 -110
- package/frontend/src/features/logs/services/usage.service.ts +31 -0
- package/frontend/src/features/onboard/components/McpConnectionStatus.tsx +68 -0
- package/frontend/src/features/onboard/components/OnboardingModal.tsx +267 -0
- package/frontend/src/features/onboard/components/VideoDemoModal.tsx +38 -0
- package/frontend/src/features/onboard/components/index.ts +4 -0
- package/frontend/src/features/onboard/components/mcp/CursorDeeplinkGenerator.tsx +2 -2
- package/frontend/src/features/onboard/components/mcp/{mcp-helper.tsx → helpers.tsx} +8 -8
- package/frontend/src/features/onboard/components/mcp/index.ts +2 -3
- package/frontend/src/features/onboard/index.ts +13 -3
- package/frontend/src/features/storage/components/BucketEmptyState.tsx +9 -6
- package/frontend/src/features/storage/components/BucketFormDialog.tsx +25 -41
- package/frontend/src/features/storage/components/FilePreviewDialog.tsx +20 -8
- package/frontend/src/features/storage/components/StorageDataGrid.tsx +4 -3
- package/frontend/src/features/storage/components/StorageManager.tsx +23 -34
- package/frontend/src/features/storage/components/index.ts +12 -0
- package/frontend/src/features/storage/hooks/useStorage.ts +208 -0
- package/frontend/src/features/storage/page/StoragePage.tsx +41 -115
- package/frontend/src/features/storage/services/storage.service.ts +22 -1
- package/frontend/src/features/visualizer/components/AuthNode.tsx +72 -56
- package/frontend/src/features/visualizer/components/BucketNode.tsx +4 -4
- package/frontend/src/features/visualizer/components/SchemaVisualizer.tsx +108 -80
- package/frontend/src/features/visualizer/components/TableNode.tsx +34 -41
- package/frontend/src/features/visualizer/components/VisualizerSkeleton.tsx +12 -4
- package/frontend/src/features/visualizer/page/VisualizerPage.tsx +33 -29
- package/frontend/src/index.css +1 -0
- package/frontend/src/lib/analytics/posthog.tsx +27 -0
- package/frontend/src/lib/contexts/AuthContext.tsx +38 -31
- package/frontend/src/lib/contexts/SocketContext.tsx +5 -6
- package/frontend/src/{features/metadata → lib}/hooks/useMetadata.ts +1 -1
- package/frontend/src/lib/hooks/useToast.tsx +6 -2
- package/frontend/src/lib/routing/AppRoutes.tsx +84 -0
- package/frontend/src/lib/routing/RequireAuth.tsx +27 -0
- package/frontend/src/lib/utils/cloudMessaging.ts +20 -0
- package/frontend/src/lib/utils/menuItems.ts +183 -0
- package/frontend/src/lib/utils/{validation-schemas.ts → schemaValidations.ts} +10 -5
- package/frontend/src/lib/utils/utils.ts +19 -1
- package/frontend/src/vite-env.d.ts +1 -0
- package/frontend/vite.config.ts +5 -3
- package/functions/server.ts +28 -3
- package/functions/worker-template.js +15 -4
- package/i18n/README.ar.md +130 -0
- package/i18n/README.de.md +130 -0
- package/i18n/README.es.md +154 -0
- package/i18n/README.fr.md +134 -0
- package/i18n/README.hi.md +129 -0
- package/i18n/README.ja.md +174 -0
- package/i18n/README.ko.md +137 -0
- package/i18n/README.pt-BR.md +131 -0
- package/i18n/README.ru.md +129 -0
- package/i18n/README.zh-CN.md +133 -0
- package/openapi/ai.yaml +31 -4
- package/openapi/auth.yaml +827 -146
- package/package.json +16 -7
- package/shared-schemas/package.json +1 -1
- package/shared-schemas/src/ai-api.schema.ts +34 -58
- package/shared-schemas/src/ai.schema.ts +5 -0
- package/shared-schemas/src/auth-api.schema.ts +154 -8
- package/shared-schemas/src/auth.schema.ts +42 -6
- package/shared-schemas/src/cloud-events.schema.ts +57 -0
- package/shared-schemas/src/database-api.schema.ts +3 -3
- package/shared-schemas/src/database.schema.ts +1 -1
- package/shared-schemas/src/index.ts +1 -0
- package/shared-schemas/src/logs-api.schema.ts +7 -1
- package/shared-schemas/src/logs.schema.ts +26 -0
- package/shared-schemas/src/metadata.schema.ts +9 -4
- package/test-gemini.sh +35 -0
- package/test-usage-admin.sh +57 -0
- package/test-usage.sh +50 -0
- package/zeabur/README.md +13 -0
- package/zeabur/template.yml +1032 -0
- package/.github/workflows/deploy-aws.yml +0 -130
- package/backend/src/api/routes/agent.ts +0 -29
- package/backend/src/api/routes/auth.oauth.ts +0 -482
- package/backend/src/api/routes/auth.ts +0 -386
- package/backend/src/api/routes/docs.ts +0 -66
- package/backend/src/api/routes/functions.ts +0 -183
- package/backend/src/api/routes/openapi.ts +0 -82
- package/backend/src/api/routes/usage.ts +0 -96
- package/backend/src/core/ai/client.ts +0 -242
- package/backend/src/core/ai/model.ts +0 -117
- package/backend/src/core/auth/auth.ts +0 -781
- package/backend/src/core/database/table.ts +0 -772
- package/backend/src/core/documentation/agent.ts +0 -689
- package/backend/src/core/documentation/openapi.ts +0 -856
- package/backend/src/core/logs/analytics.ts +0 -76
- package/backend/src/core/logs/providers/localdb.provider.ts +0 -246
- package/backend/src/core/storage/storage.ts +0 -923
- package/backend/src/utils/cloud-token.ts +0 -39
- package/backend/src/utils/helpers.ts +0 -49
- package/backend/src/utils/uuid.ts +0 -9
- package/backend/tests/manual/test-better-auth.sh +0 -303
- package/docker-init/db/logs.sql +0 -9
- package/frontend/README.md +0 -112
- package/frontend/src/components/datagrid/index.tsx +0 -20
- package/frontend/src/components/layout/CloudLayout.tsx +0 -95
- package/frontend/src/features/ai/components/AIConfigDialog.tsx +0 -76
- package/frontend/src/features/ai/components/AIConfigForm.tsx +0 -222
- package/frontend/src/features/ai/components/fields/ModalityField.tsx +0 -87
- package/frontend/src/features/ai/components/fields/ModelSelectionField.tsx +0 -134
- package/frontend/src/features/ai/components/fields/SystemPromptField.tsx +0 -33
- package/frontend/src/features/auth/components/AddOAuthDialog.tsx +0 -106
- package/frontend/src/features/auth/components/AuthMethodTab.tsx +0 -238
- package/frontend/src/features/auth/components/UsersTab.tsx +0 -114
- package/frontend/src/features/auth/page/AuthenticationPage.tsx +0 -169
- package/frontend/src/features/database/hooks/UseLinkModal.tsx +0 -78
- package/frontend/src/features/functions/components/FunctionViewer.tsx +0 -46
- package/frontend/src/features/functions/components/FunctionsContent.tsx +0 -88
- package/frontend/src/features/login/components/AuthErrorBoundary.tsx +0 -87
- package/frontend/src/features/login/components/PrivateRoute.tsx +0 -24
- package/frontend/src/features/logs/components/AnalyticsLogsTable.tsx +0 -313
- package/frontend/src/features/logs/components/LogsTable.tsx +0 -199
- package/frontend/src/features/logs/page/AnalyticsLogsPage.tsx +0 -530
- package/frontend/src/features/metadata/index.ts +0 -0
- package/frontend/src/features/metadata/page/MetadataPage.tsx +0 -136
- package/frontend/src/features/onboard/components/CompletionCard.tsx +0 -41
- package/frontend/src/features/onboard/components/OnboardButton.tsx +0 -84
- package/frontend/src/features/onboard/components/StepContent.tsx +0 -91
- package/frontend/src/features/onboard/components/TestConnectionStep.tsx +0 -53
- package/frontend/src/features/onboard/components/mcp/McpInstallation.tsx +0 -144
- package/frontend/src/features/onboard/page/OnBoardPage.tsx +0 -104
- package/frontend/src/features/onboard/types.ts +0 -8
- package/frontend/src/lib/contexts/OnboardStepContext.tsx +0 -68
- package/frontend/src/lib/hooks/useOnboardingCompletion.ts +0 -29
- /package/backend/src/api/{middleware → middlewares}/error.ts +0 -0
- /package/backend/src/api/{middleware → middlewares}/upload.ts +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/000_create-base-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/001_create-helper-functions.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/002_rename-auth-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/003_create-users-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/004_add-reload-postgrest-func.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/005_enable-project-admin-modify-users.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/006_modify-ai-usage-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/007_drop-metadata-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/008_add-system-tables.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/009_add-function-secrets.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/010_modify-ai-config-modalities.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/011_refactor-secrets-table.sql +0 -0
- /package/backend/{migrations → src/infra/database/migrations}/012_add-storage-uploaded-by.sql +0 -0
- /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'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'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
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
|
-
import { createMCPServerConfig, type PlatformType } from './
|
|
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
|
|
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: '
|
|
41
|
-
displayName: '
|
|
42
|
-
logo: <
|
|
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 './
|
|
4
|
-
export { MCP_AGENTS, createMCPConfig, createMCPServerConfig } from './
|
|
2
|
+
export type { MCPAgent, PlatformType } from './helpers';
|
|
3
|
+
export { MCP_AGENTS, createMCPConfig, createMCPServerConfig } from './helpers';
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
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-
|
|
10
|
-
<Folder className="h-10 w-10 text-gray-400 dark:text-
|
|
11
|
-
<p className="text-sm text-gray-600 dark:text-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 {
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
4
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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');
|