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
40 changes: 40 additions & 0 deletions Skills/create-vue/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: create-vue
description: Creates a new Vue.js project using create-vue (the official scaffolding tool), with optional TypeScript support and installs custom AI rules.
inputs:
- id: workspace_name
name: Workspace Name
type: string
description: The name of the folder for the new project
- id: language
name: Language
type: enum
default: ts
options:
js: JavaScript
ts: TypeScript
---

## When to Use This Skill

Use this skill when the user wants to create a new Vue.js project using `create-vue`, with either JavaScript or TypeScript, 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 Vue.js project (using the `workspace_name` and `language` inputs).
- Install dependencies.
- Create the `.agents/rules/vue.md` file using the content from `resources/ai_rules.md`.
- Ensure the `.agents/rules/` directory exists.

3. **Final Verification**
Check that:
- `package.json` exists in the new project
- `.agents/rules/vue.md` exists
- `src/main.ts` (or `src/main.js` depending on options) exists
103 changes: 103 additions & 0 deletions Skills/create-vue/Scripts/install_node_official.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# 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 %LOCALAPPDATA%\Programs\nodejs\<version>
# - Adds to user PATH (no admin required)
# - Prompts to restart terminal / Antigravity

$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

function Get-LatestLtsVersion {
$index = Invoke-RestMethod -Uri "https://nodejs.org/dist/index.json"
$lts = $index | Where-Object { $_.lts -ne $false } | Select-Object -First 1
if (-not $lts -or -not $lts.version) {
throw "Could not determine latest LTS from https://nodejs.org/dist/index.json"
}
return $lts.version # e.g., v20.11.1
}

function Get-PlatformSuffix {
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
"AMD64" { return "win-x64" }
"ARM64" { return "win-arm64" }
"x86" { return "win-x86" }
default { throw "Unsupported Windows architecture: $arch" }
}
}

function Get-MajorVersion([string]$v) {
# v like "v20.11.1"
$v = $v.Trim()
if ($v.StartsWith("v")) { $v = $v.Substring(1) }
return [int]($v.Split(".")[0])
}

# If Node already installed and >= 20, do nothing.
try {
$existing = & node -v 2>$null
if ($LASTEXITCODE -eq 0) {
$major = Get-MajorVersion $existing
if ($major -ge 20) {
Write-Host "Node is already installed ($existing). No action needed."
Write-Host "npm version: " -NoNewline; & npm -v
exit 0
}
Write-Host "Node detected ($existing) but < 20; proceeding to install latest LTS."
}
} catch {
# node not found
}

$version = Get-LatestLtsVersion
$platform = Get-PlatformSuffix
$zipName = "node-$version-$platform.zip"
$zipUrl = "https://nodejs.org/dist/$version/$zipName"

$installBase = Join-Path $env:LOCALAPPDATA "Programs\nodejs"
New-Item -ItemType Directory -Force -Path $installBase | Out-Null

$tmpDir = Join-Path $env:TEMP ("node-install-" + [guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Force -Path $tmpDir | Out-Null
$zipPath = Join-Path $tmpDir $zipName

try {
Write-Host "Downloading $zipUrl"
Invoke-WebRequest -Uri $zipUrl -OutFile $zipPath

Write-Host "Extracting to $installBase"
Expand-Archive -Path $zipPath -DestinationPath $installBase -Force

$extractedDir = Join-Path $installBase ("node-" + $version + "-" + $platform)
if (-not (Test-Path $extractedDir)) {
throw "Extraction failed; expected folder not found: $extractedDir"
}

# Add to user PATH if not present
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (-not $userPath) { $userPath = "" }

$already = $userPath.Split(";") | Where-Object { $_.Trim() -ieq $extractedDir }
if (-not $already) {
$newUserPath = ($extractedDir + ";" + $userPath).TrimEnd(";")
[Environment]::SetEnvironmentVariable("Path", $newUserPath, "User")
Write-Host "Added Node to user PATH: $extractedDir"
} else {
Write-Host "Node path already present in user PATH."
}

# Also update current session PATH
$env:Path = $extractedDir + ";" + $env:Path

Write-Host "Installed Node $version"
Write-Host "Verify:"
& node -v
& npm -v

Write-Host ""
Write-Host "Restart your terminal / Antigravity session so PATH updates fully."
} finally {
if (Test-Path $tmpDir) { Remove-Item -Recurse -Force $tmpDir }
}
152 changes: 152 additions & 0 deletions Skills/create-vue/Scripts/install_node_official.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env bash
set -euo pipefail

# Installs latest Node.js LTS from official nodejs.org releases (user-local install).
# - Detects OS + CPU arch
# - Fetches latest LTS from Node dist index.json
# - Downloads official tarball and installs under ~/.local/node/current
# - Updates shell profile PATH (bash/zsh/profile)
# - Prompts restart

need_cmd() { command -v "$1" >/dev/null 2>&1; }

if need_cmd node; then
ver="$(node -v)"
major="${ver#v}"; major="${major%%.*}"
if [[ "$major" -ge 20 ]]; then
echo "Node is already installed ($ver). No action needed."
npm -v || true
exit 0
fi
echo "Node detected ($ver) but < 20; proceeding to install latest LTS."
fi

DL_TOOL=""
if need_cmd curl; then DL_TOOL="curl -fsSL"
elif need_cmd wget; then DL_TOOL="wget -qO-"
else
echo "Error: need curl or wget"
exit 1
fi

OS="$(uname -s)"
ARCH="$(uname -m)"

case "$OS" in
Darwin) OS_TAG="darwin" ;;
Linux) OS_TAG="linux" ;;
*)
echo "Unsupported OS: $OS"
exit 1
;;
esac

case "$ARCH" in
x86_64|amd64) ARCH_TAG="x64" ;;
arm64|aarch64) ARCH_TAG="arm64" ;;
armv7l) ARCH_TAG="armv7l" ;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac

INDEX_JSON="$($DL_TOOL https://nodejs.org/dist/index.json)"

# Parse latest LTS version:
if need_cmd jq; then
VERSION="$(printf '%s' "$INDEX_JSON" | jq -r '.[] | select(.lts != false) | .version' | head -n 1)"
elif need_cmd python3; then
VERSION="$(python3 - <<'PY'
import json,sys
data=json.load(sys.stdin)
for r in data:
if r.get("lts") not in (False, None):
print(r["version"])
break
PY
<<<"$INDEX_JSON")"
else
echo "Error: need jq or python3 to parse Node release index.json"
exit 1
fi

if [[ -z "${VERSION:-}" || "${VERSION}" == "null" ]]; then
echo "Error: could not determine latest LTS version"
exit 1
fi

PLATFORM="${OS_TAG}-${ARCH_TAG}"

# Node uses .tar.gz for macOS builds, and .tar.xz for Linux builds.
EXT="tar.xz"
[[ "$OS_TAG" == "darwin" ]] && EXT="tar.gz"

TARBALL="node-${VERSION}-${PLATFORM}.${EXT}"
URL="https://nodejs.org/dist/${VERSION}/${TARBALL}"

INSTALL_BASE="${INSTALL_BASE:-$HOME/.local/node}"
INSTALL_DIR="${INSTALL_BASE}/${VERSION}"

mkdir -p "$INSTALL_BASE"

TMP="$(mktemp -d)"
cleanup() { rm -rf "$TMP"; }
trap cleanup EXIT

echo "Downloading $URL"
if need_cmd curl; then
curl -fsSL "$URL" -o "$TMP/$TARBALL"
else
wget -q "$URL" -O "$TMP/$TARBALL"
fi

echo "Installing to $INSTALL_DIR"
rm -rf "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR"

if [[ "$EXT" == "tar.gz" ]]; then
tar -xzf "$TMP/$TARBALL" -C "$TMP"
else
tar -xJf "$TMP/$TARBALL" -C "$TMP"
fi

EXTRACTED="$TMP/node-${VERSION}-${PLATFORM}"
if [[ ! -d "$EXTRACTED" ]]; then
echo "Error: expected extracted folder not found: $EXTRACTED"
exit 1
fi

# Move contents into versioned install dir
cp -R "$EXTRACTED"/. "$INSTALL_DIR"/

# Update 'current' symlink
ln -sfn "$INSTALL_DIR" "$INSTALL_BASE/current"

NODE_BIN="$INSTALL_BASE/current/bin"
EXPORT_LINE="export PATH="$NODE_BIN:$PATH""
MARKER="# >>> antigravity node >>>"

write_profile() {
local f="$1"
[[ -f "$f" ]] || touch "$f"
if ! grep -q "$MARKER" "$f"; then
{
echo ""
echo "$MARKER"
echo "$EXPORT_LINE"
echo "# <<< antigravity node <<<"
} >> "$f"
fi
}

# Update common profiles
write_profile "$HOME/.bashrc"
write_profile "$HOME/.zshrc"
write_profile "$HOME/.profile"

echo ""
echo "Installed Node ${VERSION} under $INSTALL_BASE/current"
echo "Restart your shell / Antigravity session, then verify:"
echo " node -v"
echo " npm -v"
46 changes: 46 additions & 0 deletions Skills/create-vue/resources/ai_rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Gemini AI Rules for Vue with Vite Projects

## 1. Persona & Expertise

You are an expert front-end developer specializing in building fast and modern web applications with Vue and Vite. You are proficient in TypeScript, Vue's template syntax, and the broader Vue ecosystem. Your expertise includes component-based architecture, state management with Pinia, performance optimization, and leveraging Vite's features for a rapid and efficient development workflow.

## 2. Project Context

This project is a front-end application built with Vue and TypeScript, using Vite as the development server and build tool. It is designed to be developed within the Firebase Studio (formerly Project IDX) environment. The focus is on creating a fast, responsive, and maintainable application.

## 3. Development Environment

This project is configured to run in a pre-built developer environment provided by Firebase Studio. The environment is defined in the `dev.nix` file and includes the following:

- **Runtime:** Node.js 20.
- **Tools:** Git and VS Code.
- **Workspace Setup:** On creation, the workspace automatically runs `npm install` to install dependencies and opens `src/App.vue` (or equivalent).
- **Previews:** The web preview is enabled and configured to run `npm run dev`.

When providing instructions, assume that these tools are pre-installed and configured.

## 4. Coding Standards & Best Practices

### General
- **Language:** Always use TypeScript and Vue's template syntax. Adhere to modern Vue best practices, including the Composition API.
- **Styling:** Use scoped CSS or a popular CSS-in-JS library like Emotion or styled-components.
- **Dependencies:** After suggesting new npm dependencies, remind the user to run `npm install`.
- **Testing:** Encourage the use of Vitest and Vue Test Utils for unit and component testing.

### Vue & Vite Specific
- **Component Structure:** Build the UI using small, reusable, single-file components.
- **State Management:** For simple to moderate state needs, use Vue's built-in reactivity APIs. For more complex, global state, suggest Pinia.
- **Performance:**
- **Lazy Loading:** Use `defineAsyncComponent` for code-splitting and lazy loading components, especially for different routes.
- **Memoization:** Use `computed` properties for memoizing expensive calculations.
- **Vite Configuration:** When modifying `vite.config.ts`, explain the purpose of the changes, whether it's adding a plugin, setting up path aliases, or configuring the proxy.
- **API Keys:** Never expose API keys on the client-side. For interacting with AI services, recommend creating a backend proxy or using serverless functions to keep API keys secure.
- **Error Handling:** Implement robust error handling, especially for asynchronous operations like API calls. Use `onErrorCaptured` to catch and handle errors in the component tree.

## 5. Interaction Guidelines

- Assume the user is familiar with Vue and modern front-end development concepts.
- Provide clear, concise, and actionable code examples for Vue components, composables, and Vite configurations.
- When generating a new component, provide the full file content for a `.vue` file.
- If a request is ambiguous, ask for clarification regarding component state, props, or desired behavior.
- Break down complex tasks into smaller steps: defining state and props, writing the template, adding event handlers, and writing tests.
Loading