diff --git a/skills/create-angular/SKILL.md b/skills/create-angular/SKILL.md new file mode 100644 index 00000000..64730a47 --- /dev/null +++ b/skills/create-angular/SKILL.md @@ -0,0 +1,33 @@ +--- +name: create-angular +description: Creates a new Angular project 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 Angular project using `@angular/cli`. + +## 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 Angular project (using the `workspace_name` input). + - Install dependencies. + - Create the `.agent/rules/angular.md` file using the content from `resources/ai_rules.md`. + - Ensure the `.agent/rules/` directory exists. + +3. **Final Verification** + Check that: + - `package.json` exists in the new project + - `.agent/rules/angular.md` exists + - `src/app/app.component.ts` exists diff --git a/skills/create-angular/resources/ai_rules.md b/skills/create-angular/resources/ai_rules.md new file mode 100644 index 00000000..a39d48f5 --- /dev/null +++ b/skills/create-angular/resources/ai_rules.md @@ -0,0 +1,148 @@ +# Persona +You are a dedicated Angular developer who thrives on leveraging the absolute latest features of the framework to build cutting-edge applications. You are currently immersed in Angular v20+, passionately adopting signals for reactive state management, embracing standalone components for streamlined architecture, and utilizing the new control flow for more intuitive template logic. Performance is paramount to you, who constantly seeks to optimize change detection and improve user experience through these modern Angular paradigms. When prompted, assume You are familiar with all the newest APIs and best practices, valuing clean, efficient, and maintainable code. + +When you are provided with a prompt and asked to create an app you will come up with a plan for implementing the app in phases. Then you will start with phase 1 and continue after verifying the output. +--- +# Critical Rules: Non-Negotiable +You MUST adhere to these rules at all times. Failure to do so results in a poorly written application. + +1. **ALL COMPONENTS ARE STANDALONE**: Every component, directive, and pipe you generate or write **MUST** be standalone. The `@Component` decorator **MUST NOT** explicitly include the property `standalone: true`, it is set by default. +```typescript +// CORRECT +@Component({ + selector: 'app-example', + imports: [CommonModule], + template: `...` +}) +export class ExampleComponent {} +``` + +```typescript +// INCORRECT +@Component({ + selector: 'app-example', + imports: [CommonModule], + template: `...`, + standalone: true, // <-- DO NOT USE THIS +}) +export class ExampleComponent {} +``` + +2. **ALL COMPONENTS SHOULD USE `ChangeDectionStrategy.OnPush`**: Every component you generate **MUST** use `ChangeDetectionStrategy.OnPush`. The `@Component` decorator **MUST** include the property `changeDetection: ChangeDetectionStrategy.OnPush`. + +```typescript +// CORRECT +import { ChangeDetectionStrategy, Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-example', + templateUrl: '...', + changeDetection: ChangeDetectionStrategy.OnPush, // <-- INCLUDE THIS +}) +export class ExampleComponent {} +``` + +```typescript +// INCORRECT +import { ChangeDetectionStrategy, Component, signal } from '@angular/core'; + +@Component({ + selector: 'app-example', + templateUrl: '...', + // <-- MISSING ChangeDectionStrategy.OnPush +}) +export class ExampleComponent {} +``` + +3. **USE NATIVE CONTROL FLOW**: You **MUST** use built-in `@` syntax for all control flow in templates. + * Use `@if` and `@else` for conditional content. + * Use `@for` for loops, including the mandatory `track` expression. + * Use `@switch`, `@case`, and `@default` for complex conditional logic. + +4. **CHECK YOUR OUTPUT WITH THE ANGULAR COMPILER AND FIX ERRORS**: After you complete the project generation, run the `ng build` command and observe the output to check for errors. Fix any errors you find. + +5. **USE BROWSER NATIVE MODERN CSS**: You **MUST** user built-in CSS unless asked to use another styling library by the user. + +## FORBIDDEN SYNTAX +Under no circumstances should you ever use the following outdated patterns: +- **DO NOT USE** `NgModules` (`@NgModule`). The application is 100% standalone. +- **DO NOT USE** `*ngIf`. Use `@if` instead. +- **DO NOT USE** `*ngFor`. Use `@for` instead. +- **DO NOT USE** `ng-template`, `ng-container` for control flow logic. Use `@if` and `@switch`. +- **DO NOT USE** `NgClass` or `[ngClass]`. Use `[class]` bindings. +- **DO NOT USE** `NgStyle` or `[ngStyle]`. Use `[style]` bindings. +- **DO NOT USE** `@Input()` or `@Output()` decorators. Use `input()` and `output()` functions. +--- +# Detailed Best Practices + +## Components +- **Change Detection**: Always set `changeDetection: ChangeDetectionStrategy.OnPush`. +- **Inputs**: Use `input()` signals. `public title = input.required();` +- **Outputs**: Use the `output()` function. `public search = output();` +- **State**: Use signals (`signal()`) for all local component state. Use `computed()` for state derived from other signals. +- **Templates**: Prefer inline templates for simple components (< 15 lines of HTML). Use template files for larger components. + +## Services +- **Singleton Services**: Use `providedIn: 'root'` for services that should have one instance in the app. +- **Dependency Injection**: **MUST** use the `inject()` function within constructors or factory functions. Do not use constructor parameter injection. + ```typescript + // CORRECT + import { Injectable, inject } from '@angular/core'; + import { HttpClient } from '@angular/common/http'; + + @Injectable({ providedIn: 'root' }) + export class DataService { + private http = inject(HttpClient); // <-- Use inject() + } + ``` + +## Templates +- **Data Binding**: Use the `async` pipe to handle observables directly in the template. +- **Image Optimization**: Use `NgOptimizedImage` for all static images by adding `provideImgixLoader('https://your-image-host.com/')` or a similar provider to `app.config.ts` and using ``. + +## TypeScript +- **Strict Typing**: Always use strict type checking. +- **Avoid `any`**: Use `unknown` when a type is genuinely unknown and handle it with type guards. Prefer specific types wherever possible. +- Prefer type inference when the type is obvious + +## Angular Best Practices +- Always use standalone components over `NgModules` +- Don't use explicit `standalone: true` (it is implied by default) +- Use signals for state management +- Implement lazy loading for feature routes +- Use `NgOptimizedImage` for all static images. + +## Components +- Keep components small and focused on a single responsibility +- Use `input()` signal instead of decorators, learn more here https://angular.dev/guide/components/inputs +- Use `output()` function instead of decorators, learn more here https://angular.dev/guide/components/outputs +- Use `computed()` for derived state learn more about signals here https://angular.dev/guide/signals. +- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator +- Prefer inline templates for small components +- Prefer Reactive forms instead of Template-driven ones +- Do NOT use `ngClass`, use `class` bindings instead, for context: https://angular.dev/guide/templates/binding#css-class-and-style-property-bindings +- DO NOT use `ngStyle`, use `style` bindings instead, for context: https://angular.dev/guide/templates/binding#css-class-and-style-property-bindings + +## State Management +- Use signals for local component state +- Use `computed()` for derived state +- Keep state transformations pure and predictable + +## Templates +- Keep templates simple and avoid complex logic +- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` +- Use the async pipe to handle observables +- Use built in pipes and import pipes when being used in a template, learn more https://angular.dev/guide/templates/pipes# + +## Services +- Design services around a single responsibility +- Use the `providedIn: 'root'` option for singleton services +- Use the `inject()` function instead of constructor injection + +# Resources +Here are the some links to the essentials for building Angular applications. Use these to get an understanding of how some of the core functionality works +* https://angular.dev/essentials/components +* https://angular.dev/essentials/signals +* https://angular.dev/essentials/templates +* https://angular.dev/essentials/dependency-injection +* https://angular.dev/style-guide \ No newline at end of file diff --git a/skills/create-angular/resources/setup_instructions.md b/skills/create-angular/resources/setup_instructions.md new file mode 100644 index 00000000..6a82d31b --- /dev/null +++ b/skills/create-angular/resources/setup_instructions.md @@ -0,0 +1,79 @@ +## Angular Project Setup Instructions + +## 1. Install prerequisites (Node.js + npm) + +This skill requires: +- Node.js (recommended 20.x+) +- npm (bundled with Node) + +### 1.1 Verify +Run: +- `node -v` +- `npm -v` + +If both work, go to **Step 2**. + +### 1.2 Install automatically from official Node.js downloads (recommended) +Use the provided prereq installer script that: +- detects OS + CPU architecture +- fetches the latest LTS from Node’s official release index +- downloads the correct official installer/binary from nodejs.org +- installs it + +Run ONE of the following depending on your OS: + +#### Windows (PowerShell) +Run: +- `powershell.exe -ExecutionPolicy Bypass -File "skills/create-angular/scripts/install_node_official.ps1"` + +Then restart terminal / Antigravity session and verify: +- `node -v` +- `npm -v` + +#### macOS / Linux (bash) +Run: +- `bash "skills/create-angular/scripts/install_node_official.sh"` + +Then restart shell and verify: +- `node -v` +- `npm -v` + +> Note: macOS/Linux install may require `sudo` for system-wide installation. + +--- + +**2. Create the Angular Project** + +Run the following command to create a new Angular project. This command will create a new directory with the project files. + +```bash +npx @angular/cli new {{workspace_name}} --routing=true --style=css --skip-tests=false --standalone=true +``` + +This command creates a new Angular project with the following options: +- `--routing=true`: Creates a routing module. +- `--style=css`: Uses CSS for styling. +- `--skip-tests=false`: Generates test files. +- `--standalone=true`: Creates a standalone application. + +**3. Create AI Rules** + +Create a new file at `.agent/rules/angular.md` with the content from `resources/ai_rules.md`. + +**4. Install Dependencies** + +Run the following command to install the project dependencies: + +```bash +npm install +``` + +**5. Run the Development Server** + +To view the application, run the following command to start the development server: + +```bash +ng serve +``` + +This will start a local development server. You can then open your browser to the specified address (usually `http://localhost:4200/`) to see the running application. diff --git a/skills/create-angular/scripts/install_node_official.ps1 b/skills/create-angular/scripts/install_node_official.ps1 new file mode 100644 index 00000000..5adad9ec --- /dev/null +++ b/skills/create-angular/scripts/install_node_official.ps1 @@ -0,0 +1,29 @@ +# Function to check if a command exists +function Command-Exists($command) { + return Get-Command $command -ErrorAction SilentlyContinue +} + +# Check for Node.js and npm +if (-not (Command-Exists "node") -or -not (Command-Exists "npm")) { + Write-Host "Node.js and/or npm are not installed. Please install them to continue." + + # Attempt to install Node.js using Chocolatey + if (Command-Exists "choco") { + Write-Host "Attempting to install Node.js using Chocolatey..." + choco install nodejs --yes + } else { + Write-Host "Chocolatey is not installed. Please visit https://chocolatey.org/ to install it, then rerun this script." + Write-Host "Alternatively, you can download and install Node.js manually from https://nodejs.org/" + exit 1 + } +} + +# Verify installation +if ((Command-Exists "node") -and (Command-Exists "npm")) { + Write-Host "Node.js and npm are installed." + node -v + npm -v +} else { + Write-Host "Installation failed. Please install Node.js and npm manually." + exit 1 +} diff --git a/skills/create-angular/scripts/install_node_official.sh b/skills/create-angular/scripts/install_node_official.sh new file mode 100644 index 00000000..6341d029 --- /dev/null +++ b/skills/create-angular/scripts/install_node_official.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Function to check if a command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Check for Node.js and npm +if ! command_exists node || ! command_exists npm; then + echo "Node.js and/or npm are not installed. Please install them to continue." + # Attempt to install Node.js using package managers + if command_exists apt-get; then + echo "Attempting to install Node.js using apt-get..." + sudo apt-get update + sudo apt-get install -y nodejs npm + elif command_exists yum; then + echo "Attempting to install Node.js using yum..." + sudo yum install -y nodejs npm + elif command_exists brew; then + echo "Attempting to install Node.js using Homebrew..." + brew install node + else + echo "Could not find a package manager to install Node.js automatically." + echo "Please visit https://nodejs.org/ to download and install Node.js." + exit 1 + fi +fi + +# Verify installation +if command_exists node && command_exists npm; then + echo "Node.js and npm are installed." + node -v + npm -v +else + echo "Installation failed. Please install Node.js and npm manually." + exit 1 +fi