├── public └── favicon.ico ├── src ├── vite-env.d.ts ├── components │ ├── ui │ │ ├── aspect-ratio.tsx │ │ ├── skeleton.tsx │ │ ├── collapsible.tsx │ │ ├── label.tsx │ │ ├── textarea.tsx │ │ ├── separator.tsx │ │ ├── progress.tsx │ │ ├── input.tsx │ │ ├── toaster.tsx │ │ ├── sonner.tsx │ │ ├── checkbox.tsx │ │ ├── slider.tsx │ │ ├── switch.tsx │ │ ├── tooltip.tsx │ │ ├── badge.tsx │ │ ├── hover-card.tsx │ │ ├── popover.tsx │ │ ├── avatar.tsx │ │ ├── toggle.tsx │ │ ├── radio-group.tsx │ │ ├── scroll-area.tsx │ │ ├── alert.tsx │ │ ├── resizable.tsx │ │ ├── toggle-group.tsx │ │ ├── button.tsx │ │ ├── tabs.tsx │ │ ├── accordion.tsx │ │ ├── card.tsx │ │ ├── input-otp.tsx │ │ ├── calendar.tsx │ │ ├── breadcrumb.tsx │ │ ├── pagination.tsx │ │ ├── table.tsx │ │ ├── drawer.tsx │ │ ├── dialog.tsx │ │ ├── use-toast.ts │ │ ├── sheet.tsx │ │ ├── form.tsx │ │ ├── alert-dialog.tsx │ │ ├── toast.tsx │ │ ├── command.tsx │ │ ├── navigation-menu.tsx │ │ ├── select.tsx │ │ ├── carousel.tsx │ │ ├── context-menu.tsx │ │ ├── dropdown-menu.tsx │ │ ├── menubar.tsx │ │ └── chart.tsx │ └── layout.tsx ├── lib │ └── utils.ts ├── styled-jsx.d.ts ├── index.css ├── main.tsx └── artifacts │ ├── index.tsx │ └── signup.tsx ├── postcss.config.js ├── npx ├── docker │ ├── .dockerignore │ ├── Dockerfile │ ├── build │ ├── README.md │ └── publish ├── package.json ├── publish.js └── README.md ├── jsconfig.json ├── tsconfig.json ├── .gitignore ├── tsconfig.node.json ├── components.json ├── index.html ├── .eslintrc.cjs ├── .github └── workflows │ └── ci.yml ├── tsconfig.app.json ├── LICENSE ├── README.default.md ├── vite.single.config.ts ├── vite.config.ts ├── tailwind.config.mjs ├── package.json └── bin └── test-pr.sh /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/claudio-silva/claude-artifact-runner/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /npx/docker/.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .git 4 | .gitignore 5 | *.md 6 | .vscode 7 | .idea 8 | *.log 9 | .DS_Store 10 | 11 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" 2 | 3 | const AspectRatio = AspectRatioPrimitive.Root 4 | 5 | export { AspectRatio } 6 | -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /src/styled-jsx.d.ts: -------------------------------------------------------------------------------- 1 | import 'react'; 2 | 3 | declare module 'react' { 4 | interface StyleHTMLAttributes extends React.HTMLAttributes { 5 | jsx?: boolean; 6 | global?: boolean; 7 | } 8 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.app.json" 6 | }, 7 | { 8 | "path": "./tsconfig.node.json" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/components/layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function Layout({ children }: { children: React.ReactNode }) { 4 | return ( 5 | <> 6 | {children} 7 | 8 | ); 9 | } -------------------------------------------------------------------------------- /src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "src/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /.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 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" 2 | 3 | const Collapsible = CollapsiblePrimitive.Root 4 | 5 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 6 | 7 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 8 | 9 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 10 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 5 | "skipLibCheck": true, 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "noEmit": true 11 | }, 12 | "include": ["vite.config.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": false, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/index.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "src/components", 15 | "utils": "src/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Artifact Viewer 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /npx/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:23.11.0-alpine 2 | 3 | # Install git (required by run-claude-artifact to clone the template) 4 | RUN apk add --no-cache git 5 | 6 | # Set working directory 7 | WORKDIR /app 8 | 9 | # Clear npm cache and install the run-claude-artifact package globally 10 | # Using --force ensures we get the latest version even if cached 11 | RUN npm cache clean --force && \ 12 | npm install -g run-claude-artifact@latest --force 13 | 14 | # Create entrypoint script that forwards arguments to npx 15 | RUN echo '#!/bin/sh' > /entrypoint.sh && \ 16 | echo 'exec npx run-claude-artifact --no-open --public "$@"' >> /entrypoint.sh && \ 17 | chmod +x /entrypoint.sh 18 | 19 | # Set entrypoint 20 | ENTRYPOINT ["/entrypoint.sh"] 21 | 22 | # Default command (can be overridden) 23 | CMD ["--help"] 24 | 25 | -------------------------------------------------------------------------------- /npx/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "run-claude-artifact", 3 | "version": "2.2.1", 4 | "description": "Run Claude AI Artifacts locally - quick preview, or create projects, build, deploy, and push to a Git repository.", 5 | "bin": { 6 | "run-claude-artifact": "./run-claude-artifact.js" 7 | }, 8 | "scripts": { 9 | "build": "echo \"nothing to build\"", 10 | "test": "node run-claude-artifact.js --help", 11 | "publish:package": "node publish.js" 12 | }, 13 | "author": "Cláudio Silva", 14 | "license": "MIT", 15 | "keywords": [ 16 | "claude", 17 | "artifact", 18 | "react", 19 | "vite", 20 | "typescript", 21 | "tailwindcss", 22 | "shadcn-ui" 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "https://github.com/claudio-silva/claude-artifact-runner" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import * as LabelPrimitive from "@radix-ui/react-label" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "src/lib/utils" 6 | 7 | const labelVariants = cva( 8 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 9 | ) 10 | 11 | const Label = React.forwardRef< 12 | React.ElementRef, 13 | React.ComponentPropsWithoutRef & 14 | VariantProps 15 | >(({ className, ...props }, ref) => ( 16 | 21 | )) 22 | Label.displayName = LabelPrimitive.Root.displayName 23 | 24 | export { Label } 25 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | '@typescript-eslint/no-unused-vars': ['error', { 18 | argsIgnorePattern: '^_', 19 | varsIgnorePattern: '^_', 20 | }], 21 | }, 22 | overrides: [ 23 | { 24 | files: ['**/components/ui/**/*.tsx'], 25 | rules: { 26 | 'react-refresh/only-export-components': 'off' 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "src/lib/utils" 4 | 5 | export type TextareaProps = React.TextareaHTMLAttributes 6 | 7 | const Textarea = React.forwardRef( 8 | ({ className, ...props }, ref) => { 9 | return ( 10 |