From 8c22c3dc62d569bbb126a2a66f2f768b150af987 Mon Sep 17 00:00:00 2001 From: anandpant Date: Thu, 16 Apr 2026 17:58:33 -0500 Subject: [PATCH] chore: clean up dead code and patch dependencies --- apps/web/package.json | 5 +- .../diagram-studio/diagram-list-item.tsx | 4 +- apps/web/src/components/loader.tsx | 9 -- apps/web/src/components/ui/card.tsx | 8 +- apps/web/src/components/ui/dropdown-menu.tsx | 10 +- apps/web/src/components/ui/skeleton.tsx | 16 --- bun.lock | 98 +++++++--------- package.json | 15 +-- .../convex/lib/excalidrawShareLinks.ts | 2 +- .../backend/lib/agents/diagram-generator.ts | 81 ------------- packages/backend/lib/json-repair.ts | 108 ------------------ packages/backend/lib/output.ts | 51 --------- packages/backend/package.json | 2 +- packages/env/package.json | 1 - packages/opencode-excalidraw/package.json | 2 +- packages/shared/src/excalidraw-share-links.ts | 2 +- tests/api/plan/parse-v2-share-link.ts | 3 - tests/e2e/package.json | 10 +- .../diagram-studio-occ-conflict.ts | 12 +- .../icon-library-generator-invalid-svg.ts | 15 --- .../unauthenticated/mcp-v2-share-link.ts | 2 +- 21 files changed, 72 insertions(+), 384 deletions(-) delete mode 100644 apps/web/src/components/loader.tsx delete mode 100644 apps/web/src/components/ui/skeleton.tsx delete mode 100644 packages/backend/lib/agents/diagram-generator.ts delete mode 100644 packages/backend/lib/json-repair.ts delete mode 100644 packages/backend/lib/output.ts delete mode 100644 tests/api/plan/parse-v2-share-link.ts delete mode 100644 tests/e2e/src/scenarios/unauthenticated/icon-library-generator-invalid-svg.ts diff --git a/apps/web/package.json b/apps/web/package.json index f847cc4..170457b 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -19,14 +19,12 @@ "@sketchi/backend": "workspace:*", "@sketchi/env": "workspace:*", "@sketchi/shared": "workspace:*", - "@tanstack/react-form": "^1.28.3", "@vercel/analytics": "^1.6.1", "@workos-inc/authkit-nextjs": "^2.15.0", "babel-plugin-react-compiler": "^1.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "convex": "catalog:", - "dotenv": "catalog:", "fractional-indexing": "^3.2.0", "jszip": "^3.10.1", "lucide-react": "^0.575.0", @@ -44,8 +42,7 @@ "devDependencies": { "@sketchi/config": "workspace:*", "@tailwindcss/postcss": "^4.2.0", - "@types/jszip": "^3.4.1", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "tailwindcss": "^4.2.0", diff --git a/apps/web/src/components/diagram-studio/diagram-list-item.tsx b/apps/web/src/components/diagram-studio/diagram-list-item.tsx index b0d4cff..ce1a2f1 100644 --- a/apps/web/src/components/diagram-studio/diagram-list-item.tsx +++ b/apps/web/src/components/diagram-studio/diagram-list-item.tsx @@ -306,9 +306,9 @@ export function DiagramListItem({ Created {createdLabel} ) : null} - {item.latestSceneVersion !== null ? ( + {item.latestSceneVersion === null ? null : ( v{item.latestSceneVersion} - ) : null} + )} {originLabel} diff --git a/apps/web/src/components/loader.tsx b/apps/web/src/components/loader.tsx deleted file mode 100644 index e17ec79..0000000 --- a/apps/web/src/components/loader.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { Loader2 } from "lucide-react"; - -export default function Loader() { - return ( -
- -
- ); -} diff --git a/apps/web/src/components/ui/card.tsx b/apps/web/src/components/ui/card.tsx index f243586..c81d515 100644 --- a/apps/web/src/components/ui/card.tsx +++ b/apps/web/src/components/ui/card.tsx @@ -94,10 +94,10 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) { export { Card, - CardHeader, - CardFooter, - CardTitle, CardAction, - CardDescription, CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, }; diff --git a/apps/web/src/components/ui/dropdown-menu.tsx b/apps/web/src/components/ui/dropdown-menu.tsx index 39d8c69..69fa68b 100644 --- a/apps/web/src/components/ui/dropdown-menu.tsx +++ b/apps/web/src/components/ui/dropdown-menu.tsx @@ -245,18 +245,18 @@ function DropdownMenuShortcut({ export { DropdownMenu, - DropdownMenuPortal, - DropdownMenuTrigger, + DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, - DropdownMenuLabel, DropdownMenuItem, - DropdownMenuCheckboxItem, + DropdownMenuLabel, + DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, - DropdownMenuSubTrigger, DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, }; diff --git a/apps/web/src/components/ui/skeleton.tsx b/apps/web/src/components/ui/skeleton.tsx deleted file mode 100644 index 155a140..0000000 --- a/apps/web/src/components/ui/skeleton.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { cn } from "@/lib/utils"; - -function Skeleton({ - className, - ...props -}: React.HTMLAttributes) { - return ( -
- ); -} - -export { Skeleton }; diff --git a/bun.lock b/bun.lock index 2c50e27..51ecd32 100644 --- a/bun.lock +++ b/bun.lock @@ -4,17 +4,12 @@ "workspaces": { "": { "name": "sketchi", - "dependencies": { - "@sketchi/env": "workspace:*", - "dotenv": "^17.3.1", - "zod": "^4.3.6", - }, "devDependencies": { - "@biomejs/biome": "2.4.4", + "@biomejs/biome": "2.4.12", "@sketchi/config": "workspace:*", - "@types/bun": "^1.3.9", - "@types/node": "^25.3.0", - "turbo": "^2.8.10", + "@types/bun": "^1.3.12", + "@types/node": "^25.6.0", + "turbo": "^2.9.6", "typescript": "^5.9.3", "ultracite": "7.2.3", }, @@ -33,14 +28,12 @@ "@sketchi/backend": "workspace:*", "@sketchi/env": "workspace:*", "@sketchi/shared": "workspace:*", - "@tanstack/react-form": "^1.28.3", "@vercel/analytics": "^1.6.1", "@workos-inc/authkit-nextjs": "^2.15.0", "babel-plugin-react-compiler": "^1.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "convex": "catalog:", - "dotenv": "catalog:", "fractional-indexing": "^3.2.0", "jszip": "^3.10.1", "lucide-react": "^0.575.0", @@ -58,8 +51,7 @@ "devDependencies": { "@sketchi/config": "workspace:*", "@tailwindcss/postcss": "^4.2.0", - "@types/jszip": "^3.4.1", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "tailwindcss": "^4.2.0", @@ -92,7 +84,7 @@ "devDependencies": { "@edge-runtime/vm": "^5.0.0", "@sketchi/config": "workspace:*", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "@types/pako": "^2.0.4", "convex-test": "^0.0.41", "typescript": "catalog:", @@ -108,7 +100,6 @@ "version": "0.0.0", "dependencies": { "@t3-oss/env-nextjs": "^0.13.10", - "dotenv": "catalog:", "zod": "catalog:", }, "devDependencies": { @@ -118,13 +109,13 @@ }, "packages/opencode-excalidraw": { "name": "@sketchi-app/opencode-excalidraw", - "version": "0.0.7", + "version": "0.0.9", "dependencies": { "playwright": "^1.58.2", }, "devDependencies": { "@opencode-ai/plugin": "1.2.10", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "bun-types": "1.3.9", "typescript": "^5.9.3", }, @@ -150,20 +141,19 @@ "dependencies": { "@browserbasehq/stagehand": "^3.0.8", "@sketchi/shared": "workspace:*", - "convex": "^1.32.0", - "dotenv": "^17.3.1", - "pako": "^2.1.0", + "dotenv": "catalog:", }, "devDependencies": { "@playwright/test": "^1.58.2", - "@types/bun": "latest", + "@types/bun": "^1.3.12", + "bun-types": "1.3.9", "rrweb-player": "1.0.0-alpha.4", }, }, }, "catalog": { "convex": "^1.31.7", - "dotenv": "^17.2.4", + "dotenv": "^17.4.2", "typescript": "^5", "zod": "^4.1.13", }, @@ -272,23 +262,23 @@ "@base-ui/utils": ["@base-ui/utils@0.2.5", "", { "dependencies": { "@babel/runtime": "^7.28.6", "@floating-ui/utils": "^0.2.10", "reselect": "^5.1.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-oYC7w0gp76RI5MxprlGLV0wze0SErZaRl3AAkeP3OnNB/UBMb6RqNf6ZSIlxOc9Qp68Ab3C2VOcJQyRs7Xc7Vw=="], - "@biomejs/biome": ["@biomejs/biome@2.4.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.4", "@biomejs/cli-darwin-x64": "2.4.4", "@biomejs/cli-linux-arm64": "2.4.4", "@biomejs/cli-linux-arm64-musl": "2.4.4", "@biomejs/cli-linux-x64": "2.4.4", "@biomejs/cli-linux-x64-musl": "2.4.4", "@biomejs/cli-win32-arm64": "2.4.4", "@biomejs/cli-win32-x64": "2.4.4" }, "bin": { "biome": "bin/biome" } }, "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q=="], + "@biomejs/biome": ["@biomejs/biome@2.4.12", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.12", "@biomejs/cli-darwin-x64": "2.4.12", "@biomejs/cli-linux-arm64": "2.4.12", "@biomejs/cli-linux-arm64-musl": "2.4.12", "@biomejs/cli-linux-x64": "2.4.12", "@biomejs/cli-linux-x64-musl": "2.4.12", "@biomejs/cli-win32-arm64": "2.4.12", "@biomejs/cli-win32-x64": "2.4.12" }, "bin": { "biome": "bin/biome" } }, "sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA=="], - "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A=="], + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng=="], - "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg=="], + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A=="], - "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg=="], + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw=="], - "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ=="], + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig=="], - "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg=="], + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw=="], - "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g=="], + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.12", "", { "os": "linux", "cpu": "x64" }, "sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew=="], - "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q=="], + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig=="], - "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.4", "", { "os": "win32", "cpu": "x64" }, "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A=="], + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.12", "", { "os": "win32", "cpu": "x64" }, "sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA=="], "@braintree/sanitize-url": ["@braintree/sanitize-url@6.0.2", "", {}, "sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg=="], @@ -854,25 +844,25 @@ "@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.0", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.0", "@tailwindcss/oxide": "4.2.0", "postcss": "^8.5.6", "tailwindcss": "4.2.0" } }, "sha512-u6YBacGpOm/ixPfKqfgrJEjMfrYmPD7gEFRoygS/hnQaRtV0VCBdpkx5Ouw9pnaLRwwlgGCuJw8xLpaR0hOrQg=="], - "@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.0", "", {}, "sha512-RPfGuk2bDZgcu9bAJodvO2lnZeHuz4/71HjZ0bGb/SPg8+lyTA+RLSKQvo7fSmPSi8/vcH3aKQ8EM9ywf1olaw=="], + "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], - "@tanstack/form-core": ["@tanstack/form-core@1.28.3", "", { "dependencies": { "@tanstack/devtools-event-client": "^0.4.0", "@tanstack/pacer-lite": "^0.1.1", "@tanstack/store": "^0.8.1" } }, "sha512-DBhnu1d5VfACAYOAZJO8tsEUHjWczZMJY8v/YrtAJNWpwvL/3ogDuz8e6yUB2m/iVTNq6K8yrnVN2nrX0/BX/w=="], + "@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="], - "@tanstack/pacer-lite": ["@tanstack/pacer-lite@0.1.1", "", {}, "sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w=="], + "@tsconfig/svelte": ["@tsconfig/svelte@1.0.13", "", {}, "sha512-5lYJP45Xllo4yE/RUBccBT32eBlRDbqN8r1/MIvQbKxW3aFqaYPCNgm8D5V20X4ShHcwvYWNlKg3liDh1MlBoA=="], - "@tanstack/react-form": ["@tanstack/react-form@1.28.3", "", { "dependencies": { "@tanstack/form-core": "1.28.3", "@tanstack/react-store": "^0.8.1" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-84yd0swZRcyC3Q46dYBH6bHf1tlIY1flchbdG3VwArg/wLVW5RdBenIrJhleHjk2OxXuF+9HoKQbHglJyWIXQA=="], + "@turbo/darwin-64": ["@turbo/darwin-64@2.9.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-X/56SnVXIQZBLKwniGTwEQTGmtE5brSACnKMBWpY3YafuxVYefrC2acamfjgxP7BG5w3I+6jf0UrLoSzgPcSJg=="], - "@tanstack/react-store": ["@tanstack/react-store@0.8.1", "", { "dependencies": { "@tanstack/store": "0.8.1", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-XItJt+rG8c5Wn/2L/bnxys85rBpm0BfMbhb4zmPVLXAKY9POrp1xd6IbU4PKoOI+jSEGc3vntPRfLGSgXfE2Ig=="], + "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aalBeSl4agT/QtYGDyf/XLajedWzUC9Vg/pm/YO6QQ93vkQ91Vz5uK1ta5RbVRDozQSz4njxUNqRNmOXDzW+qw=="], - "@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="], + "@turbo/linux-64": ["@turbo/linux-64@2.9.6", "", { "os": "linux", "cpu": "x64" }, "sha512-YKi05jnNHaD7vevgYwahpzGwbsNNTwzU2c7VZdmdFm7+cGDP4oREUWSsainiMfRqjRuolQxBwRn8wf1jmu+YZA=="], - "@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="], + "@turbo/linux-arm64": ["@turbo/linux-arm64@2.9.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-02o/ZS69cOYEDczXvOB2xmyrtzjQ2hVFtWZK1iqxXUfzMmTjZK4UumrfNnjckSg+gqeBfnPRHa0NstA173Ik3g=="], - "@ts-morph/common": ["@ts-morph/common@0.27.0", "", { "dependencies": { "fast-glob": "^3.3.3", "minimatch": "^10.0.1", "path-browserify": "^1.0.1" } }, "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ=="], + "@turbo/windows-64": ["@turbo/windows-64@2.9.6", "", { "os": "win32", "cpu": "x64" }, "sha512-wVdQjvnBI15wB6JrA+43CtUtagjIMmX6XYO758oZHAsCNSxqRlJtdyujih0D8OCnwCRWiGWGI63zAxR0hO6s9g=="], - "@tsconfig/svelte": ["@tsconfig/svelte@1.0.13", "", {}, "sha512-5lYJP45Xllo4yE/RUBccBT32eBlRDbqN8r1/MIvQbKxW3aFqaYPCNgm8D5V20X4ShHcwvYWNlKg3liDh1MlBoA=="], + "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-1XUUyWW0W6FTSqGEhU8RHVqb2wP1SPkr7hIvBlMEwH9jr+sJQK5kqeosLJ/QaUv4ecSAd1ZhIrLoW7qslAzT4A=="], - "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="], + "@types/bun": ["@types/bun@1.3.12", "", { "dependencies": { "bun-types": "1.3.12" } }, "sha512-DBv81elK+/VSwXHDlnH3Qduw+KxkTIWi7TXkAeh24zpi5l0B2kUg9Ga3tb4nJaPcOFswflgi/yAvMVBPrxMB+A=="], "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], @@ -900,15 +890,13 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/jszip": ["@types/jszip@3.4.1", "", { "dependencies": { "jszip": "*" } }, "sha512-TezXjmf3lj+zQ651r6hPqvSScqBLvyPI9FxdXBqpEwBijNGQ2NXpaFW/7joGzveYkKQUil7iiDHLo6LV71Pc0A=="], - "@types/mdast": ["@types/mdast@3.0.15", "", { "dependencies": { "@types/unist": "^2" } }, "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], "@types/mysql": ["@types/mysql@2.15.27", "", { "dependencies": { "@types/node": "*" } }, "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA=="], - "@types/node": ["@types/node@25.3.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A=="], + "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], @@ -1300,7 +1288,7 @@ "dompurify": ["dompurify@3.1.6", "", {}, "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ=="], - "dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="], + "dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], @@ -2240,19 +2228,7 @@ "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="], - "turbo": ["turbo@2.8.10", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.10", "turbo-darwin-arm64": "2.8.10", "turbo-linux-64": "2.8.10", "turbo-linux-arm64": "2.8.10", "turbo-windows-64": "2.8.10", "turbo-windows-arm64": "2.8.10" }, "bin": { "turbo": "bin/turbo" } }, "sha512-OxbzDES66+x7nnKGg2MwBA1ypVsZoDTLHpeaP4giyiHSixbsiTaMyeJqbEyvBdp5Cm28fc+8GG6RdQtic0ijwQ=="], - - "turbo-darwin-64": ["turbo-darwin-64@2.8.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-A03fXh+B7S8mL3PbdhTd+0UsaGrhfyPkODvzBDpKRY7bbeac4MDFpJ7I+Slf2oSkCEeSvHKR7Z4U71uKRUfX7g=="], - - "turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sidzowgWL3s5xCHLeqwC9M3s9M0i16W1nuQF3Mc7fPHpZ+YPohvcbVFBB2uoRRHYZg6yBnwD4gyUHKTeXfwtXA=="], - - "turbo-linux-64": ["turbo-linux-64@2.8.10", "", { "os": "linux", "cpu": "x64" }, "sha512-YK9vcpL3TVtqonB021XwgaQhY9hJJbKKUhLv16osxV0HkcQASQWUqR56yMge7puh6nxU67rQlTq1b7ksR1T3KA=="], - - "turbo-linux-arm64": ["turbo-linux-arm64@2.8.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-3+j2tL0sG95iBJTm+6J8/45JsETQABPqtFyYjVjBbi6eVGdtNTiBmHNKrbvXRlQ3ZbUG75bKLaSSDHSEEN+btQ=="], - - "turbo-windows-64": ["turbo-windows-64@2.8.10", "", { "os": "win32", "cpu": "x64" }, "sha512-hdeF5qmVY/NFgiucf8FW0CWJWtyT2QPm5mIsX0W1DXAVzqKVXGq+Zf+dg4EUngAFKjDzoBeN6ec2Fhajwfztkw=="], - - "turbo-windows-arm64": ["turbo-windows-arm64@2.8.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-QGdr/Q8LWmj+ITMkSvfiz2glf0d7JG0oXVzGL3jxkGqiBI1zXFj20oqVY0qWi+112LO9SVrYdpHS0E/oGFrMbQ=="], + "turbo": ["turbo@2.9.6", "", { "optionalDependencies": { "@turbo/darwin-64": "2.9.6", "@turbo/darwin-arm64": "2.9.6", "@turbo/linux-64": "2.9.6", "@turbo/linux-arm64": "2.9.6", "@turbo/windows-64": "2.9.6", "@turbo/windows-arm64": "2.9.6" }, "bin": { "turbo": "bin/turbo" } }, "sha512-+v2QJey7ZUeUiuigkU+uFfklvNUyPI2VO2vBpMYJA+a1hKFLFiKtUYlRHdb3P9CrAvMzi0upbjI4WT+zKtqkBg=="], "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], @@ -2270,7 +2246,7 @@ "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], - "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], @@ -2438,6 +2414,8 @@ "@browserbasehq/stagehand/ai": ["ai@5.0.124", "", { "dependencies": { "@ai-sdk/gateway": "2.0.30", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Li6Jw9F9qsvFJXZPBfxj38ddP2iURCnMs96f9Q3OeQzrDVcl1hvtwSEAuxA/qmfh6SDV2ERqFUOFzigvr0697g=="], + "@browserbasehq/stagehand/dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="], + "@browserbasehq/stagehand/playwright": ["playwright@1.58.0", "", { "dependencies": { "playwright-core": "1.58.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ=="], "@browserbasehq/stagehand/playwright-core": ["playwright-core@1.58.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw=="], @@ -2560,6 +2538,8 @@ "@ts-morph/common/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], + "@types/bun/bun-types": ["bun-types@1.3.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-HqOLj5PoFajAQciOMRiIZGNoKxDJSr6qigAttOX40vJuSp6DN/CxWp9s3C1Xwm4oH7ybueITwiaOcWXoYVoRkA=="], + "@types/connect/@types/node": ["@types/node@24.10.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw=="], "@types/mysql/@types/node": ["@types/node@24.10.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw=="], diff --git a/package.json b/package.json index 43200dc..ec625e8 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "tests/*" ], "catalog": { - "dotenv": "^17.2.4", + "dotenv": "^17.4.2", "zod": "^4.1.13", "typescript": "^5", "convex": "^1.31.7" @@ -25,17 +25,12 @@ "dev:setup": "turbo -F @sketchi/backend dev:setup", "seed:palantir-icons": "bun --cwd packages/backend run seed:palantir-icons" }, - "dependencies": { - "@sketchi/env": "workspace:*", - "dotenv": "^17.3.1", - "zod": "^4.3.6" - }, "devDependencies": { - "@biomejs/biome": "2.4.4", + "@biomejs/biome": "2.4.12", "@sketchi/config": "workspace:*", - "@types/bun": "^1.3.9", - "@types/node": "^25.3.0", - "turbo": "^2.8.10", + "@types/bun": "^1.3.12", + "@types/node": "^25.6.0", + "turbo": "^2.9.6", "typescript": "^5.9.3", "ultracite": "7.2.3" }, diff --git a/packages/backend/convex/lib/excalidrawShareLinks.ts b/packages/backend/convex/lib/excalidrawShareLinks.ts index e9cf411..fd37b72 100644 --- a/packages/backend/convex/lib/excalidrawShareLinks.ts +++ b/packages/backend/convex/lib/excalidrawShareLinks.ts @@ -629,7 +629,7 @@ async function fetchLinkSharing(sceneId: string): Promise { fields?: { linkSharing?: { integerValue?: string } }; }; const raw = json.fields?.linkSharing?.integerValue; - const value = raw != null ? Number(raw) : Number.NaN; + const value = raw == null ? Number.NaN : Number(raw); return Number.isFinite(value) ? value : undefined; } catch { return undefined; diff --git a/packages/backend/lib/agents/diagram-generator.ts b/packages/backend/lib/agents/diagram-generator.ts deleted file mode 100644 index 5b60534..0000000 --- a/packages/backend/lib/agents/diagram-generator.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { generateObjectWithRetry, getModel } from "../ai-utils"; -import type { IntermediateFormat } from "../diagram-intermediate"; -import { convertIntermediateToDiagram } from "../diagram-layout"; -import { type Diagram, DiagramSchema } from "../diagram-structure"; -import { CHART_VISUAL_SPECS } from "../prompts/chart-specs"; - -const DEFAULT_CHART_PROMPT = `Generate a diagram: -- Use rectangles for main components -- Use ellipses for external entities or start/end points -- Use diamonds for decision points -- Connect related elements with arrows -- Apply colors to group related items`; - -function getChartPrompt(chartType: string): string { - return CHART_VISUAL_SPECS[chartType]?.trim() ?? DEFAULT_CHART_PROMPT; -} - -export interface DiagramGeneratorOptions { - maxRetries?: number; - timeoutMs?: number; -} - -export interface DiagramGeneratorResult { - diagram: Diagram; - durationMs: number; - tokens?: number; -} - -export async function generateDiagram( - intermediate: IntermediateFormat, - options: DiagramGeneratorOptions = {} -): Promise { - const { timeoutMs = 60_000, maxRetries = 2 } = options; - const start = Date.now(); - - const chartType = intermediate.graphOptions?.diagramType ?? "flowchart"; - const chartPrompt = getChartPrompt(chartType); - - const systemPrompt = `You are a diagram element generator. Convert the provided components and relationships into precise diagram elements. - -${chartPrompt} - -Rules: -- Every shape needs a unique id -- Arrow fromId/toId must reference valid shape ids -- Preserve all component labels exactly -- Apply colors from the input if provided -- Use appropriate shapes based on component context`; - - const userPrompt = `Convert this to diagram elements: - -Chart Type: ${chartType} -Layout: ${intermediate.graphOptions?.layout?.direction || "TB"} - -Components: -${intermediate.nodes.map((n) => `- ${n.id}: "${n.label}" (kind: ${n.kind || "default"})`).join("\n")} - -Relationships: -${intermediate.edges.map((r) => `- ${r.fromId} -> ${r.toId}${r.label ? ` [${r.label}]` : ""}`).join("\n")}`; - - const result = await generateObjectWithRetry({ - model: getModel(), - schema: DiagramSchema, - system: systemPrompt, - prompt: userPrompt, - timeoutMs, - maxRetries, - }); - - return { - diagram: result.object as Diagram, - tokens: result.usage?.totalTokens, - durationMs: Date.now() - start, - }; -} - -export function generateDiagramDirect( - intermediate: IntermediateFormat -): Diagram { - return convertIntermediateToDiagram(intermediate); -} diff --git a/packages/backend/lib/json-repair.ts b/packages/backend/lib/json-repair.ts deleted file mode 100644 index 742d91f..0000000 --- a/packages/backend/lib/json-repair.ts +++ /dev/null @@ -1,108 +0,0 @@ -const MARKDOWN_JSON_FENCE_START = /^```(?:json|javascript|js)?\s*\n?/i; -const MARKDOWN_FENCE_END = /\n?```\s*$/; -const JSON_START_PATTERN = /[[{]/; -const TRAILING_COMMA = /,\s*$/; - -function stripMarkdownFences(input: string): string { - return input - .trim() - .replace(MARKDOWN_JSON_FENCE_START, "") - .replace(MARKDOWN_FENCE_END, "") - .trim(); -} - -function findJsonStart(text: string): number { - return text.search(JSON_START_PATTERN); -} - -interface ParseState { - inString: boolean; - isEscaped: boolean; - stack: string[]; -} - -function processCharacter( - ch: string, - state: ParseState -): { complete: boolean } { - if (state.inString) { - if (state.isEscaped) { - state.isEscaped = false; - return { complete: false }; - } - if (ch === "\\") { - state.isEscaped = true; - return { complete: false }; - } - if (ch === '"') { - state.inString = false; - } - return { complete: false }; - } - - if (ch === '"') { - state.inString = true; - return { complete: false }; - } - - if (ch === "{") { - state.stack.push("}"); - return { complete: false }; - } - - if (ch === "[") { - state.stack.push("]"); - return { complete: false }; - } - - if (ch === "}" || ch === "]") { - if (state.stack.length && state.stack.at(-1) === ch) { - state.stack.pop(); - } - if (state.stack.length === 0) { - return { complete: true }; - } - } - - return { complete: false }; -} - -function closeUnclosedBrackets(text: string, state: ParseState): string { - let result = text; - if (state.inString) { - result += '"'; - } - result = result.replace(TRAILING_COMMA, ""); - while (state.stack.length) { - result += state.stack.pop(); - } - return result; -} - -export function repairJsonClosure(input: string): string { - const processed = stripMarkdownFences(input); - const start = findJsonStart(processed); - - if (start === -1) { - return processed; - } - - const state: ParseState = { - inString: false, - isEscaped: false, - stack: [], - }; - - for (let i = start; i < processed.length; i++) { - const char = processed[i]; - if (char === undefined) { - continue; - } - const result = processCharacter(char, state); - if (result.complete) { - return processed.slice(start, i + 1); - } - } - - return closeUnclosedBrackets(processed.slice(start), state); -} diff --git a/packages/backend/lib/output.ts b/packages/backend/lib/output.ts deleted file mode 100644 index f401943..0000000 --- a/packages/backend/lib/output.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { mkdir, writeFile } from "node:fs/promises"; -import { join } from "node:path"; - -const OUTPUT_DIR = join(import.meta.dirname, "../output"); - -function getTimestamp(): string { - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, "0"); - const day = String(now.getDate()).padStart(2, "0"); - const hours = String(now.getHours()).padStart(2, "0"); - const minutes = String(now.getMinutes()).padStart(2, "0"); - const seconds = String(now.getSeconds()).padStart(2, "0"); - return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}`; -} - -export interface OutputSession { - dir: string; - saveJson: (name: string, data: unknown) => Promise; - savePng: (name: string, buffer: Buffer) => Promise; - saveText: (name: string, content: string) => Promise; - timestamp: string; -} - -export async function createOutputSession( - prefix = "run" -): Promise { - const timestamp = getTimestamp(); - const dir = join(OUTPUT_DIR, `${prefix}_${timestamp}`); - await mkdir(dir, { recursive: true }); - - const saveJson = async (name: string, data: unknown): Promise => { - const path = join(dir, `${name}.json`); - await writeFile(path, JSON.stringify(data, null, 2)); - return path; - }; - - const savePng = async (name: string, buffer: Buffer): Promise => { - const path = join(dir, `${name}.png`); - await writeFile(path, buffer); - return path; - }; - - const saveText = async (name: string, content: string): Promise => { - const path = join(dir, `${name}.txt`); - await writeFile(path, content); - return path; - }; - - return { dir, timestamp, saveJson, savePng, saveText }; -} diff --git a/packages/backend/package.json b/packages/backend/package.json index 97fcd0b..9707cb3 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -34,7 +34,7 @@ "devDependencies": { "@edge-runtime/vm": "^5.0.0", "@sketchi/config": "workspace:*", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "@types/pako": "^2.0.4", "convex-test": "^0.0.41", "typescript": "catalog:", diff --git a/packages/env/package.json b/packages/env/package.json index 6a4cb39..e87c21b 100644 --- a/packages/env/package.json +++ b/packages/env/package.json @@ -8,7 +8,6 @@ }, "dependencies": { "@t3-oss/env-nextjs": "^0.13.10", - "dotenv": "catalog:", "zod": "catalog:" }, "devDependencies": { diff --git a/packages/opencode-excalidraw/package.json b/packages/opencode-excalidraw/package.json index 47624fa..3e0566e 100644 --- a/packages/opencode-excalidraw/package.json +++ b/packages/opencode-excalidraw/package.json @@ -38,7 +38,7 @@ }, "devDependencies": { "@opencode-ai/plugin": "1.2.10", - "@types/node": "^25.3.0", + "@types/node": "^25.6.0", "bun-types": "1.3.9", "typescript": "^5.9.3" }, diff --git a/packages/shared/src/excalidraw-share-links.ts b/packages/shared/src/excalidraw-share-links.ts index 2cad354..0879784 100644 --- a/packages/shared/src/excalidraw-share-links.ts +++ b/packages/shared/src/excalidraw-share-links.ts @@ -567,7 +567,7 @@ async function fetchLinkSharing(sceneId: string): Promise { fields?: { linkSharing?: { integerValue?: string } }; }; const raw = json.fields?.linkSharing?.integerValue; - const value = raw != null ? Number(raw) : Number.NaN; + const value = raw == null ? Number.NaN : Number(raw); return Number.isFinite(value) ? value : undefined; } catch { return undefined; diff --git a/tests/api/plan/parse-v2-share-link.ts b/tests/api/plan/parse-v2-share-link.ts deleted file mode 100644 index 2a3a3a8..0000000 --- a/tests/api/plan/parse-v2-share-link.ts +++ /dev/null @@ -1,3 +0,0 @@ -// Scenario: Parse V2 Excalidraw share link via public API. -// - Call /api/diagrams/parse with a known V2 share URL. -// - Assert status 200 and expected counts for nodes/elements/edges. diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 7460203..9aba34d 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -11,18 +11,18 @@ "excalidraw-plus-links": "bun run src/scenarios/unauthenticated/excalidraw-plus-links.ts", "diagram-studio-happy-path": "bun run src/scenarios/unauthenticated/diagram-studio-happy-path.ts", "diagram-studio-occ-conflict": "bun run src/scenarios/unauthenticated/diagram-studio-occ-conflict.ts", - "opencode-web-continuity": "bun run src/scenarios/unauthenticated/opencode-web-continuity.ts" + "opencode-web-continuity": "bun run src/scenarios/unauthenticated/opencode-web-continuity.ts", + "run-scenarios": "bun run scripts/run-scenarios.ts" }, "dependencies": { "@browserbasehq/stagehand": "^3.0.8", "@sketchi/shared": "workspace:*", - "convex": "^1.32.0", - "dotenv": "^17.3.1", - "pako": "^2.1.0" + "dotenv": "catalog:" }, "devDependencies": { "@playwright/test": "^1.58.2", - "@types/bun": "latest", + "@types/bun": "^1.3.12", + "bun-types": "1.3.9", "rrweb-player": "1.0.0-alpha.4" } } diff --git a/tests/e2e/src/scenarios/unauthenticated/diagram-studio-occ-conflict.ts b/tests/e2e/src/scenarios/unauthenticated/diagram-studio-occ-conflict.ts index cb0fcf5..c3df2ef 100644 --- a/tests/e2e/src/scenarios/unauthenticated/diagram-studio-occ-conflict.ts +++ b/tests/e2e/src/scenarios/unauthenticated/diagram-studio-occ-conflict.ts @@ -272,18 +272,18 @@ async function main() { await sleep(1200); await addCanvasElement(pageB); - if (versionAValue !== null) { + if (versionAValue === null) { + const savedA2 = await waitForSaveStatus(pageA, "Saved", 35_000); + if (!savedA2) { + throw new Error("Tab A second save did not complete."); + } + } else { const advanced = await waitForVersionAtLeast(pageA, versionAValue + 1); if (!advanced) { throw new Error( `Tab A version did not advance to >= v${versionAValue + 1}.` ); } - } else { - const savedA2 = await waitForSaveStatus(pageA, "Saved", 35_000); - if (!savedA2) { - throw new Error("Tab A second save did not complete."); - } } const versionA2 = await getTestIdText(pageA, "diagram-session-version"); console.log(` Tab A new version: ${versionA2}`); diff --git a/tests/e2e/src/scenarios/unauthenticated/icon-library-generator-invalid-svg.ts b/tests/e2e/src/scenarios/unauthenticated/icon-library-generator-invalid-svg.ts deleted file mode 100644 index 290e20f..0000000 --- a/tests/e2e/src/scenarios/unauthenticated/icon-library-generator-invalid-svg.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* -Scenario: Icon library generator invalid SVG handling - -Intent: Ensure invalid SVG uploads are rejected without breaking the editor. - -Steps: -- Visit Icon Library Generator. -- Create a new library. -- Attempt to upload an invalid SVG (malformed or non-SVG file renamed .svg). - -Success: -- UI shows a clear error toast. -- No icons are added to the grid. -- Editor remains usable (upload valid SVG afterward works). -*/ diff --git a/tests/e2e/src/scenarios/unauthenticated/mcp-v2-share-link.ts b/tests/e2e/src/scenarios/unauthenticated/mcp-v2-share-link.ts index d36db46..e1f00fa 100644 --- a/tests/e2e/src/scenarios/unauthenticated/mcp-v2-share-link.ts +++ b/tests/e2e/src/scenarios/unauthenticated/mcp-v2-share-link.ts @@ -24,8 +24,8 @@ Success: import { mkdir, readFile, writeFile } from "node:fs/promises"; import { join } from "node:path"; +import { chromium } from "@playwright/test"; import { parseExcalidrawShareLink } from "@sketchi/shared"; -import { chromium } from "playwright"; const FIXTURE_PATH = join( import.meta.dir,