Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions skills/create-qwik-vite/SKILL.md
Original file line number Diff line number Diff line change
@@ -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.
34 changes: 34 additions & 0 deletions skills/create-qwik-vite/resources/ai_rules.md
Original file line number Diff line number Diff line change
@@ -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.
86 changes: 86 additions & 0 deletions skills/create-qwik-vite/resources/setup_instructions.md
Original file line number Diff line number Diff line change
@@ -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="<workspace_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
```
102 changes: 102 additions & 0 deletions skills/create-qwik-vite/scripts/install_node_official.ps1
Original file line number Diff line number Diff line change
@@ -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/<version>
# - 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
88 changes: 88 additions & 0 deletions skills/create-qwik-vite/scripts/install_node_official.sh
Original file line number Diff line number Diff line change
@@ -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