| import gradio as gr |
| from github import Github, GithubException |
| import os |
| import requests |
| import re |
| from collections import Counter |
| import jinja2 |
| from diff_match_patch import diff_match_patch |
|
|
| |
| GITHUB_TOKEN = os.getenv('GITHUB_TOKEN') |
| if not GITHUB_TOKEN: |
| raise ValueError("GITHUB_TOKEN environment variable not set!") |
| g = Github(GITHUB_TOKEN) |
|
|
| |
| PROJECT_TEMPLATES = { |
| "flask": { |
| "params": { |
| "database_type": { |
| "type": "choice", |
| "default": "sqlite", |
| "choices": ["sqlite", "postgresql", "mysql"], |
| "description": "Type of database to configure for the Flask app." |
| } |
| }, |
| "files": { |
| "app.py": """from flask import Flask |
| from flask_sqlalchemy import SQLAlchemy |
| import os |
| basedir = os.path.abspath(os.path.dirname(__file__)) |
| app = Flask(__name__) |
| app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or \\ |
| '{{database_uri}}' # Placeholder for database URI |
| app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False |
| db = SQLAlchemy(app) |
| class HelloWorld(db.Model): |
| id = db.Column(db.Integer, primary_key=True) |
| message = db.Column(db.String(128)) |
| def __repr__(self): |
| return f'<HelloWorld {self.message}>' |
| @app.route('/') |
| def hello(): |
| return "Hello, Flask!" |
| @app.route('/db_test') |
| def db_test(): |
| try: |
| HelloWorld.query.first() # Simple DB query to test connection |
| return "Database connection successful!" |
| except Exception as e: |
| return f"Database connection failed: {e}" |
| if __name__ == '__main__': |
| with app.app_context(): # Create application context for DB operations |
| db.create_all() |
| if not HelloWorld.query.first(): # Initialize DB with a default entry if empty |
| default_hello = HelloWorld(message="Hello, Database!") |
| db.session.add(default_hello) |
| db.session.commit() |
| app.run(debug=True)""", |
| "requirements.txt": """Flask |
| Flask-SQLAlchemy |
| {{sqlalchemy_dependency}} # Placeholder for SQLAlchemy dependency""", |
| ".gitignore": "__pycache__/\n*.pyc\nvenv/\ninstance/\n*.db" |
| }, |
| "post_process": "install_dependencies" |
| }, |
| "react": { |
| "files": { |
| "package.json": """{ |
| "name": "react-app", |
| "private": true, |
| "version": "0.0.0", |
| "type": "module", |
| "scripts": { |
| "dev": "vite", |
| "build": "vite build", |
| "preview": "vite preview" |
| }, |
| "dependencies": { |
| "react": "^18.2.0", |
| "react-dom": "^18.2.0" |
| }, |
| "devDependencies": { |
| "@vitejs/plugin-react": "^4.2.1", |
| "vite": "^5.0.8" |
| }}""", |
| "vite.config.js": """import { defineConfig } from 'vite' |
| import react from '@vitejs/plugin-react' |
| # https://vitejs.dev/config/ |
| export default defineConfig({ |
| plugins: [react()], |
| })""", |
| "index.html": """<!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Vite + React</title> |
| </head> |
| <body> |
| <div id="root"></div> |
| <script type="module" src="/src/main.jsx"></script> |
| </body> |
| </html>""", |
| "src/main.jsx": """import React from 'react' |
| import ReactDOM from 'react-dom/client' |
| import App from './App.jsx' |
| import './index.css' |
| ReactDOM.createRoot(document.getElementById('root')).render( |
| <React.StrictMode> |
| <App /> |
| </React.StrictMode>, |
| )""", |
| "src/App.jsx": """import React from 'react' |
| import './App.css' |
| function App() { |
| return ( |
| <> |
| <h1>Hello from React!</h1> |
| </> |
| ) |
| } |
| export default App""", |
| "src/index.css": """body { |
| margin: 0; |
| font-family: sans-serif; |
| -webkit-font-smoothing: antialiased; |
| -moz-osx-font-smoothing: grayscale; |
| } |
| code { |
| font-family: monospace; |
| }""", |
| ".gitignore": "node_modules/\ndist/" |
| } |
| }, |
| "django": { |
| "files": { |
| "manage.py": """#!/usr/bin/env python |
| import os |
| import sys |
| if __name__ == "__main__": |
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings") |
| try: |
| from django.core.management import execute_from_command_line |
| except ImportError as exc: |
| raise ImportError( |
| "Couldn't import Django. Are you sure it is installed and " |
| "available on your PYTHONPATH environment variable? Did you " |
| "forget to activate a virtual environment?" |
| ) from exc |
| execute_from_command_line(sys.argv)""", |
| "myapp/settings.py": """import os |
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| SECRET_KEY = 'your_secret_key_here' |
| DEBUG = True |
| ALLOWED_HOSTS = [] |
| INSTALLED_APPS = [ |
| 'django.contrib.admin', |
| 'django.contrib.auth', |
| 'django.contrib.contenttypes', |
| 'django.contrib.sessions', |
| 'django.contrib.messages', |
| 'django.contrib.staticfiles', |
| ] |
| MIDDLEWARE = [ |
| 'django.middleware.security.SecurityMiddleware', |
| 'django.contrib.sessions.middleware.SessionMiddleware', |
| 'django.middleware.common.CommonMiddleware', |
| 'django.middleware.csrf.CsrfViewMiddleware', |
| 'django.contrib.auth.middleware.AuthenticationMiddleware', |
| 'django.contrib.messages.middleware.MessageMiddleware', |
| 'django.middleware.clickjacking.XFrameOptionsMiddleware', |
| ] |
| ROOT_URLCONF = 'myapp.urls' |
| TEMPLATES = [ |
| { |
| 'BACKEND': 'django.template.backends.django.DjangoTemplates', |
| 'DIRS': [], |
| 'APP_DIRS': True, |
| 'OPTIONS': { |
| 'context_processors': [ |
| 'django.template.context_processors.debug', |
| 'django.template.context_processors.request', |
| 'django.contrib.auth.context_processors.auth', |
| 'django.contrib.messages.context_processors.messages', |
| ], |
| }, |
| }, |
| ] |
| WSGI_APPLICATION = 'myapp.wsgi.application' |
| DATABASES = { |
| 'default': { |
| 'ENGINE': 'django.db.backends.sqlite3', |
| 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), |
| } |
| } |
| AUTH_PASSWORD_VALIDATORS = [ |
| {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',}, |
| {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',}, |
| {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',}, |
| {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',}, |
| ] |
| LANGUAGE_CODE = 'en-us' |
| TIME_ZONE = 'UTC' |
| USE_I18N = True |
| USE_L10N = True |
| USE_TZ = True |
| STATIC_URL = '/static/' |
| """, |
| "myapp/urls.py": """from django.contrib import admin |
| from django.urls import path |
| from django.http import HttpResponse |
| def home(request): |
| return HttpResponse("Hello, Django!") |
| urlpatterns = [ |
| path('admin/', admin.site.urls), |
| path('', home, name='home'), |
| ]""", |
| "myapp/wsgi.py": """import os |
| from django.core.wsgi import get_wsgi_application |
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings") |
| application = get_wsgi_application()""", |
| "requirements.txt": "Django", |
| ".gitignore": "__pycache__/\n*.pyc\nvenv/\ndb.sqlite3\n", |
| }, |
| "rename_files": {"myapp": "{{repo_name_snake_case}}"} |
| }, |
| "nodejs_express": { |
| "files": { |
| "server.js": """const express = require('express') |
| const app = express() |
| const port = 3000 |
| app.get('/', (req, res) => { |
| res.send('Hello World from Express!') |
| }) |
| app.listen(port, () => { |
| console.log(`Server listening on port ${port}`) |
| })""", |
| "package.json": """{ |
| "name": "express-app", |
| "version": "1.0.0", |
| "description": "", |
| "main": "server.js", |
| "scripts": { |
| "start": "node server.js" |
| }, |
| "dependencies": { |
| "express": "^4.17.1" |
| } |
| }""", |
| ".gitignore": "node_modules/\n" |
| } |
| }, |
| "static_website": { |
| "files": { |
| "index.html": """<!DOCTYPE html> |
| <html> |
| <head> |
| <title>Simple Static Website</title> |
| </head> |
| <body> |
| <h1>Hello from Static Website!</h1> |
| <p>This is a basic HTML page.</p> |
| </body> |
| </html>""", |
| "style.css": """body { |
| font-family: sans-serif; |
| margin: 20px; |
| }""", |
| "script.js": """console.log("Hello from JavaScript!");""", |
| ".gitignore": "" |
| } |
| }, |
| "python_script": { |
| "files": { |
| "main.py": """def main(): |
| print("Hello from Python script!") |
| if __name__ == "__main__": |
| main()""", |
| "requirements.txt": "", |
| ".gitignore": "__pycache__/\n*.pyc\nvenv/\n" |
| } |
| }, |
| "empty": { |
| "files": { |
| "README.md": "# {{repo_name}}", |
| ".gitignore": "" |
| }, |
| "rename_files": {"README.md": "{{readme_filename}}"} |
| }, |
| "shadcn": { |
| "files": { |
| "package.json": """{ |
| "name": "shadcn-react-app", |
| "private": true, |
| "version": "0.0.0", |
| "type": "module", |
| "scripts": { |
| "dev": "vite", |
| "build": "vite build", |
| "preview": "vite preview", |
| "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", |
| "preview": "vite preview" |
| }, |
| "dependencies": { |
| "@radix-ui/react-slot": "^1.0.2", |
| "class-variance-authority": "^0.7.0", |
| "clsx": "^2.1.0", |
| "lucide-react": "^0.303.0", |
| "react": "^18.2.0", |
| "react-dom": "^18.2.0", |
| "tailwind-merge": "^2.2.0", |
| "tailwindcss-animate": "^1.0.7" |
| }, |
| "devDependencies": { |
| "@vitejs/plugin-react": "^4.2.1", |
| "autoprefixer": "^10.4.16", |
| "eslint": "^8.55.0", |
| "eslint-plugin-react": "^7.33.2", |
| "eslint-plugin-react-hooks": "^4.6.0", |
| "eslint-plugin-react-refresh": "^0.4.5", |
| "postcss": "^8.4.33", |
| "tailwindcss": "^3.4.1", |
| "vite": "^5.0.8" |
| } |
| }""", |
| "vite.config.js": """import { defineConfig } from 'vite' |
| import react from '@vitejs/plugin-react' |
| # https://vitejs.dev/config/ |
| export default defineConfig({ |
| plugins: [react()], |
| })""", |
| "index.html": """<!doctype html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Vite + React + Shadcn</title> |
| </head> |
| <body class="bg-background"> |
| <div id="root"></div> |
| <script type="module" src="/src/main.jsx"></script> |
| </body> |
| </html>""", |
| "src/main.jsx": """import React from 'react' |
| import ReactDOM from 'react-dom/client' |
| import App from './App.jsx' |
| import './index.css' |
| ReactDOM.createRoot(document.getElementById('root')).render( |
| <React.StrictMode> |
| <App /> |
| </React.StrictMode>, |
| )""", |
| "src/App.jsx": """import React from 'react' |
| import { Button } from "./components/ui/button" |
| import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./components/ui/card" |
| function App() { |
| return ( |
| <div className="container mx-auto py-10"> |
| <h1 className="text-3xl font-bold text-center mb-5"> |
| Witaj w aplikacji Shadcn UI! |
| </h1> |
| <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> |
| <Card> |
| <CardHeader> |
| <CardTitle>Karta 1</CardTitle> |
| <CardDescription>Prosta karta z Shadcn UI.</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <p>Zawartość karty.</p> |
| <Button className="mt-4">Przycisk Akcji</Button> |
| </CardContent> |
| </Card> |
| <Card> |
| <CardHeader> |
| <CardTitle>Karta 2</CardTitle> |
| <CardDescription>Kolejna karta dla przykładu.</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <p>Więcej zawartości.</p> |
| <Button variant="secondary" className="mt-4">Przycisk Wtórny</Button> |
| </CardContent> |
| </Card> |
| <Card className="lg:col-span-1 md:col-span-2"> |
| <CardHeader> |
| <CardTitle>Dłuższa Karta</CardTitle> |
| <CardDescription>Karta zajmująca więcej miejsca.</CardDescription> |
| </CardHeader> |
| <CardContent> |
| <p> |
| Ta karta demonstruje jak karty mogą dostosowywać się do różnych |
| rozmiarów ekranów i układów. Shadcn UI i Tailwind CSS |
| dają dużą elastyczność w projektowaniu interfejsów. |
| </p> |
| <Button variant="destructive" className="mt-4">Przycisk Destrukcyjny</Button> |
| </CardContent> |
| </Card> |
| </div> |
| </div> |
| ) |
| } |
| export default App""", |
| "src/index.css": """@tailwind base; |
| @tailwind components; |
| @tailwind utilities; |
| @layer base { |
| :root { |
| --background: 0 0% 100%; |
| --foreground: 222.2 84.9% 4.9%; |
| --card: 0 0% 100%; |
| --card-foreground: 222.2 84.9% 4.9%; |
| --popover: 0 0% 100%; |
| --popover-foreground: 222.2 84.9% 4.9%; |
| --primary: 221.2 83.2% 53.3%; |
| --primary-foreground: 210 40% 98%; |
| --secondary: 210 40% 96.1%; |
| --secondary-foreground: 222.2 47.4% 11.2%; |
| --muted: 210 40% 96.1%; |
| --muted-foreground: 215.4 16.3% 46.9%; |
| --accent: 210 40% 96.1%; |
| --accent-foreground: 222.2 47.4% 11.2%; |
| --destructive: 0 84.2% 60.2%; |
| --destructive-foreground: 210 40% 98%; |
| --border: 214.3 31.8% 91.4%; |
| --input: 214.3 31.8% 91.4%; |
| --ring: 221.2 83.2% 53.3%; |
| --radius: 0.5rem; |
| } |
| .dark { |
| --background: 222.2 84.9% 4.9%; |
| --foreground: 210 40% 98%; |
| --card: 222.2 84.9% 4.9%; |
| --card-foreground: 210 40% 98%; |
| --popover: 222.2 84.9% 4.9%; |
| --popover-foreground: 210 40% 98%; |
| --primary: 217.2 91.2% 59.8%; |
| --primary-foreground: 222.2 47.4% 11.2%; |
| --secondary: 217.2 32.6% 17.5%; |
| --secondary-foreground: 210 40% 98%; |
| --muted: 217.2 32.6% 17.5%; |
| --muted-foreground: 215 20.2% 65.1%; |
| --accent: 217.2 32.6% 17.5%; |
| --accent-foreground: 210 40% 98%; |
| --destructive: 0 62.8% 30.6%; |
| --destructive-foreground: 210 40% 98%; |
| --border: 217.2 32.6% 17.5%; |
| --input: 217.2 32.6% 17.5%; |
| --ring: 224.9 98.6% 67.3%; |
| } |
| } |
| @layer components { |
| .container { |
| @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8; |
| } |
| } |
| """, |
| "postcss.config.js": """module.exports = { |
| plugins: { |
| tailwindcss: {}, |
| autoprefixer: {}, |
| }, |
| }""", |
| "tailwind.config.js": """/** @type {import('tailwindcss').Config} */ |
| module.exports = { |
| darkMode: ["class"], |
| content: [ |
| './pages/**/*.{js,jsx}', |
| './components/**/*.{js,jsx}', |
| './app/**/*.{js,jsx}', |
| './src/**/*.{js,jsx}', |
| ], |
| prefix: "", |
| theme: { |
| container: { |
| center: true, |
| padding: "2rem", |
| screens: { |
| "2xl": "1400px", |
| }, |
| }, |
| extend: { |
| colors: { |
| border: "hsl(var(--border))", |
| input: "hsl(var(--input))", |
| ring: "hsl(var(--ring))", |
| background: "hsl(var(--background))", |
| foreground: "hsl(var(--foreground))", |
| primary: { |
| DEFAULT: "hsl(var(--primary))", |
| foreground: "hsl(var(--primary-foreground))", |
| }, |
| secondary: { |
| DEFAULT: "hsl(var(--secondary))", |
| foreground: "hsl(var(--secondary-foreground))", |
| }, |
| destructive: { |
| DEFAULT: "hsl(var(--destructive))", |
| foreground: "hsl(var(--destructive-foreground))", |
| }, |
| muted: { |
| DEFAULT: "hsl(var(--muted))", |
| foreground: "hsl(var(--muted-foreground))", |
| }, |
| accent: { |
| DEFAULT: "hsl(var(--accent))", |
| foreground: "hsl(var(--accent-foreground))", |
| }, |
| popover: { |
| DEFAULT: "hsl(var(--popover))", |
| foreground: "hsl(var(--popover-foreground))", |
| }, |
| card: { |
| DEFAULT: "hsl(var(--card))", |
| foreground: "hsl(var(--card-foreground))", |
| }, |
| }, |
| borderRadius: { |
| lg: "var(--radius)", |
| md: "calc(var(--radius) - 2px)", |
| sm: "calc(var(--radius) - 4px)", |
| }, |
| keyframes: { |
| "accordion-down": { |
| from: { height: "0" }, |
| to: { height: "var(--radix-accordion-content-height)" }, |
| }, |
| "accordion-up": { |
| from: { height: "var(--radix-accordion-content-height)" }, |
| to: { height: "0" }, |
| }, |
| }, |
| animation: { |
| "accordion-down": "accordion-down 0.2s ease-out", |
| "accordion-up": "accordion-up 0.2s ease-out", |
| }, |
| }, |
| }, |
| plugins: [require("tailwindcss-animate")], |
| }""", |
| "src/components/ui/button.jsx": """import * as React from "react" |
| import { cn } from "@/lib/utils" |
| import { Slot } from "@radix-ui/react-slot" |
| import { cva } from "class-variance-authority"; |
| const buttonVariants = cva( |
| "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", |
| { |
| variants: { |
| variant: { |
| default: "bg-primary text-primary-foreground hover:bg-primary/90", |
| destructive: |
| "bg-destructive text-destructive-foreground hover:bg-destructive/90", |
| outline: |
| "border border-input bg-background hover:bg-accent hover:text-accent-foreground", |
| secondary: |
| "bg-secondary text-secondary-foreground hover:bg-secondary/80", |
| ghost: "hover:bg-accent hover:text-accent-foreground", |
| link: "underline-offset-4 hover:underline text-primary", |
| }, |
| size: { |
| default: "h-10 px-4 py-2", |
| sm: "h-9 rounded-md px-3", |
| lg: "h-11 rounded-md px-8", |
| icon: "h-10 w-10", |
| }, |
| }, |
| defaultVariants: { |
| variant: "default", |
| size: "default", |
| }, |
| } |
| ) |
| const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => { |
| const Comp = asChild ? Slot : "button" |
| return (<Comp |
| className={cn(buttonVariants({ variant, size, className }))} |
| ref={ref} {...props} />) |
| }) |
| Button.displayName = "Button" |
| export { Button, buttonVariants }""", |
| "src/components/ui/card.jsx": """import * as React from "react" |
| import { cn } from "@/lib/utils" |
| const Card = React.forwardRef(({ className, ...props }, ref) => (<div |
| className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)} |
| ref={ref} |
| {...props} />)) |
| Card.displayName = "Card" |
| const CardHeader = React.forwardRef(({ className, ...props }, ref) => (<div |
| className={cn("flex flex-col space-y-1.5 p-6", className)} |
| ref={ref} |
| {...props} />)) |
| CardHeader.displayName = "CardHeader" |
| const CardTitle = React.forwardRef(({ className, ...props }, ref) => (<h3 |
| className={cn("text-lg font-semibold leading-none tracking-tight", className)} |
| ref={ref} |
| {...props} />)) |
| CardTitle.displayName = "CardTitle" |
| const CardDescription = React.forwardRef(({ className, ...props }, ref) => (<p |
| className={cn("text-sm text-muted-foreground", className)} |
| ref={ref} |
| {...props} />)) |
| CardDescription.displayName = "CardDescription" |
| const CardContent = React.forwardRef(({ className, ...props }, ref) => (<div |
| className={cn("p-6 pt-0", className)} |
| ref={ref} |
| {...props} />)) |
| CardContent.displayName = "CardContent" |
| const CardFooter = React.forwardRef(({ className, ...props }, ref) => (<div |
| className={cn("flex items-center p-6 pt-0", className)} |
| ref={ref} |
| {...props} />)) |
| CardFooter.displayName = "CardFooter" |
| export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }""", |
| "src/lib/utils.js": """import { clsx } from "clsx" |
| import { twMerge } from "tailwind-merge" |
| |
| export function cn(...inputs) { |
| return twMerge(clsx(inputs)) |
| }""" |
| }, |
| "post_process": "shadcn_setup" |
| }, |
| "fastapi": { |
| "files": { |
| "main.py": """from fastapi import FastAPI |
| |
| app = FastAPI() |
| |
| @app.get("/") |
| async def read_root(): |
| return {"Hello": "World from FastAPI"} |
| """, |
| "requirements.txt": "fastapi\nuvicorn", |
| ".gitignore": "__pycache__/\nvenv/\n" |
| } |
| }, |
| "nextjs": { |
| "files": { |
| "package.json": """{ |
| "name": "nextjs-app", |
| "version": "0.1.0", |
| "private": true, |
| "scripts": { |
| "dev": "next dev", |
| "build": "next build", |
| "start": "next start", |
| "lint": "next lint" |
| }, |
| "dependencies": { |
| "@types/node": "20.8.9", |
| "@types/react": "18.2.33", |
| "@types/react-dom": "18.2.14", |
| "eslint": "8.52.0", |
| "eslint-config-next": "14.0.0", |
| "next": "14.0.0", |
| "react": "18.2.0", |
| "react-dom": "18.2.0", |
| "typescript": "5.2.2" |
| } |
| }""", |
| "next.config.js": """/** @type {import('next').NextConfig} */ |
| const nextConfig = { |
| reactStrictMode: true, |
| } |
| |
| module.exports = nextConfig""", |
| "pages/index.js": """import Head from 'next/head' |
| import styles from '../styles/Home.module.css' |
| |
| export default function Home() { |
| return ( |
| <div className={styles.container}> |
| <Head> |
| <title>Create Next App</title> |
| <link rel="icon" href="/favicon.ico" /> |
| </Head> |
| |
| <main className={styles.main}> |
| <h1 className={styles.title}> |
| Welcome to <a href="https://nextjs.org">Next.js!</a> |
| </h1> |
| |
| <p className={styles.description}> |
| Get started by editing{' '} |
| <code className={styles.code}>pages/index.js</code> |
| </p> |
| </main> |
| |
| <footer className={styles.footer}> |
| <a |
| href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app" |
| target="_blank" |
| rel="noopener noreferrer" |
| > |
| Powered by{' '} |
| <img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} /> |
| </a> |
| </footer> |
| </div> |
| ) |
| }""", |
| "styles/Home.module.css": """.container { |
| min-height: 100vh; |
| padding: 0 0.5rem; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| align-items: center; |
| height: 100vh; |
| } |
| |
| .main { |
| padding: 5rem 0; |
| flex: 1; |
| display: flex; |
| flex-direction: column; |
| justify-content: center; |
| align-items: center; |
| } |
| |
| .footer { |
| width: 100%; |
| height: 100px; |
| border-top: 1px solid #eaeaea; |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| } |
| |
| .footer img { |
| margin-left: 0.5rem; |
| } |
| |
| .footer a { |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| } |
| |
| .title a { |
| color: #0070f3; |
| text-decoration: none; |
| } |
| |
| .title a:hover, |
| .title a:focus, |
| .title a:active { |
| text-decoration: underline; |
| } |
| |
| .title { |
| margin: 0; |
| line-height: 1.15; |
| font-size: 4rem; |
| } |
| |
| .title, |
| .description { |
| text-align: center; |
| } |
| |
| .description { |
| line-height: 1.5; |
| font-size: 1.5rem; |
| } |
| |
| .code { |
| background: #fafafa; |
| border-radius: 5px; |
| padding: 0.75rem; |
| font-size: 1.1rem; |
| font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, |
| Bitstream Vera Sans Mono, Courier New, monospace; |
| } |
| |
| .logo { |
| height: 1em; |
| margin-left: 0.5rem; |
| } |
| |
| @media (max-width: 600px) { |
| .grid { |
| width: 100%; |
| flex-direction: column; |
| } |
| }""", |
| "pages/_app.js": """import '../styles/globals.css' |
| |
| function MyApp({ Component, pageProps }) { |
| return <Component {...pageProps} /> |
| } |
| |
| export default MyApp""", |
| "pages/api/hello.js": """// Next.js API route support: https://nextjs.org/docs/api-routes/introduction |
| |
| export default function handler(req, res) { |
| res.status(200).json({ text: 'Hello' }) |
| }""", |
| "package-lock.json": """{ |
| "name": "nextjs-app", |
| "version": "0.1.0", |
| "lockfileVersion": 2, |
| "requires": true, |
| "packages": { |
| "": { |
| "name": "nextjs-app", |
| "version": "0.1.0", |
| "private": true, |
| "dependencies": { |
| "@types/node": "20.8.9", |
| "@types/react": "18.2.33", |
| "@types/react-dom": "18.2.14", |
| "eslint": "8.52.0", |
| "eslint-config-next": "14.0.0", |
| "next": "14.0.0", |
| "react": "18.2.0", |
| "react-dom": "18.2.0", |
| "typescript": "5.2.2" |
| } |
| }, |
| "node_modules/@babel/code-frame": { |
| "version": "7.23.5", |
| #"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@babel/highlight": "^7.22.16" |
| }, |
| "engines": { |
| "node": ">=6.9.0" |
| } |
| }, |
| "node_modules/@babel/highlight": { |
| "version": "7.23.4", |
| #"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "chalk": "^2.0.0", |
| "esutils": "^2.0.0" |
| }, |
| "engines": { |
| "node": ">=6.9.0" |
| } |
| }, |
| "node_modules/@cnakazawa/describe-type": { |
| "version": "2.1.1", |
| #"resolved": "https://registry.npmjs.org/@cnakazawa/describe-type/-/describe-type-2.1.1.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@eslint/eslintrc": { |
| "version": "2.1.1", |
| #"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "ajv": "^6.12.2", |
| "chalk": "^2.0.0", |
| "functional-red-black-tree": "^1.0.1", |
| "ignore": "^5.1.7", |
| "import-fresh": "^3.2.1", |
| "js-yaml": "^3.13.1", |
| "json-stable-stringify-without-jsonify": "^1.0.3", |
| "semver": "^6.3.0", |
| "strip-json-comments": "^3.1.1" |
| }, |
| "engines": { |
| "node": "^10.0.0 || >= 12.0.0" |
| } |
| }, |
| "node_modules/@eslint/js": { |
| "version": "8.52.0", |
| #"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": "^10.0.0 || >= 12.0.0" |
| } |
| }, |
| "node_modules/@humanwhocodes/config-array": { |
| "version": "0.11.12", |
| # "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.12.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@humanwhocodes/object-schema": "^1.2.1", |
| "debug": "^4.3.4", |
| "semver": "^7.5.4" |
| }, |
| "engines": { |
| "node": ">=14.18.0" |
| } |
| }, |
| "node_modules/@humanwhocodes/object-schema": { |
| "version": "1.2.1", |
| #"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=12" |
| } |
| }, |
| "node_modules/@jest/types": { |
| "version": "29.6.3", |
| #"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/jest": "*", |
| "@types/node": "*", |
| "expect-type": "0.8.1" |
| } |
| }, |
| "node_modules/@next/env": { |
| "version": "14.0.0", |
| #"resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@npmcli/ci-detect": { |
| "version": "2.0.1", |
| #"resolved": "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-2.0.1.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@radix-ui/react-slot": { |
| "version": "1.0.2", |
| #"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@radix-ui/slot": { |
| "version": "1.0.2", |
| #"resolved": "https://registry.npmjs.org/@radix-ui/slot/-/slot-1.0.2.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "react": "*" |
| } |
| }, |
| "node_modules/@rollup/plugin-commonjs": { |
| "version": "25.0.7", |
| #"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "rollup": "^1.20.0||^2||^3" |
| }, |
| "peerDependenciesMeta": { |
| "rollup": { |
| "optional": true |
| } |
| } |
| }, |
| "node_modules/@rollup/plugin-inject": { |
| "version": "5.1.0", |
| #"resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-5.1.0.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "rollup": "^1.20.0||^2||^3" |
| }, |
| "peerDependenciesMeta": { |
| "rollup": { |
| "optional": true |
| } |
| } |
| }, |
| "node_modules/@stylistic/eslint-plugin-js": { |
| "version": "1.5.1", |
| #"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.5.1.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@stylistic/eslint-plugin-plus": "1.5.1", |
| "globals": "^13.20.0" |
| }, |
| "peerDependencies": { |
| "eslint": ">=8.0.0" |
| } |
| }, |
| "node_modules/@stylistic/eslint-plugin-plus": { |
| "version": "1.5.1", |
| #"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.5.1.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "eslint": ">=8.0.0" |
| } |
| }, |
| "node_modules/@stylistic/js": { |
| "version": "1.5.1", |
| #"resolved": "https://registry.npmjs.org/@stylistic/js/-/js-1.5.1.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=14.0.0" |
| } |
| }, |
| "node_modules/@svgr/plugin-jsx": { |
| "version": "8.1.4", |
| #"resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.4.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@babel/plugin-syntax-jsx": "^7.18.6", |
| "@svgr/babel-preset": "8.1.4", |
| "@svgr/core": "8.1.4", |
| "@svgr/plugin-prettier": "8.1.4", |
| "@svgr/plugin-svgo": "8.1.4", |
| "camelcase": "^6.0.0", |
| "semver": "^7.3.5" |
| }, |
| "engines": { |
| "node": ">=14" |
| } |
| }, |
| "node_modules/@tsconfig/cypress": { |
| "version": "3.0.0", |
| #"resolved": "https://registry.npmjs.org/@tsconfig/cypress/-/cypress-3.0.0.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "typescript": ">=4.5" |
| } |
| }, |
| "node_modules/@tsconfig/create-react-app": { |
| "version": "2.0.1", |
| #"resolved": "https://registry.npmjs.org/@tsconfig/create-react-app/-/create-react-app-2.0.1.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "typescript": ">=3.8" |
| } |
| }, |
| "node_modules/@tsconfig/node-lts-strictest": { |
| "version": "20.1.1", |
| #"resolved": "https://registry.npmjs.org/@tsconfig/node-lts-strictest/-/node-lts-strictest-20.1.1.tgz", |
| #"integrity": "sha512-...", |
| "peerDependencies": { |
| "typescript": ">=4.8" |
| } |
| }, |
| "node_modules/@types/babel__core": { |
| "version": "7.20.3", |
| #"resolved": "https://registry.npmjs.org/@types/babel__core/-/core-7.20.3.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@babel/parser": "*", |
| "@types/babel__generator": "*", |
| "@types/babel__template": "*", |
| "@types/babel__traverse": "*", |
| "@types/semver": "*" |
| } |
| }, |
| "node_modules/@types/babel__generator": { |
| "version": "7.6.8", |
| #"resolved": "https://registry.npmjs.org/@types/babel__generator/-/generator-7.6.8.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/babel__template": { |
| "version": "7.4.5", |
| #"resolved": "https://registry.npmjs.org/@types/babel__template/-/template-7.4.5.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/babel__traverse": { |
| "version": "7.20.5", |
| #"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/traverse-7.20.5.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/babel__parser": "*" |
| } |
| }, |
| "node_modules/@types/chalk": { |
| "version": "2.2.0", |
| #"resolved": "https://registry.npmjs.org/@types/chalk/-/chalk-2.2.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/color-name": { |
| "version": "1.1.3", |
| #"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.3.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/eslint": { |
| "version": "8.44.7", |
| #"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.7.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@jest/types": "*", |
| "@types/estree": "*", |
| "@types/json-schema": "*", |
| "@types/node": "*" |
| } |
| }, |
| "node_modules/@types/estree": { |
| "version": "2.0.0", |
| #"resolved": "https://registry.npmjs.org/@types/estree/-/estree-2.0.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/glob": { |
| "version": "8.1.0", |
| #"resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/node": "*" |
| } |
| }, |
| "node_modules/@types/hoist-non-react-statics": { |
| "version": "3.3.1", |
| #"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/jest": { |
| "version": "29.5.5", |
| #"resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.5.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/estree": "*", |
| "@types/node": "*", |
| "@types/promises-aplus": "*", |
| "@types/testing-library__dom": "*", |
| "@types/ungap__structured-clone": "*", |
| "expect-type": "0.8.1" |
| } |
| }, |
| "node_modules/@types/json-schema": { |
| "version": "7.0.12", |
| #"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/json5": { |
| "version": "0.0.2", |
| #"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.2.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/minimatch": { |
| "version": "5.1.0", |
| #"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/node": { |
| "version": "20.8.9", |
| #"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.9.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/parse-json": { |
| "version": "4.0.0", |
| #"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/prettier": { |
| "version": "2.7.3", |
| #"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/promises-aplus": { |
| "version": "2.0.5", |
| #"resolved": "https://registry.npmjs.org/@types/promises-aplus/-/promises-aplus-2.0.5.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/node": "*" |
| } |
| }, |
| "node_modules/@types/react": { |
| "version": "18.2.33", |
| #"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.33.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/prop-types": "*", |
| "@types/scheduler": "*", |
| "csstype": "^3.0.5" |
| } |
| }, |
| "node_modules/@types/react-dom": { |
| "version": "18.2.14", |
| #"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.14.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/react": "*" |
| } |
| }, |
| "node_modules/@types/resolve": { |
| "version": "1.20.2", |
| #"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/scheduler": { |
| "version": "0.16.4", |
| #"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/semver": { |
| "version": "7.5.3", |
| #"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/stack-trace-parser": { |
| "version": "1.3.2", |
| #"resolved": "https://registry.npmjs.org/@types/stack-trace-parser/-/stack-trace-parser-1.3.2.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@types/testing-library__dom": { |
| "version": "7.5.0", |
| #"resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/dom-7.5.0.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/node": "*" |
| } |
| }, |
| "node_modules/@types/ungap__structured-clone": { |
| "version": "0.3.0", |
| #"resolved": "https://registry.npmjs.org/@types/ungap__structured-clone/-/structured-clone-0.3.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/@vercel/nft": { |
| "version": "0.25.0", |
| #"resolved": "https://registry.npmjs.org/@vercel/nft/-/nft-0.25.0.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@types/glob": "^8.0.0", |
| "cacache": "^16.1.0", |
| "esbuild": "0.19.5", |
| "fast-glob": "^3.2.12", |
| "ignore": "^7.0.0", |
| "ora": "^5.4.1", |
| "resolve": "^1.22.8", |
| "walker": "^1.0.8" |
| }, |
| "engines": { |
| "node": ">=16.7.0" |
| } |
| }, |
| "node_modules/ajv": { |
| "version": "6.12.6", |
| #"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "fast-deep-equal": "^3.1.1", |
| "json-schema-traverse": "^0.4.1", |
| "uri-js": "^4.2.2" |
| }, |
| "engines": { |
| "node": ">=6.9" |
| } |
| }, |
| "node_modules/ansi-styles": { |
| "version": "3.2.1", |
| #"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "color-convert": "^1.9.0" |
| }, |
| "engines": { |
| "node": ">=4" |
| } |
| }, |
| "node_modules/arg": { |
| "version": "5.0.2", |
| #"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=14" |
| } |
| }, |
| "node_modules/assert": { |
| "version": "1.5.0", |
| #"resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "ieee754": "^1.1.13", |
| "util": "0.10.4" |
| } |
| }, |
| "node_modules/autoprefixer": { |
| "version": "10.4.16", |
| #"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "browserslist": "^4.22.1", |
| "caniuse-lite": "1.0.30015751", |
| "chokidar": "^3.5.3", |
| "escalade": "^3.1.1", |
| "nanoid": "^3.3.6", |
| "picocolors": "^1.0.0", |
| "postcss": "^8.4.31", |
| "postcss-value-parser": "^6.0.5" |
| }, |
| "funding": { |
| "url": "https://opencollective.com/postcss" |
| }, |
| "peerDependencies": { |
| "postcss": "^8.1.0" |
| } |
| }, |
| "node_modules/balanced-match": { |
| "version": "1.0.2", |
| #"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/browserslist": { |
| "version": "4.22.2", |
| #"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", |
| #"integrity": "sha512-...", |
| "funding": { |
| "type": "opencollective", |
| "url": "https://opencollective.com/browserslist" |
| }, |
| "engines": { |
| "node": ">=6" |
| } |
| }, |
| "node_modules/cacache": { |
| "version": "16.1.1", |
| #"resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.1.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "@npmcli/ci-detect": "^2.0.0", |
| "@npmcli/fs": "^3.1.0", |
| "@npmcli/move-file": "^2.0.0", |
| "chownr": "^3.0.0", |
| "fs-minipass": "^3.0.0", |
| "lru-cache": "^7.1.5", |
| "minipass": "^5.0.0", |
| "minipass-collect": "^2.0.0", |
| "minipass-fetch": "^2.0.3", |
| "minipass-pipeline": "^1.2.0", |
| "minipass-sized": "^2.0.0", |
| "mkdirp": "^1.0.4", |
| "rimraf": "^4.1.0", |
| "ssri": "^9.0.0", |
| "tar": "^6.1.11" |
| }, |
| "engines": { |
| "node": ">=12" |
| } |
| }, |
| "node_modules/camelcase": { |
| "version": "6.3.0", |
| #"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=10" |
| } |
| }, |
| "node_modules/caniuse-lite": { |
| "version": "1.0.30015751", |
| #"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30015751.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/chalk": { |
| "version": "2.4.2", |
| #"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "ansi-styles": "^3.2.1", |
| "escape-string-regexp": "^1.0.5", |
| "supports-color": "^5.3.0" |
| }, |
| "engines": { |
| "node": ">=4" |
| } |
| }, |
| "node_modules/chokidar": { |
| "version": "3.5.3", |
| #"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "anymatch": "~3.1.3", |
| "braces": "~3.0.2", |
| "glob-parent": "~5.1.2", |
| "is-binary-path": "~2.1.0", |
| "is-glob": "~4.0.3", |
| "normalize-path": "~3.0.0", |
| "readdirp": "~3.6.0" |
| }, |
| "engines": { |
| "node": ">= 8.16.0" |
| }, |
| "optionalDependencies": { |
| "fsevents": "~2.3.2" |
| } |
| }, |
| "node_modules/chownr": { |
| "version": "3.0.0", |
| #"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=12" |
| } |
| }, |
| "node_modules/class-variance-authority": { |
| "version": "0.7.0", |
| #"resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/cli-boxes": { |
| "version": "2.2.1", |
| #"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=12" |
| } |
| }, |
| "node_modules/clsx": { |
| "version": "2.1.0", |
| #"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", |
| #"integrity": "sha512-...", |
| }, |
| "node_modules/color-convert": { |
| "version": "1.9.3", |
| #"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", |
| #"integrity": "sha512-...", |
| "dependencies": { |
| "color-name": "1.1.3" |
| }, |
| "engines": { |
| "node": ">=0.4.0" |
| } |
| }, |
| "node_modules/color-name": { |
| "version": "1.1.3", |
| #"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", |
| #"integrity": "sha512-...", |
| "engines": { |
| "node": ">=0.1.90" |
| } |
| }, |
| |
| |
| export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }""", |
| "src/lib/utils.js": """import { clsx } from "clsx" |
| import { twMerge } from "tailwind-merge" |
| |
| export function cn(...inputs) { |
| return twMerge(clsx(inputs)) |
| }""" |
| }, |
| "post_process": "shadcn_setup" |
| }, |
| } |
| def get_file_content(owner, repo_name, path, branch="main"): |
| """Fetches file content from a GitHub repository.""" |
| url = f"https://raw.githubusercontent.com/{owner}/{repo_name}/{branch}/{path}" |
| try: |
| response = requests.get(url) |
| response.raise_for_status() |
| return response.text |
| except requests.exceptions.RequestException as e: |
| return f"Error fetching file: {e}" |
| def extract_repo_info(url): |
| """Extracts owner and repo name from a GitHub URL.""" |
| match = re.search(r"github\.com/([^/]+)/([^/]+)", url) |
| return match.group(1), match.group(2) if match else (None, None) |
| def analyze_file_content(content, file_path): |
| """Analyzes file content and returns statistics.""" |
| lines = content.splitlines() |
| word_count = sum(len(line.split()) for line in lines) |
| line_count = len(lines) |
| file_extension = file_path.split('.')[-1].lower() if '.' in file_path else "unknown" |
| return { |
| "line_count": line_count, |
| "word_count": word_count, |
| "file_extension": file_extension, |
| } |
| def github_tool( |
| action: str, |
| repo_name: str = None, |
| branch: str = "main", |
| path: str = None, |
| content: str = None, |
| message: str = None, |
| owner: str = None, |
| vcs_url: str = None, |
| title: str = None, |
| body: str = None, |
| base: str = None, |
| head: str = None, |
| issue_number: int = None, |
| labels: str = None, |
| tag: str = None, |
| name: str = None, |
| file_url: str = None, |
| repo_url: str = None, |
| template_name: str = None, |
| template_params: dict = None, |
| diff: str = None, |
| diff_message: str = None, |
| new_description: str = None, |
| issue_title: str = None, |
| issue_body: str = None, |
| issue_state: str = None, |
| **kwargs |
| ): |
| """Manages GitHub repositories.""" |
| user = g.get_user() |
| try: |
| if action == "import_repository": |
| if not all([owner, repo_name, vcs_url]): |
| raise ValueError("Missing parameters: owner, repo_name, vcs_url") |
| try: |
| user.get_repo(repo_name) |
| return "Repository already exists." |
| except GithubException: |
| pass |
| headers = { |
| 'Authorization': f'token {GITHUB_TOKEN}', |
| 'Accept': 'application/vnd.github.v3+json', |
| } |
| import_url = f'https://api.github.com/repos/{owner}/{repo_name}/import' |
| response = requests.put(import_url, json={'vcs_url': vcs_url, 'vcs': 'git'}, headers=headers) |
| response.raise_for_status() |
| return "Repository import started." |
| elif action == "create_repository": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.create_repo(name=repo_name) |
| return f"Repository **{repo_name}** created! [Open repository]({repo.html_url})" |
| elif action == "create_project_from_template": |
| if not all([repo_name, template_name]): |
| raise ValueError("Missing parameters: repo_name, template_name") |
| if template_name not in PROJECT_TEMPLATES: |
| raise ValueError( |
| f"Unknown template: {template_name}. Available: {', '.join(PROJECT_TEMPLATES.keys())}" |
| ) |
| repo = user.create_repo(name=repo_name) |
| template = PROJECT_TEMPLATES[template_name] |
| template_params_final = {} |
| if "params" in template: |
| for param_name, param_config in template["params"].items(): |
| template_params_final[param_name] = template_params.get(param_name, param_config.get("default")) if template_params else param_config.get("default") |
| repo_name_snake_case = repo_name.replace("-", "_") |
| readme_filename = "README.md" |
| env = jinja2.Environment() |
| for file_path, file_content in template["files"].items(): |
| final_file_path = file_path |
| final_file_content = file_content |
| if "rename_files" in template: |
| for old_name, new_name_template in template["rename_files"].items(): |
| if file_path == old_name: |
| final_file_path = new_name_template.replace("{{repo_name_snake_case}}", repo_name_snake_case).replace("{{repo_name}}", repo_name).replace("{{readme_filename}}", readme_filename) |
| template_render = env.from_string(final_file_content) |
| final_file_content = template_render.render( |
| repo_name=repo_name, |
| repo_name_snake_case=repo_name_snake_case, |
| readme_filename=readme_filename, |
| **template_params_final |
| ) |
| repo.create_file( |
| final_file_path, |
| f"Create {final_file_path} from template {template_name}", |
| final_file_content, |
| branch="main", |
| ) |
| if "post_process" in template: |
| post_process_action = template["post_process"] |
| if post_process_action == "install_dependencies": |
| print( |
| f"Post-processing: install_dependencies for {repo_name} (Not fully implemented in this example).") |
| elif post_process_action == "shadcn_setup": |
| instructions = f""" |
| **Konfiguracja Shadcn UI wymaga dodatkowych kroków po stronie klienta!** |
| |
| 1. **Sklonuj repozytorium:** `git clone https://github.com/{user.login}/{repo_name}.git` |
| 2. **Przejdź do katalogu projektu:** `cd {repo_name}` |
| 3. **Zainstaluj zależności:** `npm install` (lub `yarn install`, `pnpm install`) |
| 4. **Zainicjuj Shadcn UI:** `npx shadcn-ui@latest init` |
| 5. **Uruchom aplikację:** `npm run dev` (lub odpowiednia komenda dla Twojego menedżera pakietów) |
| |
| Po wykonaniu tych kroków, Twoja aplikacja Shadcn UI będzie w pełni skonfigurowana i gotowa do rozwoju. |
| """ |
| return f"Repository **{repo_name}** created from template **{template_name}**! [Open repository]({repo.html_url})\n\n{instructions}" |
| else: |
| print(f"Unknown post-process action: {post_process_action}") |
| return f"Repository **{repo_name}** created from template **{template_name}**! [Open repository]({repo.html_url})" |
| elif action == "create_file": |
| if not all([repo_name, path, content, message]): |
| raise ValueError("Missing parameters: repo_name, path, content, message") |
| repo = user.get_repo(repo_name) |
| repo.create_file(path, message, content, branch=branch) |
| return f"File **`{path}`** created in repository **`{repo_name}`** on branch **`{branch}`**." |
| elif action == "get_file": |
| if not all([repo_name, path]): |
| raise ValueError("Missing parameters: repo_name, path") |
| repo = user.get_repo(repo_name) |
| file_content = repo.get_contents(path, ref=branch) |
| return ( |
| f"File content of **`{path}`** from **`{repo_name}`**:\n\n`\n{file_content.decoded_content.decode()}\n`" |
| ) |
| elif action == "get_file_content_by_url": |
| if not file_url: |
| raise ValueError("Missing parameter: file_url") |
| file_content = get_file_content(None, None, None, None) |
| return f"File content from URL **`{file_url}`**:\n\n`\n{file_content}\n`" |
| elif action == "delete_file": |
| if not all([repo_name, path]): |
| raise ValueError("Missing parameters: repo_name, path") |
| repo = user.get_repo(repo_name) |
| file_contents = repo.get_contents(path, ref=branch) |
| repo.delete_file(path, "Delete file", file_contents.sha, branch=branch) |
| return f"File **`{path}`** deleted from repository **`{repo_name}`** on branch **`{branch}`**." |
| elif action == "update_file": |
| if not all([repo_name, path, content, message]): |
| raise ValueError("Missing parameters: repo_name, path, content, message") |
| repo = user.get_repo(repo_name) |
| file_contents = repo.get_contents(path, ref=branch) |
| repo.update_file(path, message, content, file_contents.sha, branch=branch) |
| return f"File **`{path}`** updated in repository **`{repo_name}`** on branch **`{branch}`**." |
| elif action == "update_file_diff": |
| if not all([repo_name, path, diff, diff_message]): |
| raise ValueError("Missing parameters: repo_name, path, diff, diff_message") |
| repo = user.get_repo(repo_name) |
| file_contents = repo.get_contents(path, ref=branch) |
| current_content_text = file_contents.decoded_content.decode() |
| dmp = diff_match_patch() |
| try: |
| patches = dmp.patch_fromText(diff) |
| except ValueError: |
| raise ValueError("Invalid patch format. Please provide a valid patch in 'diff' format.") |
| patched_content_tuple = dmp.patch_apply(patches, current_content_text) |
| patched_content_text = patched_content_tuple[0] |
| patch_results = patched_content_tuple[1] |
| if not any(patch_results): |
| raise ValueError("Failed to apply patch. Diff might be outdated or invalid.") |
| repo.update_file(path, diff_message, patched_content_text, file_contents.sha, branch=branch) |
| return f"File **`{path}`** updated using diff in repository **`{repo_name}`** on branch **`{branch}`**." |
| elif action == "list_branches": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| branches = repo.get_branches() |
| branch_list = "\n".join([f"- `{branch.name}`" for branch in branches]) |
| return f"Branches in repository **`{repo_name}`**:\n{branch_list}" |
| elif action == "create_branch": |
| if not all([repo_name, base, head]): |
| raise ValueError("Missing parameters: repo_name, base, head") |
| repo = user.get_repo(repo_name) |
| source_branch = repo.get_branch(base) |
| repo.create_git_ref(ref=f"refs/heads/{head}", sha=source_branch.commit.sha) |
| return f"Branch **`{head}`** created from **`{base}`** in repository **`{repo_name}`**." |
| elif action == "delete_branch": |
| if not all([repo_name, branch]): |
| raise ValueError("Missing parameters: repo_name, branch") |
| repo = user.get_repo(repo_name) |
| repo.get_git_ref(f"heads/{branch}").delete() |
| return f"Branch **`{branch}`** deleted from repository **`{repo_name}`**." |
| elif action == "create_pull_request": |
| if not all([repo_name, title, body, base, head]): |
| raise ValueError("Missing parameters: repo_name, title, body, base, head") |
| repo = user.get_repo(repo_name) |
| pr = repo.create_pull(title=title, body=body, base=base, head=head) |
| return f"Pull request created! [Open Pull Request]({pr.html_url})" |
| elif action == "list_open_pull_requests": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| open_prs = repo.get_pulls(state='open') |
| if not open_prs: |
| return f"No open pull requests in repository **`{repo_name}`**." |
| prs_list = "\n".join([f"- [{pr.title}]({pr.html_url})" for pr in open_prs]) |
| return f"Open pull requests in repository **`{repo_name}`**:\n{prs_list}" |
| elif action == "create_issue": |
| if not all([repo_name, title, body]): |
| raise ValueError("Missing parameters: repo_name, title, body") |
| repo = user.get_repo(repo_name) |
| issue = repo.create_issue(title=title, body=body) |
| return f"Issue created! [Open Issue]({issue.html_url})" |
| elif action == "list_issues": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| issues = repo.get_issues(state='open') |
| if not issues: |
| return f"No open issues in repository **`{repo_name}`**." |
| issues_list = "\n".join([f"- [{issue.title}]({issue.html_url})" for issue in issues]) |
| return f"Open issues in repository **`{repo_name}`**:\n{issues_list}" |
| elif action == "add_label_to_issue": |
| if not all([repo_name, issue_number, labels]): |
| raise ValueError("Missing parameters: repo_name, issue_number, labels") |
| repo = user.get_repo(repo_name) |
| issue = repo.get_issue(number=int(issue_number)) |
| for label in labels.split(","): |
| issue.add_to_labels(label.strip()) |
| return ( |
| f"Labels **`{labels}`** added to issue **#{issue_number}** in repository **`{repo_name}`**." |
| ) |
| elif action == "close_issue": |
| if not all([repo_name, issue_number]): |
| raise ValueError("Missing parameters: repo_name, issue_number") |
| repo = user.get_repo(repo_name) |
| issue = repo.get_issue(number=int(issue_number)) |
| issue.edit(state='closed') |
| return f"Issue **#{issue_number}** closed in repository **`{repo_name}`**." |
| elif action == "add_comment_to_issue": |
| if not all([repo_name, issue_number, message]): |
| raise ValueError("Missing parameters: repo_name, issue_number, message") |
| repo = user.get_repo(repo_name) |
| issue = repo.get_issue(number=int(issue_number)) |
| issue.create_comment(body=message) |
| return f"Comment added to issue **#{issue_number}** in repository **`{repo_name}`**." |
| elif action == "create_release": |
| if not all([repo_name, tag, name, message]): |
| raise ValueError("Missing parameters: repo_name, tag, name, message") |
| repo = user.get_repo(repo_name) |
| release = repo.create_git_release(tag=tag, name=name, message=message) |
| return ( |
| f"Release **`{name}`** created in repository **`{repo_name}`**! [Open Release]({release.html_url})" |
| ) |
| elif action == "list_releases": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| releases = repo.get_releases() |
| if not releases: |
| return f"No releases in repository **`{repo_name}`**." |
| releases_list = "\n".join([f"- [{release.tag_name}]({release.html_url})" for release in releases]) |
| return f"Releases in repository **`{repo_name}`**:\n{releases_list}" |
| elif action == "fork_repository": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = g.get_repo(repo_name) |
| fork = user.create_fork(repo) |
| return f"Repository **`{repo_name}`** forked! [Open fork]({fork.html_url})" |
| elif action == "list_forks": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = g.get_repo(repo_name) |
| forks = repo.get_forks() |
| if not forks: |
| return f"No forks of repository **`{repo_name}`**." |
| forks_list = "\n".join([f"- [{fork.full_name}]({fork.html_url})" for fork in forks]) |
| return f"Forks of repository **`{repo_name}`**:\n{forks_list}" |
| elif action == "list_files": |
| if not all([owner, repo_name]): |
| raise ValueError("Missing parameters: owner, repo_name") |
| repo = g.get_repo(f"{owner}/{repo_name}") |
| contents = repo.get_contents("" if not path else path) |
| if not contents: |
| return f"No files in path **`{path}`** of repository **`{repo_name}`**." |
| files_list = "\n".join([f"- [{content.name}]({content.download_url})" for content in contents]) |
| return f"Files in path **`{path}`** of repository **`{repo_name}`**:\n{files_list}" |
| elif action == "get_repository_info": |
| if not all([owner, repo_name]): |
| raise ValueError("Missing parameters: owner, repo_name") |
| repo = g.get_repo(f"{owner}/{repo_name}") |
| info = { |
| "Name": repo.name, |
| "Description": repo.description, |
| "URL": repo.html_url, |
| "Owner": repo.owner.login, |
| "Default branch": repo.default_branch, |
| "Language": repo.language, |
| "Stars": repo.stargazers_count, |
| "Forks": repo.forks_count, |
| "Created at": str(repo.created_at), |
| "Last updated": str(repo.updated_at), |
| } |
| info_md = "\n".join([f"- **{key}**: {value}" for key, value in info.items()]) |
| return f"Repository info for **`{repo_name}`**:\n{info_md}" |
| elif action == "get_file_content": |
| if not all([owner, repo_name, path]): |
| raise ValueError("Missing parameters: owner, repo_name, path") |
| content_text = get_file_content(owner, repo_name, path, branch) |
| return ( |
| f"File content of **`{path}`** from repository **`{repo_name}`**:\n\n`\n{content_text}\n`" |
| ) |
| elif action == "analyze_repository_by_url": |
| if not repo_url: |
| raise ValueError("Missing parameter: repo_url") |
| owner, repo_name = extract_repo_info(repo_url) |
| if not owner or not repo_name: |
| raise ValueError("Invalid repository URL") |
| repo = g.get_repo(f"{owner}/{repo_name}") |
| contents = repo.get_contents("") |
| file_analyses = [] |
| for content in contents: |
| if content.type == "file": |
| file_content = content.decoded_content.decode() |
| analysis = analyze_file_content(file_content, content.path) |
| file_analyses.append({ |
| "name": content.name, |
| "path": content.path, |
| "analysis": analysis, |
| }) |
| analysis_md = "Repository file analysis:\n" + "\n".join([ |
| f"- **{f['path']}**:\n" |
| f" - Lines: {f['analysis']['line_count']}\n" |
| f" - Words: {f['analysis']['word_count']}\n" |
| f" - Extension: {f['analysis']['file_extension']}" |
| for f in file_analyses |
| ]) |
| return analysis_md |
| elif action == "analyze_repository_content": |
| if not all([owner, repo_name]): |
| raise ValueError("Missing parameters: owner, repo_name") |
| repo = g.get_repo(f"{owner}/{repo_name}") |
| contents = repo.get_contents("") |
| file_analyses = [] |
| for content in contents: |
| if content.type == "file": |
| file_content = get_file_content(owner, repo_name, content.path, branch) |
| analysis = analyze_file_content(file_content, content.path) |
| file_analyses.append({ |
| "name": content.name, |
| "path": content.path, |
| "analysis": analysis, |
| }) |
| analysis_md = "Repository content analysis:\n" + "\n".join([ |
| f"- **{f['path']}**:\n" |
| f" - Lines: {f['analysis']['line_count']}\n" |
| f" - Words: {f['analysis']['word_count']}\n" |
| f" - Extension: {f['analysis']['file_extension']}" |
| for f in file_analyses |
| ]) |
| return analysis_md |
| elif action == "delete_repository": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| repo.delete() |
| return f"Repository **`{repo_name}`** deleted!" |
| elif action == "update_repository_description": |
| if not all([repo_name, new_description]): |
| raise ValueError("Missing parameters: repo_name, new_description") |
| repo = user.get_repo(repo_name) |
| repo.edit(description=new_description) |
| return f"Repository **`{repo_name}`** description updated to: \"{new_description}\"" |
| elif action == "edit_issue": |
| if not all([repo_name, issue_number]): |
| raise ValueError("Missing parameters: repo_name, issue_number") |
| repo = user.get_repo(repo_name) |
| issue = repo.get_issue(number=int(issue_number)) |
| issue_update_params = {} |
| if issue_title is not None: |
| issue_update_params['title'] = issue_title |
| if issue_body is not None: |
| issue_update_params['body'] = issue_body |
| if issue_state is not None: |
| issue_update_params['state'] = issue_state |
| if not issue_update_params: |
| raise ValueError("No issue details to update provided (title, body, or state)") |
| issue.edit(**issue_update_params) |
| updated_fields = ", ".join(issue_update_params.keys()) |
| return f"Issue **#{issue_number}** in repository **`{repo_name}`** updated fields: {updated_fields}" |
| elif action == "list_closed_issues": |
| if not repo_name: |
| raise ValueError("Missing parameter: repo_name") |
| repo = user.get_repo(repo_name) |
| issues = repo.get_issues(state='closed') |
| if not issues: |
| return f"No closed issues in repository **`{repo_name}`**." |
| issues_list = "\n".join([f"- [{issue.title}]({issue.html_url})" for issue in issues]) |
| return f"Closed issues in repository **`{repo_name}`**:\n{issues_list}" |
| elif action == "get_issue_details": |
| if not all([repo_name, issue_number]): |
| raise ValueError("Missing parameters: repo_name, issue_number") |
| repo = user.get_repo(repo_name) |
| issue = repo.get_issue(number=int(issue_number)) |
| comments = issue.get_comments() |
| details = f""" |
| **Issue #{issue.number}: {issue.title}** |
| State: {issue.state} |
| Created At: {issue.created_at} |
| Author: {issue.user.login} |
| |
| **Body:** |
| {issue.body} |
| |
| **Comments:** |
| """ |
| if comments: |
| for comment in comments: |
| details += f""" |
| --- |
| **{comment.user.login}** at {comment.created_at}: |
| {comment.body} |
| **\n** |
| """ |
| else: |
| details += "No comments." |
| return details |
| else: |
| raise ValueError(f"Unknown action: {action}") |
| except GithubException as e: |
| return f"**GitHub Error:** {e}" |
| except ValueError as e: |
| return f"**Error:** {e}" |
| except requests.exceptions.RequestException as e: |
| return f"**Connection Error:** {e}" |
| except Exception as e: |
| return f"**Unexpected Error:** {e}" |
| with gr.Blocks() as demo: |
| gr.Markdown("# GitHub Tool Plugingit (Simplified Interface)") |
| with gr.Column(): |
| action = gr.Dropdown( |
| choices=[ |
| "import_repository", "create_repository", "create_project_from_template", |
| "create_file", "get_file", "get_file_content_by_url", |
| "delete_file", "update_file", "update_file_diff", |
| "list_branches", "create_branch", "delete_branch", |
| "create_pull_request", "list_open_pull_requests", |
| "create_issue", "list_issues", "list_closed_issues", "get_issue_details", |
| "add_label_to_issue", "close_issue", "add_comment_to_issue", |
| "create_release", "list_releases", |
| "fork_repository", "list_forks", |
| "list_files", "get_repository_info", |
| "analyze_repository_by_url", "analyze_repository_content", |
| "delete_repository", "update_repository_description", "edit_issue" |
| ], |
| label="Select Action", |
| ) |
| repo_name = gr.Textbox(label="Repository Name") |
| template_name = gr.Dropdown( |
| choices=[""] + list(PROJECT_TEMPLATES.keys()), |
| label="Project Template", |
| value="", |
| allow_custom_value=True, |
| ) |
| template_params_ui = {} |
| with gr.Row(): |
| for template_key, template_config in PROJECT_TEMPLATES.items(): |
| if "params" in template_config: |
| with gr.Column(visible=False, elem_classes=f"params_{template_key}") as params_section: |
| for param_name, param_details in template_config["params"].items(): |
| if param_details["type"] == "choice": |
| template_params_ui[param_name] = gr.Dropdown( |
| choices=param_details["choices"], |
| label=param_details["description"] or param_name, |
| value=param_details["default"] |
| ) |
| else: |
| template_params_ui[param_name] = gr.Textbox( |
| label=param_details["description"] or param_name, |
| value=param_details["default"] if "default" in param_details else "" |
| ) |
| template_params_ui[template_key] = params_section |
| branch = gr.Textbox(label="Branch", value="main") |
| path = gr.Textbox(label="File Path") |
| content = gr.Code(label="File Content", lines=5, language='python', visible=True) |
| diff = gr.Code(label="Diff Content", lines=5, language="python", visible=False) |
| message = gr.Textbox(label="Message/Comment", visible=True) |
| diff_message = gr.Textbox(label="Diff Message", visible=False) |
| owner = gr.Textbox(label="Owner") |
| vcs_url = gr.Textbox(label="VCS URL") |
| title = gr.Textbox(label="Title") |
| body = gr.Textbox(label="Body") |
| base = gr.Textbox(label="Base Branch") |
| head = gr.Textbox(label="Head Branch/New Branch") |
| issue_number = gr.Number(label="Issue Number", precision=0) |
| labels = gr.Textbox(label="Labels (comma-separated)") |
| tag = gr.Textbox(label="Tag") |
| release_name = gr.Textbox(label="Release Name") |
| file_url = gr.Textbox(label="File URL") |
| repo_url = gr.Textbox(label="Repository URL") |
| new_description = gr.Textbox(label="New Repository Description", visible=False) |
| issue_title = gr.Textbox(label="New Issue Title", visible=False) |
| issue_body = gr.Textbox(label="New Issue Body", visible=False, lines=3) |
| issue_state = gr.Dropdown( |
| label="New Issue State (open/closed)", |
| choices=["open", "closed"], |
| value=None, |
| visible=False |
| ) |
| def show_template_params(template_name): |
| visibility_map = {key: gr.Column.update(visible=False) for key in PROJECT_TEMPLATES if |
| "params" in PROJECT_TEMPLATES[key]} |
| if template_name and template_name in PROJECT_TEMPLATES and "params" in PROJECT_TEMPLATES[template_name]: |
| visibility_map[template_name] = gr.Column.update(visible=True) |
| return [visibility_map.get(key, gr.Column.update(visible=False)) for key in PROJECT_TEMPLATES if |
| "params" in PROJECT_TEMPLATES[key]] |
| template_param_visibility_outputs = [template_params_ui[key] for key in PROJECT_TEMPLATES if |
| "params" in PROJECT_TEMPLATES[key]] |
| template_name.change( |
| show_template_params, |
| inputs=[template_name], |
| outputs=template_param_visibility_outputs |
| ) |
| run_button = gr.Button("Execute") |
| output = gr.Markdown(label="Result") |
| input_components = [ |
| action, repo_name, branch, path, content, message, owner, vcs_url, title, body, base, head, issue_number, |
| labels, tag, release_name, file_url, repo_url, template_name, new_description, issue_title, issue_body, |
| issue_state, diff, diff_message |
| ] |
| for template_key in PROJECT_TEMPLATES: |
| if "params" in PROJECT_TEMPLATES[template_key]: |
| for param_name in template_params_ui: |
| if param_name in PROJECT_TEMPLATES[template_key]["params"]: |
| input_components.append(template_params_ui[param_name]) |
| def show_hide_input_fields(action_name): |
| visibility_map = { |
| "repo_name": gr.Textbox.update(visible=False), |
| "branch": gr.Textbox.update(visible=False), |
| "path": gr.Textbox.update(visible=False), |
| "content": gr.Code.update(visible=False), |
| "diff": gr.Code.update(visible=False), |
| "message": gr.Textbox.update(visible=False), |
| "diff_message": gr.Textbox.update(visible=False), |
| "owner": gr.Textbox.update(visible=False), |
| "vcs_url": gr.Textbox.update(visible=False), |
| "title": gr.Textbox.update(visible=False), |
| "body": gr.Textbox.update(visible=False), |
| "base": gr.Textbox.update(visible=False), |
| "head": gr.Textbox.update(visible=False), |
| "issue_number": gr.Number.update(visible=False), |
| "labels": gr.Textbox.update(visible=False), |
| "tag": gr.Textbox.update(visible=False), |
| "release_name": gr.Textbox.update(visible=False), |
| "file_url": gr.Textbox.update(visible=False), |
| "repo_url": gr.Textbox.update(visible=False), |
| "template_name": gr.Dropdown.update(visible=False), |
| "new_description": gr.Textbox.update(visible=False), |
| "issue_title": gr.Textbox.update(visible=False), |
| "issue_body": gr.Textbox.update(visible=False), |
| "issue_state": gr.Dropdown.update(visible=False), |
| } |
| if action_name in ["import_repository"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "owner": gr.Textbox.update(visible=True), "vcs_url": gr.Textbox.update(visible=True)}) |
| elif action_name in ["create_repository", "delete_repository", "list_branches", "list_open_pull_requests", "list_issues", "list_closed_issues", "list_releases", "list_forks"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True)}) |
| elif action_name == "create_project_from_template": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "template_name": gr.Dropdown.update(visible=True)}) |
| elif action_name in ["create_file", "get_file", "delete_file", "get_file_content"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "path": gr.Textbox.update(visible=True), "branch": gr.Textbox.update(visible=True)}) |
| if action_name == "create_file": |
| visibility_map.update({"content": gr.Code.update(visible=True), "message": gr.Textbox.update(visible=True)}) |
| elif action_name == "update_file": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "path": gr.Textbox.update(visible=True), "branch": gr.Textbox.update(visible=True), "content": gr.Code.update(visible=True), "message": gr.Textbox.update(visible=True)}) |
| elif action_name == "update_file_diff": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "path": gr.Textbox.update(visible=True), "branch": gr.Textbox.update(visible=True), "diff": gr.Code.update(visible=True), "diff_message": gr.Textbox.update(visible=True)}) |
| elif action_name == "get_file_content_by_url": |
| visibility_map.update({"file_url": gr.Textbox.update(visible=True)}) |
| elif action_name in ["create_branch", "delete_branch"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "branch": gr.Textbox.update(visible=True)}) |
| if action_name == "create_branch": |
| visibility_map.update({"base": gr.Textbox.update(visible=True), "head": gr.Textbox.update(visible=True)}) |
| elif action_name == "create_pull_request": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "title": gr.Textbox.update(visible=True), "body": gr.Textbox.update(visible=True), "base": gr.Textbox.update(visible=True), "head": gr.Textbox.update(visible=True)}) |
| elif action_name == "create_issue": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "title": gr.Textbox.update(visible=True), "body": gr.Textbox.update(visible=True)}) |
| elif action_name == "add_label_to_issue": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "issue_number": gr.Number.update(visible=True), "labels": gr.Textbox.update(visible=True)}) |
| elif action_name in ["close_issue", "add_comment_to_issue", "get_issue_details", "edit_issue"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "issue_number": gr.Number.update(visible=True)}) |
| if action_name == "add_comment_to_issue": |
| visibility_map.update({"message": gr.Textbox.update(visible=True)}) |
| if action_name == "edit_issue": |
| visibility_map.update({"issue_title": gr.Textbox.update(visible=True), "issue_body": gr.Textbox.update(visible=True), "issue_state": gr.Dropdown.update(visible=True)}) |
| elif action_name == "create_release": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "tag": gr.Textbox.update(visible=True), "release_name": gr.Textbox.update(visible=True), "message": gr.Textbox.update(visible=True)}) |
| elif action_name == "fork_repository": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True)}) |
| elif action_name in ["list_files", "get_repository_info", "analyze_repository_content"]: |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "owner": gr.Textbox.update(visible=True)}) |
| elif action_name == "analyze_repository_by_url": |
| visibility_map.update({"repo_url": gr.Textbox.update(visible=True)}) |
| elif action_name == "update_repository_description": |
| visibility_map.update({"repo_name": gr.Textbox.update(visible=True), "new_description": gr.Textbox.update(visible=True)}) |
| return [visibility_map.get(key, gr.Textbox.update(visible=False)) for key in visibility_map] |
| output_components_visibility = [ |
| repo_name, branch, path, content, message, owner, vcs_url, title, body, base, head, issue_number, labels, |
| tag, release_name, file_url, repo_url, template_name, new_description, issue_title, issue_body, |
| issue_state, diff, diff_message |
| ] |
| action.change( |
| show_hide_input_fields, |
| inputs=[action], |
| outputs=output_components_visibility |
| ) |
| run_button.click( |
| github_tool, |
| inputs=input_components, |
| outputs=output, |
| api_name="github_tool" |
| ) |
| demo.launch() |