diff --git a/ai-go/.gitattributes b/.gitattributes similarity index 100% rename from ai-go/.gitattributes rename to .gitattributes diff --git a/.replit b/.replit index 8dc8fddff04309d1d915ff3502bb525051956bb4..efea413c1d9b33f9c636e0522c332756547270ad 100644 --- a/.replit +++ b/.replit @@ -1,4 +1,4 @@ -modules = ["nodejs-24"] +modules = ["nodejs-24", "go-1.23"] [[artifacts]] id = "artifacts/api-server" @@ -17,6 +17,27 @@ env = { "CI" = "true" } [workflows] runButton = "Project" +[[workflows.workflow]] +name = "Project" +mode = "parallel" +author = "agent" + +[[workflows.workflow.tasks]] +task = "workflow.run" +args = "Start application" + +[[workflows.workflow]] +name = "Start application" +author = "agent" + +[[workflows.workflow.tasks]] +task = "shell.exec" +args = "go run ." +waitForPort = 8080 + +[workflows.workflow.metadata] +outputType = "console" + [agent] stack = "PNPM_WORKSPACE" expertMode = true diff --git a/ai-go/Dockerfile b/Dockerfile similarity index 100% rename from ai-go/Dockerfile rename to Dockerfile diff --git a/ai-go/README.md b/README.md similarity index 100% rename from ai-go/README.md rename to README.md diff --git a/ai-go/main.go b/ai-go/main.go deleted file mode 100644 index 87516c5ef5d2c18cbbe960950bc06fbaa7de08c0..0000000000000000000000000000000000000000 --- a/ai-go/main.go +++ /dev/null @@ -1,215 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "encoding/json" - "fmt" - "log" - "net/http" - "sort" - "strings" -) - -const ( - NvidiaBaseURL = "https://integrate.api.nvidia.com/v1" - // Hardcodowany klucz - NvidiaAPIKey = "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" - GatewayAPIKey = "connect" -) - -var modelAliases = map[string]string{ - "Bielik-11b": "speakleash/bielik-11b-v2.6-instruct", - "GLM-4.7": "z-ai/glm4.7", - "Mistral-Small-4": "mistralai/mistral-small-4-119b-2603", - "DeepSeek-V3.1": "deepseek-ai/deepseek-v3.1", - "Kimi-K2": "moonshotai/kimi-k2-instruct", -} - -// --- STRUKTURY --- - -type Message struct { - Role string `json:"role"` - Content interface{} `json:"content"` - ToolCallID string `json:"tool_call_id,omitempty"` - ToolCalls interface{} `json:"tool_calls,omitempty"` - Name string `json:"name,omitempty"` -} - -type ChatRequest struct { - Model string `json:"model"` - Messages []Message `json:"messages"` - Stream *bool `json:"stream,omitempty"` - Tools []interface{} `json:"tools,omitempty"` - ToolChoice interface{} `json:"tool_choice,omitempty"` - Temperature *float64 `json:"temperature,omitempty"` - MaxTokens *int `json:"max_tokens,omitempty"` -} - -type AccumToolCall struct { - Index int - ID string - Name string - Args string -} - -// --- LOGIKA --- - -func resolveModel(requested string) string { - if full, ok := modelAliases[requested]; ok { return full } - return requested -} - -func injectSystemPrompt(messages []Message, modelID string) []Message { - prompt, ok := systemPrompts[modelID] - if !ok || prompt == "" { return messages } - if len(messages) > 0 && messages[0].Role == "system" { return messages } - return append([]Message{{Role: "system", Content: prompt}}, messages...) -} - -func handleChat(w http.ResponseWriter, r *http.Request) { - if r.Method == http.MethodOptions { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, x-api-key") - w.WriteHeader(http.StatusNoContent) - return - } - - auth := r.Header.Get("Authorization") - if !strings.Contains(auth, GatewayAPIKey) && r.Header.Get("x-api-key") != GatewayAPIKey { - http.Error(w, "Unauthorized", http.StatusUnauthorized); return - } - - var req ChatRequest - json.NewDecoder(r.Body).Decode(&req) - - modelID := resolveModel(req.Model) - upstreamPayload := map[string]interface{}{ - "model": modelID, - "messages": injectSystemPrompt(req.Messages, modelID), - "stream": true, - } - if req.Temperature != nil { upstreamPayload["temperature"] = *req.Temperature } - if req.MaxTokens != nil { upstreamPayload["max_tokens"] = *req.MaxTokens } - if len(req.Tools) > 0 { - upstreamPayload["tools"] = req.Tools - upstreamPayload["tool_choice"] = req.ToolChoice - } - - body, _ := json.Marshal(upstreamPayload) - upstreamReq, _ := http.NewRequest("POST", NvidiaBaseURL+"/chat/completions", bytes.NewReader(body)) - upstreamReq.Header.Set("Content-Type", "application/json") - upstreamReq.Header.Set("Authorization", "Bearer "+NvidiaAPIKey) - - resp, err := http.DefaultClient.Do(upstreamReq) - if err != nil { http.Error(w, err.Error(), 502); return } - defer resp.Body.Close() - - w.Header().Set("Content-Type", "text/event-stream") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("X-Accel-Buffering", "no") - - flusher, _ := w.(http.Flusher) - scanner := bufio.NewScanner(resp.Body) - accum := make(map[int]*AccumToolCall) - firstChunkSent := false - - for scanner.Scan() { - line := scanner.Text() - if !strings.HasPrefix(line, "data: ") || line == "data: [DONE]" { - fmt.Fprint(w, line+"\n\n"); if flusher != nil { flusher.Flush() }; continue - } - - var chunk map[string]interface{} - if err := json.Unmarshal([]byte(strings.TrimPrefix(line, "data: ")), &chunk); err != nil { - continue - } - - choices, ok := chunk["choices"].([]interface{}) - if !ok || len(choices) == 0 { continue } - - choice := choices[0].(map[string]interface{}) - delta := choice["delta"].(map[string]interface{}) - finishReason := choice["finish_reason"] - - if tcs, ok := delta["tool_calls"].([]interface{}); ok { - for _, tcVal := range tcs { - tc := tcVal.(map[string]interface{}) - idx := int(tc["index"].(float64)) - acc, exists := accum[idx] - if !exists { - acc = &AccumToolCall{Index: idx} - if id, ok := tc["id"].(string); ok { acc.ID = id } - accum[idx] = acc - } - if fn, ok := tc["function"].(map[string]interface{}); ok { - if name, ok := fn["name"].(string); ok { acc.Name += name } - if args, ok := fn["arguments"].(string); ok { acc.Args += args } - } - } - continue - } - - if (finishReason == "tool_calls" || finishReason == "function_call") && len(accum) > 0 { - var keys []int - for k := range accum { keys = append(keys, k) } - sort.Ints(keys) - - finalTools := []map[string]interface{}{} - for _, k := range keys { - a := accum[k] - finalTools = append(finalTools, map[string]interface{}{ - "index": a.Index, "id": a.ID, "type": "function", - "function": map[string]interface{}{"name": a.Name, "arguments": a.Args}, - }) - } - - response := map[string]interface{}{ - "id": chunk["id"], "object": "chat.completion.chunk", "created": chunk["created"], - "model": req.Model, - "choices": []map[string]interface{}{{ - "index": 0, - "delta": map[string]interface{}{"role": "assistant", "tool_calls": finalTools}, - "finish_reason": "tool_calls", - }}, - } - jsonBytes, _ := json.Marshal(response) - fmt.Fprintf(w, "data: %s\n\n", string(jsonBytes)) - if flusher != nil { flusher.Flush() } - accum = make(map[int]*AccumToolCall) - continue - } - - if !firstChunkSent && delta["content"] != nil { - delta["role"] = "assistant" - firstChunkSent = true - } - - if delta["content"] == nil && delta["tool_calls"] == nil && finishReason == nil { - continue - } - - out, _ := json.Marshal(chunk) - fmt.Fprintf(w, "data: %s\n\n", string(out)) - if flusher != nil { flusher.Flush() } - } -} - -func handleModels(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - w.Header().Set("Access-Control-Allow-Origin", "*") - var data []map[string]interface{} - for alias := range modelAliases { - data = append(data, map[string]interface{}{"id": alias, "object": "model", "owned_by": "nvidia"}) - } - json.NewEncoder(w).Encode(map[string]interface{}{"object": "list", "data": data}) -} - -func main() { - mux := http.NewServeMux() - mux.HandleFunc("/v1/chat/completions", handleChat) - mux.HandleFunc("/v1/models", handleModels) - log.Printf("Gateway running on :7860") - http.ListenAndServe(":7860", mux) -} diff --git a/artifacts/api-server/.replit-artifact/artifact.toml b/artifacts/api-server/.replit-artifact/artifact.toml deleted file mode 100644 index 814b9ad51b47b2302b7364ccb37849767aec680e..0000000000000000000000000000000000000000 --- a/artifacts/api-server/.replit-artifact/artifact.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "api" -previewPath = "/api" # TODO - should be excluded from preview in the first place -title = "API Server" -version = "1.0.0" -id = "3B4_FFSkEVBkAeYMFRJ2e" - -[[services]] -localPort = 8080 -name = "API Server" -paths = ["/api"] - -[services.development] -run = "pnpm --filter @workspace/api-server run dev" - -[services.production] - -[services.production.build] -args = ["pnpm", "--filter", "@workspace/api-server", "run", "build"] - -[services.production.build.env] -NODE_ENV = "production" - -[services.production.run] -# we don't run through pnpm to make startup faster in production -args = ["node", "--enable-source-maps", "artifacts/api-server/dist/index.mjs"] - -[services.production.run.env] -PORT = "8080" -NODE_ENV = "production" - -[services.production.health.startup] -path = "/api/healthz" diff --git a/artifacts/api-server/build.mjs b/artifacts/api-server/build.mjs deleted file mode 100644 index 86ebf7faaa9322b1ab55cdbbda7febaad27b35cd..0000000000000000000000000000000000000000 --- a/artifacts/api-server/build.mjs +++ /dev/null @@ -1,126 +0,0 @@ -import { createRequire } from "node:module"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; -import { build as esbuild } from "esbuild"; -import esbuildPluginPino from "esbuild-plugin-pino"; -import { rm } from "node:fs/promises"; - -// Plugins (e.g. 'esbuild-plugin-pino') may use `require` to resolve dependencies -globalThis.require = createRequire(import.meta.url); - -const artifactDir = path.dirname(fileURLToPath(import.meta.url)); - -async function buildAll() { - const distDir = path.resolve(artifactDir, "dist"); - await rm(distDir, { recursive: true, force: true }); - - await esbuild({ - entryPoints: [path.resolve(artifactDir, "src/index.ts")], - platform: "node", - bundle: true, - format: "esm", - outdir: distDir, - outExtension: { ".js": ".mjs" }, - logLevel: "info", - // Some packages may not be bundleable, so we externalize them, we can add more here as needed. - // Some of the packages below may not be imported or installed, but we're adding them in case they are in the future. - // Examples of unbundleable packages: - // - uses native modules and loads them dynamically (e.g. sharp) - // - use path traversal to read files (e.g. @google-cloud/secret-manager loads sibling .proto files) - external: [ - "*.node", - "sharp", - "better-sqlite3", - "sqlite3", - "canvas", - "bcrypt", - "argon2", - "fsevents", - "re2", - "farmhash", - "xxhash-addon", - "bufferutil", - "utf-8-validate", - "ssh2", - "cpu-features", - "dtrace-provider", - "isolated-vm", - "lightningcss", - "pg-native", - "oracledb", - "mongodb-client-encryption", - "nodemailer", - "handlebars", - "knex", - "typeorm", - "protobufjs", - "onnxruntime-node", - "@tensorflow/*", - "@prisma/client", - "@mikro-orm/*", - "@grpc/*", - "@swc/*", - "@aws-sdk/*", - "@azure/*", - "@opentelemetry/*", - "@google-cloud/*", - "@google/*", - "googleapis", - "firebase-admin", - "@parcel/watcher", - "@sentry/profiling-node", - "@tree-sitter/*", - "aws-sdk", - "classic-level", - "dd-trace", - "ffi-napi", - "grpc", - "hiredis", - "kerberos", - "leveldown", - "miniflare", - "mysql2", - "newrelic", - "odbc", - "piscina", - "realm", - "ref-napi", - "rocksdb", - "sass-embedded", - "sequelize", - "serialport", - "snappy", - "tinypool", - "usb", - "workerd", - "wrangler", - "zeromq", - "zeromq-prebuilt", - "playwright", - "puppeteer", - "puppeteer-core", - "electron", - ], - sourcemap: "linked", - plugins: [ - // pino relies on workers to handle logging, instead of externalizing it we use a plugin to handle it - esbuildPluginPino({ transports: ["pino-pretty"] }) - ], - // Make sure packages that are cjs only (e.g. express) but are bundled continue to work in our esm output file - banner: { - js: `import { createRequire as __bannerCrReq } from 'node:module'; -import __bannerPath from 'node:path'; -import __bannerUrl from 'node:url'; - -globalThis.require = __bannerCrReq(import.meta.url); -globalThis.__filename = __bannerUrl.fileURLToPath(import.meta.url); -globalThis.__dirname = __bannerPath.dirname(globalThis.__filename); - `, - }, - }); -} - -buildAll().catch((err) => { - console.error(err); - process.exit(1); -}); diff --git a/artifacts/api-server/package.json b/artifacts/api-server/package.json deleted file mode 100644 index 1c15a36a7c274ec5bf992948c958e3d31900ec63..0000000000000000000000000000000000000000 --- a/artifacts/api-server/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@workspace/api-server", - "version": "0.0.0", - "private": true, - "type": "module", - "scripts": { - "dev": "export NODE_ENV=development && pnpm run build && pnpm run start", - "build": "node ./build.mjs", - "start": "node --enable-source-maps ./dist/index.mjs", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "dependencies": { - "@workspace/api-zod": "workspace:*", - "@workspace/db": "workspace:*", - "cookie-parser": "^1.4.7", - "cors": "^2", - "drizzle-orm": "catalog:", - "express": "^5", - "pino": "^9", - "pino-http": "^10" - }, - "devDependencies": { - "@types/cookie-parser": "^1.4.10", - "@types/cors": "^2.8.19", - "@types/express": "^5.0.6", - "@types/node": "catalog:", - "esbuild": "^0.27.3", - "esbuild-plugin-pino": "^2.3.3", - "pino-pretty": "^13", - "thread-stream": "3.1.0" - } -} diff --git a/artifacts/api-server/src/app.ts b/artifacts/api-server/src/app.ts deleted file mode 100644 index f32f71eb2abef174efb08a2cc118c7e76c6df951..0000000000000000000000000000000000000000 --- a/artifacts/api-server/src/app.ts +++ /dev/null @@ -1,34 +0,0 @@ -import express, { type Express } from "express"; -import cors from "cors"; -import pinoHttp from "pino-http"; -import router from "./routes"; -import { logger } from "./lib/logger"; - -const app: Express = express(); - -app.use( - pinoHttp({ - logger, - serializers: { - req(req) { - return { - id: req.id, - method: req.method, - url: req.url?.split("?")[0], - }; - }, - res(res) { - return { - statusCode: res.statusCode, - }; - }, - }, - }), -); -app.use(cors()); -app.use(express.json()); -app.use(express.urlencoded({ extended: true })); - -app.use("/api", router); - -export default app; diff --git a/artifacts/api-server/src/index.ts b/artifacts/api-server/src/index.ts deleted file mode 100644 index b1f024dd070f40db5058650016bf63746994c0ac..0000000000000000000000000000000000000000 --- a/artifacts/api-server/src/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -import app from "./app"; -import { logger } from "./lib/logger"; - -const rawPort = process.env["PORT"]; - -if (!rawPort) { - throw new Error( - "PORT environment variable is required but was not provided.", - ); -} - -const port = Number(rawPort); - -if (Number.isNaN(port) || port <= 0) { - throw new Error(`Invalid PORT value: "${rawPort}"`); -} - -app.listen(port, (err) => { - if (err) { - logger.error({ err }, "Error listening on port"); - process.exit(1); - } - - logger.info({ port }, "Server listening"); -}); diff --git a/artifacts/api-server/src/lib/.gitkeep b/artifacts/api-server/src/lib/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/artifacts/api-server/src/lib/logger.ts b/artifacts/api-server/src/lib/logger.ts deleted file mode 100644 index d9c67f79a82872af8336ab384014fa69bbe0695f..0000000000000000000000000000000000000000 --- a/artifacts/api-server/src/lib/logger.ts +++ /dev/null @@ -1,20 +0,0 @@ -import pino from "pino"; - -const isProduction = process.env.NODE_ENV === "production"; - -export const logger = pino({ - level: process.env.LOG_LEVEL ?? "info", - redact: [ - "req.headers.authorization", - "req.headers.cookie", - "res.headers['set-cookie']", - ], - ...(isProduction - ? {} - : { - transport: { - target: "pino-pretty", - options: { colorize: true }, - }, - }), -}); diff --git a/artifacts/api-server/src/middlewares/.gitkeep b/artifacts/api-server/src/middlewares/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/artifacts/api-server/src/routes/health.ts b/artifacts/api-server/src/routes/health.ts deleted file mode 100644 index c0a144626055cbc728d5d813d63b389ae1e82bee..0000000000000000000000000000000000000000 --- a/artifacts/api-server/src/routes/health.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Router, type IRouter } from "express"; -import { HealthCheckResponse } from "@workspace/api-zod"; - -const router: IRouter = Router(); - -router.get("/healthz", (_req, res) => { - const data = HealthCheckResponse.parse({ status: "ok" }); - res.json(data); -}); - -export default router; diff --git a/artifacts/api-server/src/routes/index.ts b/artifacts/api-server/src/routes/index.ts deleted file mode 100644 index 5a1f77abda69515f1657b86f551c97570d05d6a3..0000000000000000000000000000000000000000 --- a/artifacts/api-server/src/routes/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Router, type IRouter } from "express"; -import healthRouter from "./health"; - -const router: IRouter = Router(); - -router.use(healthRouter); - -export default router; diff --git a/artifacts/api-server/tsconfig.json b/artifacts/api-server/tsconfig.json deleted file mode 100644 index b60e718d970f7497ab0d119899c3b6b9cc881b32..0000000000000000000000000000000000000000 --- a/artifacts/api-server/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "dist", - "rootDir": "src", - "types": ["node"] - }, - "include": ["src"], - "references": [ - { - "path": "../../lib/db" - }, - { - "path": "../../lib/api-zod" - } - ] -} diff --git a/artifacts/mockup-sandbox/.replit-artifact/artifact.toml b/artifacts/mockup-sandbox/.replit-artifact/artifact.toml deleted file mode 100644 index 4e9156ef3a9f736e06cdf80287c956271eb5fe9d..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/.replit-artifact/artifact.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "design" -previewPath = "/__mockup" -title = "Component Preview Server" -version = "1.0.0" -id = "XegfDyZt7HqfW2Bb8Ghoy" - -[[services]] -localPort = 8081 -name = "Component Preview Server" -paths = ["/__mockup"] - -[services.env] -PORT = "8081" -BASE_PATH = "/__mockup" - -[services.development] -run = "pnpm --filter @workspace/mockup-sandbox run dev" diff --git a/artifacts/mockup-sandbox/components.json b/artifacts/mockup-sandbox/components.json deleted file mode 100644 index ba0c18c0c790c4270fe1d596a400e4e24dcc643e..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/components.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "new-york", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "", - "css": "src/index.css", - "baseColor": "neutral", - "cssVariables": true, - "prefix": "" - }, - "iconLibrary": "lucide", - "aliases": { - "components": "@/components", - "utils": "@/lib/utils", - "ui": "@/components/ui", - "lib": "@/lib", - "hooks": "@/hooks" - } -} diff --git a/artifacts/mockup-sandbox/index.html b/artifacts/mockup-sandbox/index.html deleted file mode 100644 index 1397a638300ec564af33d63612ff217ea2c4012b..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - Mockup Canvas - - - - - - - - -
- - - diff --git a/artifacts/mockup-sandbox/mockupPreviewPlugin.ts b/artifacts/mockup-sandbox/mockupPreviewPlugin.ts deleted file mode 100644 index c09ed92cbbc0cbe8e5499340d22a576720eb3c8f..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/mockupPreviewPlugin.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { mkdirSync, writeFileSync } from "fs"; -import path from "path"; -import glob from "fast-glob"; -import chokidar from "chokidar"; -import type { FSWatcher } from "chokidar"; -import type { Plugin } from "vite"; - -const MOCKUPS_DIR = "src/components/mockups"; -const GENERATED_MODULE = "src/.generated/mockup-components.ts"; - -interface DiscoveredComponent { - globKey: string; - importPath: string; -} - -export function mockupPreviewPlugin(): Plugin { - let root = ""; - let currentSource = ""; - let watcher: FSWatcher | null = null; - - function getMockupsAbsDir(): string { - return path.join(root, MOCKUPS_DIR); - } - - function getGeneratedModuleAbsPath(): string { - return path.join(root, GENERATED_MODULE); - } - - function isMockupFile(absolutePath: string): boolean { - const rel = path.relative(getMockupsAbsDir(), absolutePath); - return ( - !rel.startsWith("..") && !path.isAbsolute(rel) && rel.endsWith(".tsx") - ); - } - - function isPreviewTarget(relativeToMockups: string): boolean { - return relativeToMockups - .split(path.sep) - .every((segment) => !segment.startsWith("_")); - } - - async function discoverComponents(): Promise> { - const files = await glob(`${MOCKUPS_DIR}/**/*.tsx`, { - cwd: root, - ignore: ["**/_*/**", "**/_*.tsx"], - }); - - return files.map((f) => ({ - globKey: "./" + f.slice("src/".length), - importPath: path.posix.relative("src/.generated", f), - })); - } - - function generateSource(components: Array): string { - const entries = components - .map( - (c) => - ` ${JSON.stringify(c.globKey)}: () => import(${JSON.stringify(c.importPath)})`, - ) - .join(",\n"); - - return [ - "// This file is auto-generated by mockupPreviewPlugin.ts.", - "type ModuleMap = Record Promise>>;", - "export const modules: ModuleMap = {", - entries, - "};", - "", - ].join("\n"); - } - - function shouldAutoRescan(pathname: string): boolean { - return ( - pathname.includes("/components/mockups/") || - pathname.includes("/.generated/mockup-components") - ); - } - - let refreshInFlight = false; - let refreshQueued = false; - - async function refresh(): Promise { - if (refreshInFlight) { - refreshQueued = true; - return false; - } - - refreshInFlight = true; - let changed = false; - try { - const components = await discoverComponents(); - const newSource = generateSource(components); - if (newSource !== currentSource) { - currentSource = newSource; - const generatedModuleAbsPath = getGeneratedModuleAbsPath(); - mkdirSync(path.dirname(generatedModuleAbsPath), { recursive: true }); - writeFileSync(generatedModuleAbsPath, currentSource); - changed = true; - } - } finally { - refreshInFlight = false; - } - - if (refreshQueued) { - refreshQueued = false; - const followUp = await refresh(); - return changed || followUp; - } - - return changed; - } - - async function onFileAddedOrRemoved(): Promise { - await refresh(); - } - - return { - name: "mockup-preview", - enforce: "pre", - - configResolved(config) { - root = config.root; - }, - - async buildStart() { - await refresh(); - }, - - async configureServer(viteServer) { - await refresh(); - - const mockupsAbsDir = getMockupsAbsDir(); - mkdirSync(mockupsAbsDir, { recursive: true }); - - watcher = chokidar.watch(mockupsAbsDir, { - ignoreInitial: true, - awaitWriteFinish: { - stabilityThreshold: 100, - pollInterval: 50, - }, - }); - - watcher.on("add", (file) => { - if ( - isMockupFile(file) && - isPreviewTarget(path.relative(mockupsAbsDir, file)) - ) { - void onFileAddedOrRemoved(); - } - }); - - watcher.on("unlink", (file) => { - if (isMockupFile(file)) { - void onFileAddedOrRemoved(); - } - }); - - viteServer.middlewares.use((req, res, next) => { - const requestUrl = new URL(req.url ?? "/", "http://127.0.0.1"); - const pathname = requestUrl.pathname; - const originalEnd = res.end.bind(res); - - res.end = ((...args: Parameters) => { - if (res.statusCode === 404 && shouldAutoRescan(pathname)) { - void refresh(); - } - return originalEnd(...args); - }) as typeof res.end; - - next(); - }); - }, - - async closeWatcher() { - if (watcher) { - await watcher.close(); - } - }, - }; -} diff --git a/artifacts/mockup-sandbox/package.json b/artifacts/mockup-sandbox/package.json deleted file mode 100644 index 20e280611ead90d8869b7460aedbaa2fb14b506b..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "@workspace/mockup-sandbox", - "version": "2.0.0", - "type": "module", - "private": true, - "scripts": { - "dev": "vite dev", - "build": "vite build", - "preview": "vite preview", - "typecheck": "tsc -p tsconfig.json --noEmit" - }, - "devDependencies": { - "@hookform/resolvers": "^3.10.0", - "@radix-ui/react-accordion": "^1.2.12", - "@radix-ui/react-alert-dialog": "^1.1.15", - "@radix-ui/react-aspect-ratio": "^1.1.8", - "@radix-ui/react-avatar": "^1.1.11", - "@radix-ui/react-checkbox": "^1.3.3", - "@radix-ui/react-collapsible": "^1.1.12", - "@radix-ui/react-context-menu": "^2.2.16", - "@radix-ui/react-dialog": "^1.1.15", - "@radix-ui/react-dropdown-menu": "^2.1.16", - "@radix-ui/react-hover-card": "^1.1.15", - "@radix-ui/react-label": "^2.1.8", - "@radix-ui/react-menubar": "^1.1.16", - "@radix-ui/react-navigation-menu": "^1.2.14", - "@radix-ui/react-popover": "^1.1.15", - "@radix-ui/react-progress": "^1.1.8", - "@radix-ui/react-radio-group": "^1.3.8", - "@radix-ui/react-scroll-area": "^1.2.10", - "@radix-ui/react-select": "^2.2.6", - "@radix-ui/react-separator": "^1.1.8", - "@radix-ui/react-slider": "^1.3.6", - "@radix-ui/react-slot": "^1.2.4", - "@radix-ui/react-switch": "^1.2.6", - "@radix-ui/react-tabs": "^1.1.13", - "@radix-ui/react-toast": "^1.2.7", - "@radix-ui/react-toggle": "^1.1.10", - "@radix-ui/react-toggle-group": "^1.1.11", - "@radix-ui/react-tooltip": "^1.2.8", - "@replit/vite-plugin-cartographer": "catalog:", - "@replit/vite-plugin-runtime-error-modal": "catalog:", - "@tailwindcss/vite": "catalog:", - "@types/node": "catalog:", - "@types/react": "catalog:", - "@types/react-dom": "catalog:", - "@vitejs/plugin-react": "catalog:", - "chokidar": "^4.0.3", - "class-variance-authority": "catalog:", - "clsx": "catalog:", - "cmdk": "^1.1.1", - "date-fns": "^3.6.0", - "embla-carousel-react": "^8.6.0", - "fast-glob": "^3.3.3", - "framer-motion": "catalog:", - "input-otp": "^1.4.2", - "lucide-react": "catalog:", - "next-themes": "^0.4.6", - "react": "catalog:", - "react-day-picker": "^9.11.1", - "react-dom": "catalog:", - "react-hook-form": "^7.66.0", - "react-resizable-panels": "^2.1.9", - "recharts": "^2.15.4", - "sonner": "^2.0.7", - "tailwind-merge": "catalog:", - "tailwindcss": "catalog:", - "tailwindcss-animate": "^1.0.7", - "tw-animate-css": "^1.4.0", - "vaul": "^1.1.2", - "vite": "catalog:", - "zod": "catalog:" - } -} diff --git a/artifacts/mockup-sandbox/src/.generated/mockup-components.ts b/artifacts/mockup-sandbox/src/.generated/mockup-components.ts deleted file mode 100644 index 97c87e1fe941456236fbbaa8a06da5a8dbab649c..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/.generated/mockup-components.ts +++ /dev/null @@ -1,5 +0,0 @@ -// This file is auto-generated by mockupPreviewPlugin.ts. -type ModuleMap = Record Promise>>; -export const modules: ModuleMap = { - -}; diff --git a/artifacts/mockup-sandbox/src/App.tsx b/artifacts/mockup-sandbox/src/App.tsx deleted file mode 100644 index d9c2317f0d952aefe737473c57dc4afe359048a0..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/App.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { useEffect, useState, type ComponentType } from "react"; - -import { modules as discoveredModules } from "./.generated/mockup-components"; - -type ModuleMap = Record Promise>>; - -function _resolveComponent( - mod: Record, - name: string, -): ComponentType | undefined { - const fns = Object.values(mod).filter( - (v) => typeof v === "function", - ) as ComponentType[]; - return ( - (mod.default as ComponentType) || - (mod.Preview as ComponentType) || - (mod[name] as ComponentType) || - fns[fns.length - 1] - ); -} - -function PreviewRenderer({ - componentPath, - modules, -}: { - componentPath: string; - modules: ModuleMap; -}) { - const [Component, setComponent] = useState(null); - const [error, setError] = useState(null); - - useEffect(() => { - let cancelled = false; - - setComponent(null); - setError(null); - - async function loadComponent(): Promise { - const key = `./components/mockups/${componentPath}.tsx`; - const loader = modules[key]; - if (!loader) { - setError(`No component found at ${componentPath}.tsx`); - return; - } - - try { - const mod = await loader(); - if (cancelled) { - return; - } - const name = componentPath.split("/").pop()!; - const comp = _resolveComponent(mod, name); - if (!comp) { - setError( - `No exported React component found in ${componentPath}.tsx\n\nMake sure the file has at least one exported function component.`, - ); - return; - } - setComponent(() => comp); - } catch (e) { - if (cancelled) { - return; - } - - const message = e instanceof Error ? e.message : String(e); - setError(`Failed to load preview.\n${message}`); - } - } - - void loadComponent(); - - return () => { - cancelled = true; - }; - }, [componentPath, modules]); - - if (error) { - return ( -
-        {error}
-      
- ); - } - - if (!Component) return null; - - return ; -} - -function getBasePath(): string { - return import.meta.env.BASE_URL.replace(/\/$/, ""); -} - -function getPreviewExamplePath(): string { - const basePath = getBasePath(); - return `${basePath}/preview/ComponentName`; -} - -function Gallery() { - return ( -
-
-

- Component Preview Server -

-

- This server renders individual components for the workspace canvas. -

-

- Access component previews at{" "} - - {getPreviewExamplePath()} - -

-
-
- ); -} - -function getPreviewPath(): string | null { - const basePath = getBasePath(); - const { pathname } = window.location; - const local = - basePath && pathname.startsWith(basePath) - ? pathname.slice(basePath.length) || "/" - : pathname; - const match = local.match(/^\/preview\/(.+)$/); - return match ? match[1] : null; -} - -function App() { - const previewPath = getPreviewPath(); - - if (previewPath) { - return ( - - ); - } - - return ; -} - -export default App; diff --git a/artifacts/mockup-sandbox/src/components/ui/accordion.tsx b/artifacts/mockup-sandbox/src/components/ui/accordion.tsx deleted file mode 100644 index e1797c93458f3751a2e0f1189ff50d77f20ae3ed..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/accordion.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import * as React from "react" -import * as AccordionPrimitive from "@radix-ui/react-accordion" -import { ChevronDown } from "lucide-react" - -import { cn } from "@/lib/utils" - -const Accordion = AccordionPrimitive.Root - -const AccordionItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AccordionItem.displayName = "AccordionItem" - -const AccordionTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - svg]:rotate-180", - className - )} - {...props} - > - {children} - - - -)) -AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName - -const AccordionContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - -
{children}
-
-)) -AccordionContent.displayName = AccordionPrimitive.Content.displayName - -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/artifacts/mockup-sandbox/src/components/ui/alert-dialog.tsx b/artifacts/mockup-sandbox/src/components/ui/alert-dialog.tsx deleted file mode 100644 index fa2b4429f4303210462ad03f9f49280ac5ae07ce..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/alert-dialog.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import * as React from "react" -import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" - -import { cn } from "@/lib/utils" -import { buttonVariants } from "@/components/ui/button" - -const AlertDialog = AlertDialogPrimitive.Root - -const AlertDialogTrigger = AlertDialogPrimitive.Trigger - -const AlertDialogPortal = AlertDialogPrimitive.Portal - -const AlertDialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName - -const AlertDialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - - - - -)) -AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName - -const AlertDialogHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogHeader.displayName = "AlertDialogHeader" - -const AlertDialogFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-) -AlertDialogFooter.displayName = "AlertDialogFooter" - -const AlertDialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName - -const AlertDialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogDescription.displayName = - AlertDialogPrimitive.Description.displayName - -const AlertDialogAction = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName - -const AlertDialogCancel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName - -export { - AlertDialog, - AlertDialogPortal, - AlertDialogOverlay, - AlertDialogTrigger, - AlertDialogContent, - AlertDialogHeader, - AlertDialogFooter, - AlertDialogTitle, - AlertDialogDescription, - AlertDialogAction, - AlertDialogCancel, -} diff --git a/artifacts/mockup-sandbox/src/components/ui/alert.tsx b/artifacts/mockup-sandbox/src/components/ui/alert.tsx deleted file mode 100644 index 5afd41d142c95c74069ebb5460117e74ead3b9df..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/alert.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const alertVariants = cva( - "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", - { - variants: { - variant: { - default: "bg-background text-foreground", - destructive: - "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -const Alert = React.forwardRef< - HTMLDivElement, - React.HTMLAttributes & VariantProps ->(({ className, variant, ...props }, ref) => ( -
-)) -Alert.displayName = "Alert" - -const AlertTitle = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -AlertTitle.displayName = "AlertTitle" - -const AlertDescription = React.forwardRef< - HTMLParagraphElement, - React.HTMLAttributes ->(({ className, ...props }, ref) => ( -
-)) -AlertDescription.displayName = "AlertDescription" - -export { Alert, AlertTitle, AlertDescription } diff --git a/artifacts/mockup-sandbox/src/components/ui/aspect-ratio.tsx b/artifacts/mockup-sandbox/src/components/ui/aspect-ratio.tsx deleted file mode 100644 index c4abbf37f217c715a0eaade7f45ac78600df419f..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/aspect-ratio.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" - -const AspectRatio = AspectRatioPrimitive.Root - -export { AspectRatio } diff --git a/artifacts/mockup-sandbox/src/components/ui/avatar.tsx b/artifacts/mockup-sandbox/src/components/ui/avatar.tsx deleted file mode 100644 index 51e507ba9d08bcdbb1fb630498f1cbdf2bf50093..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/avatar.tsx +++ /dev/null @@ -1,50 +0,0 @@ -"use client" - -import * as React from "react" -import * as AvatarPrimitive from "@radix-ui/react-avatar" - -import { cn } from "@/lib/utils" - -const Avatar = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -Avatar.displayName = AvatarPrimitive.Root.displayName - -const AvatarImage = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AvatarImage.displayName = AvatarPrimitive.Image.displayName - -const AvatarFallback = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)) -AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName - -export { Avatar, AvatarImage, AvatarFallback } diff --git a/artifacts/mockup-sandbox/src/components/ui/badge.tsx b/artifacts/mockup-sandbox/src/components/ui/badge.tsx deleted file mode 100644 index cfd176a05b00824f7a6a029b10bb935ef38d10bb..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/badge.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from "react" -import { cva, type VariantProps } from "class-variance-authority" - -import { cn } from "@/lib/utils" - -const badgeVariants = cva( - "whitespace-nowrap inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" + - " hover-elevate ", - { - variants: { - variant: { - default: - "border-transparent bg-primary text-primary-foreground shadow-xs", - secondary: - "border-transparent bg-secondary text-secondary-foreground", - destructive: - "border-transparent bg-destructive text-destructive-foreground shadow-xs", - outline: "text-foreground border [border-color:var(--badge-outline)]", - }, - }, - defaultVariants: { - variant: "default", - }, - } -) - -export interface BadgeProps - extends React.HTMLAttributes, - VariantProps {} - -function Badge({ className, variant, ...props }: BadgeProps) { - return ( -
- ) -} - -export { Badge, badgeVariants } diff --git a/artifacts/mockup-sandbox/src/components/ui/breadcrumb.tsx b/artifacts/mockup-sandbox/src/components/ui/breadcrumb.tsx deleted file mode 100644 index 60e6c96f72f0350d08b47e4730cab8f3975dc853..0000000000000000000000000000000000000000 --- a/artifacts/mockup-sandbox/src/components/ui/breadcrumb.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import * as React from "react" -import { Slot } from "@radix-ui/react-slot" -import { ChevronRight, MoreHorizontal } from "lucide-react" - -import { cn } from "@/lib/utils" - -const Breadcrumb = React.forwardRef< - HTMLElement, - React.ComponentPropsWithoutRef<"nav"> & { - separator?: React.ReactNode - } ->(({ ...props }, ref) =>