diff --git a/skills/create-qwik-vite/SKILL.md b/skills/create-qwik-vite/SKILL.md new file mode 100644 index 00000000..3ec1898d --- /dev/null +++ b/skills/create-qwik-vite/SKILL.md @@ -0,0 +1,33 @@ +--- +name: create-qwik-vite +description: Creates a new Qwik project using Vite and installs custom AI rules. +inputs: + - id: workspace_name + name: Workspace Name + type: string + description: The name of the folder for the new project +--- + +## When to Use This Skill + +Use this skill when the user wants to create a new Qwik project using Vite, and wants the project configured with custom AI rules. + +## Instructions + +1. **Read Setup Instructions** + Review the [setup instructions](resources/setup_instructions.md) to understand how to initialize the project and install dependencies. + + *Action:* Read `resources/setup_instructions.md`. + +2. **Execute Setup** + Follow the steps outlined in `resources/setup_instructions.md` to: + - Create the Qwik project (using the `workspace_name` input). + - Install dependencies. + - Create the `.agents/rules/qwik-vite.md` file using the content from `resources/ai_rules.md`. + - Ensure the `.agents/rules/` directory exists. + +3. **Final Verification** + Check that: + - `vite.config.ts` exists in the new project directory. + - `.agents/rules/qwik-vite.md` exists. + - `src/main.tsx` exists in the project's root. diff --git a/skills/create-qwik-vite/resources/ai_rules.md b/skills/create-qwik-vite/resources/ai_rules.md new file mode 100644 index 00000000..5ff33574 --- /dev/null +++ b/skills/create-qwik-vite/resources/ai_rules.md @@ -0,0 +1,34 @@ +# Gemini AI Rules for Qwik with Vite Projects + +## 1. Persona & Expertise + +You are an expert front-end developer specializing in building high-performance, resumable web applications with Qwik. You are proficient in TypeScript, JSX, and the unique concepts of Qwik, such as resumability, lazy loading, and the optimizer. You have a deep understanding of the Vite build tool and how it integrates with Qwik to provide a fast development experience. + +## 2. Project Context + +This project is a web application built with Qwik and uses Vite as the development server and build tool. The primary focus is on achieving near-instantaneous load times and outstanding performance by adhering to Qwik's core principles. This is a bare-bones Qwik project without the Qwik City meta-framework, so it does not include directory-based routing or `routeLoader$`. + +## 3. Coding Standards & Best Practices + +### General +- **Language:** Always use TypeScript and JSX. +- **Styling:** Use scoped styles (`useStylesScoped$`) to encapsulate component styles. +- **Dependencies:** After suggesting new npm dependencies, remind the user to run `npm install` or `yarn add`. +- **Testing:** Encourage the use of Vitest and Qwik Testing Library for unit and component testing. + +### Qwik & Vite Specific +- **Resumability First:** All code should be written with Qwik's resumability model in mind. Avoid patterns that require large amounts of client-side JavaScript execution on startup. +- **Lazy Loading (`component$`):** Define all components using `component$`. This is Qwik's fundamental building block for lazy loading, ensuring that component code is only downloaded when it's needed. +- **State Management (`useStore`, `useSignal`):** Use `useStore` for complex, reactive state and `useSignal` for simple, primitive values. +- **Data Fetching (`useResource$`):** For client-side data fetching (e.g., in response to a user interaction), use the `useResource$` hook. This allows for proper handling of loading and error states. +- **API Keys:** Never expose API keys on the client-side. For interacting with AI services, recommend creating a separate backend service or using serverless functions to keep API keys secure, as this template does not have a built-in server-side execution context like Qwik City. +- **Vite Configuration:** When modifying `vite.config.ts`, explain the purpose of the changes, especially if they affect Qwik's optimizer or build process. + +## 4. Interaction Guidelines + +- Assume the user is familiar with modern front-end development but may be new to Qwik's unique concepts like resumability. +- Provide clear and actionable code examples for creating Qwik components. +- Break down complex component creation into smaller steps: defining state, writing the JSX, and adding event handlers (`$`). +- If a request is ambiguous, ask for clarification about the component's state, props, or intended behavior. +- Emphasize the importance of Qwik's performance-first approach and how it differs from traditional client-side frameworks. +- Note that since this is not a Qwik City project, there are no server-side functions (`server$`) or route loaders (`routeLoader$`). All data fetching will be client-side. diff --git a/skills/create-qwik-vite/resources/setup_instructions.md b/skills/create-qwik-vite/resources/setup_instructions.md new file mode 100644 index 00000000..3ca06d26 --- /dev/null +++ b/skills/create-qwik-vite/resources/setup_instructions.md @@ -0,0 +1,86 @@ +# Qwik + Vite Workspace Setup Instructions + +Follow these steps to initialize the workspace. + +## 1. Install prerequisites (Node.js + npm) + +This skill requires Node.js (recommended 20.x+) and npm (which is bundled with Node). + +### 1.1. Verify Installation + +First, check if the tools are already available. If both commands return a version number, you can proceed to Step 2. + +```bash +node -v +npm -v +``` + +### 1.2. Automatic Installation (Recommended) + +If Node.js or npm are not installed or are outdated, use one of the following commands to automatically install the latest LTS version of Node.js. + +**For macOS or Linux (bash):** + +```bash +bash scripts/install_node_official.sh +``` + +Then restart your shell and verify the installation: + +```bash +node -v +npm -v +``` + +**For Windows (PowerShell):** + +```powershell +powershell -ExecutionPolicy Bypass -File "scripts/install_node_official.ps1" +``` + +Then restart your terminal and verify the installation: + +```bash +node -v +npm -v +``` + +## 2. Create the Project + +First, set a variable for your workspace name: + +- `WS_NAME=""` + +Then, use `npm create` to scaffold the new Qwik project with Vite. + +```bash +npm create -y vite@latest "$WS_NAME" -- --template qwik-ts +``` + +## 3. Install Dependencies + +Navigate into your new project directory and install the dependencies. + +```bash +cd "$WS_NAME" +npm install --package-lock-only --ignore-scripts +``` + +## 4. Configure Agents Rules + +Create the directory for the AI agent's rules. The skill will then copy the rule file into it. + +```bash +mkdir -p .agents/rules +``` + +(The skill runner will place the content of `resources/ai_rules.md` into `.agents/rules/qwik-vite.md`) + + +## 5. Run the Development Server + +Once dependencies are installed, you can start the Vite development server. + +```bash +npm run dev +``` diff --git a/skills/create-qwik-vite/scripts/install_node_official.ps1 b/skills/create-qwik-vite/scripts/install_node_official.ps1 new file mode 100644 index 00000000..fbe395b6 --- /dev/null +++ b/skills/create-qwik-vite/scripts/install_node_official.ps1 @@ -0,0 +1,102 @@ +# Installs the latest Node.js LTS from official nodejs.org releases (user-local install). +# - Detects CPU architecture +# - Fetches latest LTS from Node dist index.json +# - Downloads the official zip +# - Extracts to $env:LocalAppData/nodejs/ +# - Adds to user PATH (no sudo required) +# - Prompts to restart terminal + + +# Helper to get latest LTS version number from Node.js dist index.json +function Get-LatestLtsVersion { + $url = "https://nodejs.org/dist/index.json" + try { + $json = Invoke-RestMethod -Uri $url + $ltsVersion = $json | Where-Object { $_.lts } | Select-Object -First 1 | ForEach-Object { $_.version } + if ($ltsVersion) { + return $ltsVersion + } else { + throw "Could not find LTS version in $url" + } + } catch { + Write-Error "Error fetching or parsing Node.js version data: $_" + exit 1 + } +} + +# Helper to get platform/arch suffix for official release asset +function Get-PlatformSuffix { + $arch = $env:PROCESSOR_ARCHITECTURE + switch ($arch) { + "AMD64" { return "win-x64" } + "ARM64" { return "win-arm64" } + default { Write-Error "Unsupported architecture: $arch"; exit 1 } + } +} + +# Helper to parse major version from version string (e.g., "v20.10.0" -> 20) +function Get-MajorVersion($v) { + return ($v -replace "^v") -split '\.' | Select-Object -First 1 +} + +# If Node already installed and >= 20, do nothing. +if (Get-Command node -ErrorAction SilentlyContinue) { + $existing = (node -v) + $major = Get-MajorVersion $existing + if ($major -ge 20) { + Write-Output "Node is already installed ($existing). No action needed." + $npmV = (npm -v) + Write-Output "npm version: $npmV" + exit 0 + } + Write-Output "Node detected ($existing) but is < 20; proceeding to install latest LTS..." +} + +$version = Get-LatestLtsVersion +$platform = Get-PlatformSuffix +$zipName = "node-$version-$platform.zip" +$zipUrl = "https://nodejs.org/dist/$version/$zipName" + +$installBase = "$env:LOCALAPPDATA\nodejs" +if (-not (Test-Path $installBase)) { + New-Item -ItemType Directory -Path $installBase | Out-Null +} + +$tmpDir = New-Item -ItemType Directory -Path (Join-Path $env:TEMP ([System.Guid]::NewGuid().ToString())) + +Write-Output "Downloading $zipUrl" +$zipPath = Join-Path $tmpDir.FullName $zipName +Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath + +$extractedDirName = "node-$version-$platform" +$extractedDir = Join-Path $installBase $extractedDirName + +Write-Output "Extracting to $extractedDir" +Expand-Archive -Path $zipPath -DestinationPath $installBase + +if (-not (Test-Path $extractedDir)) { + Write-Error "Extraction failed; expected folder not found: $extractedDir" + exit 1 +} + +# Add to User PATH +$userPath = [System.Environment]::GetEnvironmentVariable("Path", "User") +if ($userPath -notlike "*$extractedDir*") { + Write-Output "Adding Node to user PATH" + $newPath = "$extractedDir;$userPath" + [System.Environment]::SetEnvironmentVariable("Path", $newPath, "User") +} + +# Also update current session PATH +$env:Path = "$extractedDir;" + $env:Path + +Write-Output "Installed Node $version" +Write-Output "Verify:" +node -v +npm -v + +Write-Output "" +Write-Output "Restart your terminal so PATH updates fully take effect." + +# Clean up temp folder +Remove-Item -Recurse -Force $tmpDir diff --git a/skills/create-qwik-vite/scripts/install_node_official.sh b/skills/create-qwik-vite/scripts/install_node_official.sh new file mode 100644 index 00000000..5a1135e1 --- /dev/null +++ b/skills/create-qwik-vite/scripts/install_node_official.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# Copyright 2024 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Official Node.js installation script for Linux and macOS. +# Downloads and installs the latest LTS version of Node.js. + +set -e # Exit on any error + +# 1. Determine OS and architecture +OS="$(uname | tr '[:upper:]' '[:lower:]')" +ARCH="$(uname -m)" + +NODE_MAJOR=20 # Specify the major version to install + +# 2. Check for existing Node.js installation +if command -v node &> /dev/null; then + CURRENT_VERSION=$(node -v | sed 's/v//' | cut -d '.' -f 1) + if [ "$CURRENT_VERSION" -ge "$NODE_MAJOR" ]; then + echo "Node.js version ${NODE_MAJOR}.x or higher is already installed." + exit 0 + fi +fi + +# 3. Construct the download URL +if [ "$OS" == "linux" ]; then + if [ "$ARCH" == "x86_64" ]; then + NODE_ARCH="x64" + elif [ "$ARCH" == "aarch64" ]; then + NODE_ARCH="arm64" + else + echo "Unsupported architecture: $ARCH" >&2 + exit 1 + fi + # Get the latest LTS version for the specified major version + NODE_VERSION=$(curl -sL "https://nodejs.org/dist/index.json" | grep -A 5 '"version": "v'$NODE_MAJOR'"' | grep '"lts":' | head -1 | awk -F'"' 'NR==1 {print $4}' | sed 's/v//') + DOWNLOAD_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz" +elif [ "$OS" == "darwin" ]; then # macOS + NODE_VERSION=$(curl -sL "https://nodejs.org/dist/index.json" | grep -A 5 '"version": "v'$NODE_MAJOR'"' | grep '"lts":' | head -1 | awk -F'"' 'NR==1 {print $4}' | sed 's/v//') + # For macOS, we can use the pkg installer + DOWNLOAD_URL="https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}.pkg" +else + echo "Unsupported operating system: $OS" >&2 + exit 1 +fi + +# 4. Download and install +if [ "$OS" == "linux" ]; then + echo "Downloading Node.js from ${DOWNLOAD_URL}..." + curl -L "$DOWNLOAD_URL" -o "/tmp/node.tar.xz" + + INSTALL_DIR="$HOME/.nvm/versions/node/v${NODE_VERSION}" + mkdir -p "$INSTALL_DIR" + tar -xJf "/tmp/node.tar.xz" -C "$INSTALL_DIR" --strip-components=1 + + # Add to PATH in shell profile + PROFILE_FILE="$HOME/.bashrc" + if [ -n "$ZSH_VERSION" ]; then + PROFILE_FILE="$HOME/.zshrc" + fi + + echo "export PATH=\"$INSTALL_DIR/bin:\$PATH\"" >> "$PROFILE_FILE" + echo "Node.js v${NODE_VERSION} has been installed." + echo "Please restart your shell or run 'source $PROFILE_FILE' to apply changes." + +elif [ "$OS" == "darwin" ]; then + echo "Downloading Node.js package from ${DOWNLOAD_URL}..." + curl -L "$DOWNLOAD_URL" -o "/tmp/node.pkg" + + echo "Running the installer... (You may be prompted for your password)" + sudo installer -pkg "/tmp/node.pkg" -target / + + echo "Node.js v${NODE_VERSION} has been installed." +fi + +# 5. Clean up +rm "/tmp/node.tar.xz" || rm "/tmp/node.pkg" || true