├── worker ├── agents │ ├── services │ │ ├── interfaces │ │ │ ├── IAnalysisManager.ts │ │ │ ├── IServiceOptions.ts │ │ │ ├── IStateManager.ts │ │ │ └── IFileManager.ts │ │ └── implementations │ │ │ └── StateManager.ts │ ├── git │ │ └── index.ts │ ├── utils │ │ ├── idGenerator.ts │ │ ├── operationError.ts │ │ └── codeSerializers.ts │ ├── output-formats │ │ └── diff-formats │ │ │ └── index.ts │ ├── assistants │ │ └── assistant.ts │ ├── tools │ │ ├── types.ts │ │ └── toolkit │ │ │ ├── run-analysis.ts │ │ │ ├── queue-request.ts │ │ │ ├── wait-for-debug.ts │ │ │ ├── wait-for-generation.ts │ │ │ ├── wait.ts │ │ │ ├── rename-project.ts │ │ │ ├── regenerate-file.ts │ │ │ ├── deploy-preview.ts │ │ │ ├── read-files.ts │ │ │ └── exec-commands.ts │ ├── core │ │ ├── smartGeneratorAgent.ts │ │ ├── state.ts │ │ └── types.ts │ ├── domain │ │ └── pure │ │ │ └── DependencyManagement.ts │ └── operations │ │ └── common.ts ├── services │ ├── github │ │ └── index.ts │ ├── rate-limit │ │ └── errors.ts │ ├── sandbox │ │ ├── factory.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── cache │ │ ├── KVCache.ts │ │ └── wrapper.ts │ └── oauth │ │ └── github-exporter.ts ├── api │ ├── controllers │ │ ├── status │ │ │ ├── types.ts │ │ │ └── controller.ts │ │ ├── stats │ │ │ └── types.ts │ │ ├── user │ │ │ └── types.ts │ │ ├── analytics │ │ │ └── types.ts │ │ ├── types.ts │ │ ├── agent │ │ │ └── types.ts │ │ ├── secrets │ │ │ └── types.ts │ │ ├── appView │ │ │ └── types.ts │ │ ├── apps │ │ │ └── types.ts │ │ ├── modelProviders │ │ │ └── types.ts │ │ └── modelConfig │ │ │ └── types.ts │ ├── routes │ │ ├── statusRoutes.ts │ │ ├── sentryRoutes.ts │ │ ├── statsRoutes.ts │ │ ├── userRoutes.ts │ │ ├── analyticsRoutes.ts │ │ ├── imagesRoutes.ts │ │ ├── githubExporterRoutes.ts │ │ ├── modelProviderRoutes.ts │ │ ├── secretsRoutes.ts │ │ ├── codegenRoutes.ts │ │ ├── index.ts │ │ └── modelConfigRoutes.ts │ ├── honoAdapter.ts │ ├── types │ │ └── route-context.ts │ └── responses.ts ├── utils │ ├── envs.ts │ ├── idGenerator.ts │ ├── deployToCf.ts │ ├── dispatcherUtils.ts │ ├── timeFormatter.ts │ ├── urls.ts │ └── githubUtils.ts ├── types │ ├── appenv.ts │ └── image-attachment.ts ├── database │ ├── index.ts │ └── services │ │ └── BaseService.ts ├── middleware │ ├── security │ │ └── websocket.ts │ └── auth │ │ └── auth.ts └── logger │ └── types.ts ├── migrations ├── 0001_married_moondragon.sql ├── 0003_bumpy_albert_cleary.sql ├── meta │ └── _journal.json └── 0002_nebulous_fantastic_four.sql ├── public ├── favicon.ico └── vite.svg ├── src ├── vite-env.d.ts ├── assets │ ├── fonts │ │ └── DepartureMono-Regular.woff │ └── provider-logos │ │ ├── anthropic.svg │ │ ├── google.svg │ │ ├── cloudflare.svg │ │ └── openai.svg ├── components │ ├── ui │ │ ├── aspect-ratio.tsx │ │ ├── skeleton.tsx │ │ ├── sonner.tsx │ │ ├── label.tsx │ │ ├── separator.tsx │ │ ├── textarea.tsx │ │ ├── progress.tsx │ │ ├── collapsible.tsx │ │ ├── input.tsx │ │ ├── switch.tsx │ │ ├── avatar.tsx │ │ ├── checkbox.tsx │ │ ├── radio-group.tsx │ │ ├── hover-card.tsx │ │ ├── toggle.tsx │ │ ├── badge.tsx │ │ ├── popover.tsx │ │ ├── alert.tsx │ │ ├── scroll-area.tsx │ │ ├── tooltip.tsx │ │ ├── card.tsx │ │ ├── tabs.tsx │ │ ├── resizable.tsx │ │ ├── toggle-group.tsx │ │ └── slider.tsx │ ├── monaco-editor │ │ └── monaco-editor.module.css │ ├── primitives │ │ └── button.tsx │ ├── header.tsx │ ├── agent-mode-display.tsx │ ├── layout │ │ └── app-layout.tsx │ ├── theme-toggle.tsx │ ├── shared │ │ ├── TimePeriodSelector.tsx │ │ └── AppFiltersForm.tsx │ ├── image-upload-button.tsx │ ├── analytics │ │ └── cost-display.tsx │ ├── image-attachment-preview.tsx │ └── ErrorBoundary.tsx ├── utils │ ├── id-generator.ts │ ├── string.ts │ └── logger.ts ├── hooks │ ├── use-mobile.ts │ ├── useSentryUser.ts │ ├── use-app.ts │ ├── use-infinite-scroll.ts │ ├── use-platform-status.ts │ ├── use-auto-scroll.ts │ └── use-stats.ts ├── lib │ ├── utils.ts │ └── app-events.ts ├── routes │ ├── chat │ │ ├── utils │ │ │ ├── websocket-helpers.ts │ │ │ └── project-stage-helpers.ts │ │ └── components │ │ │ └── copy.tsx │ └── protected-route.tsx ├── main.tsx ├── App.tsx ├── routes.ts └── contexts │ └── theme-context.tsx ├── .editorconfig ├── .husky ├── pre-commit └── commit-msg ├── tsconfig.json ├── tsconfig.worker.json ├── components.json ├── container ├── package.json ├── bun-sqlite.d.ts └── example-usage.sh ├── vitest.config.ts ├── .github ├── workflows │ ├── ci.yml │ └── pr-labeler.yml └── labeler.yml ├── index.html ├── .gitignore ├── tsconfig.node.json ├── drizzle.config.local.ts ├── drizzle.config.remote.ts ├── tsconfig.app.json ├── LICENSE ├── commitlint.config.js ├── .dev.vars.example ├── eslint.config.js ├── shared └── types │ └── errors.ts ├── vite.config.ts ├── knip.json └── docs └── v1dev-environment.postman_environment.json /worker/agents/services/interfaces/IAnalysisManager.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /migrations/0001_married_moondragon.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE `apps` DROP COLUMN `blueprint`; -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/vibesdk/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /src/assets/fonts/DepartureMono-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/vibesdk/HEAD/src/assets/fonts/DepartureMono-Regular.woff -------------------------------------------------------------------------------- /worker/services/github/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub Service Module Exports 3 | */ 4 | 5 | export { GitHubService } from './GitHubService'; 6 | export * from './types'; -------------------------------------------------------------------------------- /worker/api/controllers/status/types.ts: -------------------------------------------------------------------------------- 1 | export interface PlatformStatusData { 2 | globalUserMessage: string; 3 | changeLogs: string; 4 | hasActiveMessage: boolean; 5 | } 6 | -------------------------------------------------------------------------------- /migrations/0003_bumpy_albert_cleary.sql: -------------------------------------------------------------------------------- 1 | CREATE INDEX `app_views_app_viewed_at_idx` ON `app_views` (`app_id`,`viewed_at`);--> statement-breakpoint 2 | CREATE INDEX `stars_app_starred_at_idx` ON `stars` (`app_id`,`starred_at`); -------------------------------------------------------------------------------- /worker/services/rate-limit/errors.ts: -------------------------------------------------------------------------------- 1 | import { RateLimitType } from "./config"; 2 | export interface RateLimitError { 3 | message: string; 4 | limitType: RateLimitType; 5 | limit?: number; 6 | period?: number; // seconds 7 | suggestions?: string[]; 8 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = tab 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.{yml,yaml}] 15 | indent_size = 4 -------------------------------------------------------------------------------- /worker/utils/envs.ts: -------------------------------------------------------------------------------- 1 | export function isProd(env: Env) { 2 | return env.ENVIRONMENT === 'prod' || env.ENVIRONMENT === 'production'; 3 | } 4 | 5 | export function isDev(env: Env) { 6 | return env.ENVIRONMENT === 'dev' || env.ENVIRONMENT === 'development' || env.ENVIRONMENT === 'local'; 7 | } 8 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | # Add common bun installation paths to PATH 2 | export PATH="/opt/homebrew/bin:$HOME/.bun/bin:$PATH" 3 | 4 | # Run tests with bun 5 | if command -v bun >/dev/null 2>&1; then 6 | bun test 7 | else 8 | echo "⚠️ bun not found in PATH, skipping tests" 9 | exit 0 10 | fi 11 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | # Add common bun installation paths to PATH 2 | export PATH="/opt/homebrew/bin:$HOME/.bun/bin:$PATH" 3 | 4 | # Run commitlint if bunx is available 5 | if command -v bunx >/dev/null 2>&1; then 6 | bunx commitlint --edit $1 7 | else 8 | echo "⚠️ bunx not found in PATH, skipping commitlint" 9 | exit 0 10 | fi 11 | -------------------------------------------------------------------------------- /src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 2 | 3 | function AspectRatio({ 4 | ...props 5 | }: React.ComponentProps) { 6 | return 7 | } 8 | 9 | export { AspectRatio } 10 | -------------------------------------------------------------------------------- /src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ className, ...props }: React.ComponentProps<"div">) { 4 | return ( 5 |
10 | ) 11 | } 12 | 13 | export { Skeleton } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.app.json" 6 | }, 7 | { 8 | "path": "./tsconfig.node.json" 9 | }, 10 | { 11 | "path": "./tsconfig.worker.json" 12 | } 13 | ], 14 | "compilerOptions": { 15 | "composite": true, 16 | "types": [ 17 | "./worker-configuration.d.ts" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /worker/utils/idGenerator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ID Generation Utility 3 | * Simple wrapper around crypto.randomUUID() for consistent ID generation 4 | */ 5 | 6 | import { nanoid } from "nanoid"; 7 | 8 | export function generateId(): string { 9 | return crypto.randomUUID(); 10 | } 11 | 12 | export function generateNanoId(): string { 13 | return nanoid(); 14 | } -------------------------------------------------------------------------------- /src/utils/id-generator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * ID Generation Utility for Frontend 3 | * Simple wrapper around crypto.randomUUID() for consistent ID generation 4 | */ 5 | 6 | export function generateId(): string { 7 | return crypto.randomUUID(); 8 | } 9 | 10 | export function generateShortId(): string { 11 | return crypto.randomUUID().replace(/-/g, '').substring(0, 16); 12 | } -------------------------------------------------------------------------------- /tsconfig.worker.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.node.json", 3 | "compilerOptions": { 4 | "composite": true, 5 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.worker.tsbuildinfo", 6 | "types": ["@cloudflare/workers-types", "./worker-configuration.d.ts", "vite/client", "jest"], 7 | "lib": ["ES2023"] 8 | }, 9 | "include": ["./worker-configuration.d.ts", "./shared", "./worker", "./worker/types"] 10 | } 11 | -------------------------------------------------------------------------------- /worker/agents/git/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Git version control for Durable Objects 3 | */ 4 | 5 | export { GitVersionControl } from './git'; 6 | export { GitCloneService } from './git-clone-service'; 7 | export { MemFS } from './memfs'; 8 | export { SqliteFS } from './fs-adapter'; 9 | export type { CommitInfo } from './git'; 10 | export type { SqlExecutor } from './fs-adapter'; 11 | export type { RepositoryBuildOptions } from './git-clone-service'; -------------------------------------------------------------------------------- /worker/api/controllers/stats/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Type definitions for Stats Controller responses 3 | */ 4 | 5 | import { UserStats, UserActivity } from '../../../database/types'; 6 | 7 | /** 8 | * Response data for getUserStats - uses UserStats directly 9 | */ 10 | export type UserStatsData = UserStats; 11 | 12 | /** 13 | * Response data for getUserActivity 14 | */ 15 | export interface UserActivityData { 16 | activities: UserActivity[]; 17 | } -------------------------------------------------------------------------------- /worker/types/appenv.ts: -------------------------------------------------------------------------------- 1 | import { GlobalConfigurableSettings } from "../config"; 2 | import { AuthRequirement } from "../middleware/auth/routeAuth"; 3 | import { AuthUser } from "./auth-types"; 4 | 5 | 6 | export type AppEnv = { 7 | Bindings: Env; 8 | Variables: { 9 | user: AuthUser | null; 10 | sessionId: string | null; 11 | config: GlobalConfigurableSettings; 12 | authLevel: AuthRequirement; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /worker/agents/services/interfaces/IServiceOptions.ts: -------------------------------------------------------------------------------- 1 | import { IStateManager } from './IStateManager'; 2 | import { IFileManager } from './IFileManager'; 3 | import { StructuredLogger } from '../../../logger'; 4 | 5 | /** 6 | * Common options for all agent services 7 | */ 8 | export interface ServiceOptions { 9 | env: Env, 10 | stateManager: IStateManager; 11 | fileManager: IFileManager; 12 | getLogger: () => StructuredLogger; 13 | } 14 | -------------------------------------------------------------------------------- /worker/api/controllers/user/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Type definitions for User Controller responses 3 | */ 4 | 5 | import { EnhancedAppData, PaginationInfo } from '../../../database/types'; 6 | 7 | /** 8 | * Response data for getApps 9 | */ 10 | export interface UserAppsData { 11 | apps: EnhancedAppData[]; 12 | pagination: PaginationInfo; 13 | } 14 | 15 | /** 16 | * Response data for updateProfile 17 | */ 18 | export interface ProfileUpdateData { 19 | success: boolean; 20 | message: string; 21 | } -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "", 8 | "css": "src/index.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /src/components/monaco-editor/monaco-editor.module.css: -------------------------------------------------------------------------------- 1 | :global(.diffDelete) { 2 | background-color: rgba(255, 0, 0, 0.2); 3 | text-decoration: line-through; 4 | opacity: 0.7; 5 | } 6 | 7 | :global(.dark .diffDelete) { 8 | background-color: rgba(255, 100, 100, 0.15); 9 | } 10 | 11 | :global(.diffInsert) { 12 | background-color: rgba(0, 255, 0, 0.2); 13 | margin-left: 4px; 14 | padding: 1px 4px; 15 | border-radius: 2px; 16 | } 17 | 18 | :global(.dark .diffInsert) { 19 | background-color: rgba(100, 255, 100, 0.15); 20 | } 21 | -------------------------------------------------------------------------------- /worker/api/controllers/analytics/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Analytics Controller Types 3 | * Type definitions for analytics controller requests and responses 4 | */ 5 | 6 | import { 7 | UserAnalyticsData, 8 | ChatAnalyticsData, 9 | } from '../../../services/analytics/types'; 10 | 11 | /** 12 | * User analytics response data 13 | */ 14 | export interface UserAnalyticsResponseData extends UserAnalyticsData {} 15 | 16 | /** 17 | * Agent analytics response data 18 | */ 19 | export interface AgentAnalyticsResponseData extends ChatAnalyticsData {} 20 | -------------------------------------------------------------------------------- /worker/utils/deployToCf.ts: -------------------------------------------------------------------------------- 1 | export function prepareCloudflareButton(repositoryUrl: string, format: 'markdown' | 'html' | 'url'): string { 2 | const url = `https://deploy.workers.cloudflare.com/?url=${repositoryUrl}`; 3 | if (format === 'markdown') { 4 | return `[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](${url})`; 5 | } else if (format === 'html') { 6 | return `Deploy to Cloudflare`; 7 | } else { 8 | return url; 9 | } 10 | } -------------------------------------------------------------------------------- /src/assets/provider-logos/anthropic.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /worker/api/controllers/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Base Controller Types 3 | */ 4 | 5 | import { BaseApiResponse } from "../responses"; 6 | 7 | 8 | /** 9 | * Typed response wrapper for controller methods 10 | * Ensures controller responses match their expected interface types 11 | */ 12 | export type ControllerResponse = Response & { 13 | __typedData: T; // Phantom type for compile-time checking 14 | }; 15 | 16 | /** 17 | * Type-safe API response interface that ensures data is properly typed 18 | */ 19 | export interface ApiResponse extends BaseApiResponse {} -------------------------------------------------------------------------------- /src/assets/provider-logos/google.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /worker/api/routes/statusRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from 'hono'; 2 | import { StatusController } from '../controllers/status/controller'; 3 | import { adaptController } from '../honoAdapter'; 4 | import { AppEnv } from '../../types/appenv'; 5 | import { AuthConfig, setAuthLevel } from '../../middleware/auth/routeAuth'; 6 | 7 | export function setupStatusRoutes(app: Hono): void { 8 | const statusRouter = new Hono(); 9 | 10 | statusRouter.get('/', setAuthLevel(AuthConfig.public), adaptController(StatusController, StatusController.getPlatformStatus)); 11 | 12 | app.route('/api/status', statusRouter); 13 | } 14 | -------------------------------------------------------------------------------- /worker/agents/utils/idGenerator.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility functions for generating unique IDs 3 | */ 4 | export class IdGenerator { 5 | /** 6 | * Generate a unique conversation ID 7 | * Format: conv-{timestamp}-{random} 8 | */ 9 | static generateConversationId(): string { 10 | return `conv-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; 11 | } 12 | 13 | /** 14 | * Generate a generic unique ID with custom prefix 15 | */ 16 | static generateId(prefix: string = 'id'): string { 17 | return `${prefix}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; 18 | } 19 | } -------------------------------------------------------------------------------- /worker/utils/dispatcherUtils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Dispatcher Utility Functions 3 | * 4 | * Shared utilities for checking dispatch namespace availability and handling 5 | * Workers for Platforms functionality across the application. 6 | */ 7 | 8 | export function isDispatcherAvailable(env: Env): boolean { 9 | // Check if DISPATCHER binding exists in the environment 10 | // This will be false if dispatch_namespaces is commented out in wrangler.jsonc 11 | // or if Workers for Platforms is not enabled for the account (as binding would be removed by the deploy.ts script) 12 | return 'DISPATCHER' in env && env.DISPATCHER != null; 13 | } -------------------------------------------------------------------------------- /container/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "process-monitoring-system", 3 | "version": "2.0.0", 4 | "description": "Unified process monitoring system for Cloudflare sandbox containers", 5 | "main": "cli-tools.ts", 6 | "scripts": { 7 | "build": "bun build cli-tools.ts --outdir ./dist --target bun", 8 | "start": "bun run cli-tools.ts process start", 9 | "monitor": "bun run cli-tools.ts", 10 | "errors": "bun run cli-tools.ts errors", 11 | "logs": "bun run cli-tools.ts logs", 12 | "test": "bun test", 13 | "clean": "rm -f ./data/*.db" 14 | }, 15 | "dependencies": { 16 | "zod": "^3.22.4" 17 | }, 18 | "type": "module" 19 | } -------------------------------------------------------------------------------- /src/hooks/use-mobile.ts: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | const MOBILE_BREAKPOINT = 768 4 | 5 | export function useIsMobile() { 6 | const [isMobile, setIsMobile] = React.useState(undefined) 7 | 8 | React.useEffect(() => { 9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) 10 | const onChange = () => { 11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 12 | } 13 | mql.addEventListener("change", onChange) 14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) 15 | return () => mql.removeEventListener("change", onChange) 16 | }, []) 17 | 18 | return !!isMobile 19 | } 20 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'; 2 | 3 | export default defineWorkersConfig({ 4 | test: { 5 | poolOptions: { 6 | workers: { 7 | wrangler: { configPath: './wrangler.test.jsonc' }, 8 | miniflare: { 9 | compatibilityDate: '2024-12-12', 10 | compatibilityFlags: ['nodejs_compat'], 11 | }, 12 | }, 13 | }, 14 | globals: true, 15 | setupFiles: ['./test/setup.ts'], 16 | include: ['**/*.{test,spec}.{js,ts,jsx,tsx}'], 17 | exclude: ['**/node_modules/**', '**/dist/**', '**/.git/**', '**/test/**', '**/worker/api/routes/**'], 18 | }, 19 | }); -------------------------------------------------------------------------------- /src/components/primitives/button.tsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | 3 | type ButtonProps = React.ComponentProps<'button'> & { 4 | variant?: 'primary' | 'secondary'; 5 | }; 6 | 7 | export function Button({ 8 | variant = 'secondary', 9 | children, 10 | className, 11 | ...props 12 | }: ButtonProps) { 13 | return ( 14 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /src/components/ui/sonner.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from "next-themes" 2 | import { Toaster as Sonner, type ToasterProps } from "sonner" 3 | 4 | const Toaster = ({ ...props }: ToasterProps) => { 5 | const { theme = "system" } = useTheme() 6 | 7 | return ( 8 | 20 | ) 21 | } 22 | 23 | export { Toaster } 24 | -------------------------------------------------------------------------------- /worker/api/controllers/agent/types.ts: -------------------------------------------------------------------------------- 1 | import { PreviewType } from "../../../services/sandbox/sandboxTypes"; 2 | import type { ImageAttachment } from '../../../types/image-attachment'; 3 | 4 | export interface CodeGenArgs { 5 | query: string; 6 | language?: string; 7 | frameworks?: string[]; 8 | selectedTemplate?: string; 9 | agentMode: 'deterministic' | 'smart'; 10 | images?: ImageAttachment[]; 11 | } 12 | 13 | /** 14 | * Data structure for connectToExistingAgent response 15 | */ 16 | export interface AgentConnectionData { 17 | websocketUrl: string; 18 | agentId: string; 19 | } 20 | 21 | export interface AgentPreviewResponse extends PreviewType { 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ "**" ] # Run on all branches 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Setup Bun 18 | uses: oven-sh/setup-bun@v1 19 | with: 20 | bun-version: latest 21 | 22 | - name: Install dependencies 23 | run: bun install --frozen-lockfile 24 | 25 | - name: Run build 26 | run: bun run build 27 | 28 | # - name: Run linter 29 | # run: bun run lint 30 | 31 | # - name: Run tests 32 | # run: bun run test 33 | -------------------------------------------------------------------------------- /src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | function Label({ 7 | className, 8 | ...props 9 | }: React.ComponentProps) { 10 | return ( 11 | 19 | ) 20 | } 21 | 22 | export { Label } 23 | -------------------------------------------------------------------------------- /worker/services/sandbox/factory.ts: -------------------------------------------------------------------------------- 1 | import { SandboxSdkClient } from "./sandboxSdkClient"; 2 | import { RemoteSandboxServiceClient } from "./remoteSandboxService"; 3 | import { BaseSandboxService } from "./BaseSandboxService"; 4 | import { env } from 'cloudflare:workers' 5 | 6 | export function getSandboxService(sessionId: string, agentId: string): BaseSandboxService { 7 | if (env.SANDBOX_SERVICE_TYPE == 'runner') { 8 | console.log("[getSandboxService] Using runner service for sandboxing"); 9 | return new RemoteSandboxServiceClient(sessionId); 10 | } 11 | console.log("[getSandboxService] Using sandboxsdk service for sandboxing"); 12 | return new SandboxSdkClient(sessionId, agentId); 13 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Build 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | 8 | export function getPreviewUrl(previewURL?: string, tunnelURL?: string): string { 9 | // return import.meta.env.VITE_PREVIEW_MODE === 'tunnel' ? tunnelURL || previewURL || '' : previewURL || tunnelURL || ''; 10 | return previewURL || tunnelURL || ''; 11 | } 12 | 13 | export function capitalizeFirstLetter(str: string) { 14 | if (typeof str !== 'string' || str.length === 0) { 15 | return str; // Handle non-string input or empty string 16 | } 17 | return str.charAt(0).toUpperCase() + str.slice(1); 18 | } -------------------------------------------------------------------------------- /worker/database/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Database Services Export Index 3 | * Centralized exports for all database services and utilities 4 | */ 5 | 6 | // Core database service and utilities 7 | export { DatabaseService, createDatabaseService } from './database'; 8 | 9 | // Domain-specific services 10 | export { AnalyticsService } from './services/AnalyticsService'; 11 | export { BaseService } from './services/BaseService'; 12 | export { UserService } from './services/UserService'; 13 | export { AppService } from './services/AppService'; 14 | export { SecretsService } from './services/SecretsService'; 15 | export { ModelConfigService } from './services/ModelConfigService'; 16 | export { ModelTestService } from './services/ModelTestService'; -------------------------------------------------------------------------------- /worker/agents/services/interfaces/IStateManager.ts: -------------------------------------------------------------------------------- 1 | import { CodeGenState } from '../../core/state'; 2 | 3 | /** 4 | * Interface for state management 5 | * Abstracts state persistence and updates 6 | */ 7 | export interface IStateManager { 8 | /** 9 | * Get current state 10 | */ 11 | getState(): Readonly; 12 | 13 | /** 14 | * Update state immutably 15 | */ 16 | setState(newState: CodeGenState): void; 17 | 18 | /** 19 | * Update specific field 20 | */ 21 | updateField(field: K, value: CodeGenState[K]): void; 22 | 23 | /** 24 | * Batch update multiple fields 25 | */ 26 | batchUpdate(updates: Partial): void; 27 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log* 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | .tmp 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | 27 | # wrangler files 28 | .wrangler 29 | .dev.vars* 30 | .prod.vars 31 | .env 32 | .env.* 33 | 34 | runner/downloads 35 | /generated/prisma 36 | 37 | /generated/prisma 38 | test.ts 39 | temp/ 40 | 41 | templates 42 | debugging.ipynb 43 | 44 | #bun.lock 45 | #*.lock 46 | 47 | debug-tools/*.json 48 | # Sentry Config File 49 | .env.sentry-build-plugin 50 | data-dump 51 | debug-tools/extracted -------------------------------------------------------------------------------- /container/bun-sqlite.d.ts: -------------------------------------------------------------------------------- 1 | // Type declarations for Bun's built-in SQLite module 2 | declare module 'bun:sqlite' { 3 | export interface Statement { 4 | all(...params: Params): T[]; 5 | get(...params: Params): T | null; 6 | run(...params: Params): { changes: number }; 7 | } 8 | 9 | export class Database { 10 | constructor(filename: string); 11 | 12 | query(sql: string): Statement; 13 | prepare(sql: string): Statement; 14 | exec(sql: string): void; 15 | close(): void; 16 | transaction(fn: (...args: TArgs) => TResult): (...args: TArgs) => TResult; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /worker/api/routes/sentryRoutes.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from 'hono'; 2 | import { SentryTunnelController } from '../controllers/sentry/tunnelController'; 3 | import { AppEnv } from '../../types/appenv'; 4 | import { adaptController } from '../honoAdapter'; 5 | import { AuthConfig, setAuthLevel } from '../../middleware/auth/routeAuth'; 6 | 7 | export function setupSentryRoutes(app: Hono): void { 8 | const sentryRouter = new Hono(); 9 | 10 | // Sentry tunnel endpoint for frontend events (public - no auth required) 11 | sentryRouter.post('/tunnel', setAuthLevel(AuthConfig.public), adaptController(SentryTunnelController, SentryTunnelController.tunnel)); 12 | 13 | // Mount the router under /api/sentry 14 | app.route('/api/sentry', sentryRouter); 15 | } 16 | -------------------------------------------------------------------------------- /worker/api/routes/statsRoutes.ts: -------------------------------------------------------------------------------- 1 | import { StatsController } from '../controllers/stats/controller'; 2 | import { Hono } from 'hono'; 3 | import { AppEnv } from '../../types/appenv'; 4 | import { adaptController } from '../honoAdapter'; 5 | import { AuthConfig, setAuthLevel } from '../../middleware/auth/routeAuth'; 6 | 7 | /** 8 | * Setup user statistics routes 9 | */ 10 | export function setupStatsRoutes(app: Hono): void { 11 | // User statistics 12 | app.get('/api/stats', setAuthLevel(AuthConfig.authenticated), adaptController(StatsController, StatsController.getUserStats)); 13 | 14 | // User activity timeline 15 | app.get('/api/stats/activity', setAuthLevel(AuthConfig.authenticated), adaptController(StatsController, StatsController.getUserActivity)); 16 | } -------------------------------------------------------------------------------- /worker/api/routes/userRoutes.ts: -------------------------------------------------------------------------------- 1 | import { UserController } from '../controllers/user/controller'; 2 | import { Hono } from 'hono'; 3 | import { AppEnv } from '../../types/appenv'; 4 | import { adaptController } from '../honoAdapter'; 5 | import { AuthConfig, setAuthLevel } from '../../middleware/auth/routeAuth'; 6 | 7 | /** 8 | * Setup user management routes 9 | */ 10 | export function setupUserRoutes(app: Hono): void { 11 | // User apps with pagination (this is what the frontend needs) 12 | app.get('/api/user/apps', setAuthLevel(AuthConfig.authenticated), adaptController(UserController, UserController.getApps)); 13 | 14 | // User profile 15 | app.put('/api/user/profile', setAuthLevel(AuthConfig.authenticated), adaptController(UserController, UserController.updateProfile)); 16 | } -------------------------------------------------------------------------------- /migrations/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "sqlite", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "6", 8 | "when": 1757000935039, 9 | "tag": "0000_living_forge", 10 | "breakpoints": true 11 | }, 12 | { 13 | "idx": 1, 14 | "version": "6", 15 | "when": 1757447858711, 16 | "tag": "0001_married_moondragon", 17 | "breakpoints": true 18 | }, 19 | { 20 | "idx": 2, 21 | "version": "6", 22 | "when": 1758608665393, 23 | "tag": "0002_nebulous_fantastic_four", 24 | "breakpoints": true 25 | }, 26 | { 27 | "idx": 3, 28 | "version": "6", 29 | "when": 1759483967805, 30 | "tag": "0003_bumpy_albert_cleary", 31 | "breakpoints": true 32 | } 33 | ] 34 | } -------------------------------------------------------------------------------- /src/components/header.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import clsx from 'clsx'; 3 | import { CloudflareLogo } from './icons/logos'; 4 | import { Link } from 'react-router'; 5 | 6 | export function Header({ 7 | className, 8 | children, 9 | }: React.ComponentProps<'header'>) { 10 | return ( 11 |
17 |

18 | 19 | 23 | 24 |

25 |
26 |
27 | {children} 28 |
29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /src/components/ui/separator.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as SeparatorPrimitive from "@radix-ui/react-separator" 3 | 4 | import { cn } from "@/lib/utils" 5 | 6 | function Separator({ 7 | className, 8 | orientation = "horizontal", 9 | decorative = true, 10 | ...props 11 | }: React.ComponentProps) { 12 | return ( 13 | 23 | ) 24 | } 25 | 26 | export { Separator } 27 | -------------------------------------------------------------------------------- /src/routes/chat/utils/websocket-helpers.ts: -------------------------------------------------------------------------------- 1 | import type { WebSocket } from 'partysocket'; 2 | 3 | /** 4 | * Check if WebSocket is ready for communication 5 | */ 6 | export function isWebSocketReady(websocket: WebSocket | undefined): websocket is WebSocket { 7 | return !!websocket && websocket.readyState === 1; // OPEN state 8 | } 9 | 10 | /** 11 | * Send a message via WebSocket if connection is ready 12 | */ 13 | export function sendWebSocketMessage( 14 | websocket: WebSocket | undefined, 15 | type: string, 16 | data?: Record 17 | ): boolean { 18 | if (!isWebSocketReady(websocket)) { 19 | console.warn(`WebSocket not ready for message type: ${type}`); 20 | return false; 21 | } 22 | 23 | websocket.send(JSON.stringify({ type, ...data })); 24 | return true; 25 | } 26 | -------------------------------------------------------------------------------- /src/routes/protected-route.tsx: -------------------------------------------------------------------------------- 1 | import { Navigate } from 'react-router'; 2 | import { useAuth } from '../contexts/auth-context'; 3 | import { Skeleton } from '../components/ui/skeleton'; 4 | 5 | interface ProtectedRouteProps { 6 | children: React.ReactNode; 7 | } 8 | 9 | export function ProtectedRoute({ children }: ProtectedRouteProps) { 10 | const { isAuthenticated, isLoading } = useAuth(); 11 | 12 | if (isLoading) { 13 | return ( 14 |
15 |
16 | 17 | 18 |
19 |
20 | ); 21 | } 22 | 23 | if (!isAuthenticated) { 24 | return ; 25 | } 26 | 27 | return <>{children}; 28 | } -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { 6 | return ( 7 |