mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 17:47:16 +00:00
feat: add 5 new specialized agents with 20 skills
Add domain expert agents with comprehensive skill sets: - service-mesh-expert (cloud-infrastructure): Istio/Linkerd patterns, mTLS, observability - event-sourcing-architect (backend-development): CQRS, event stores, projections, sagas - vector-database-engineer (llm-application-dev): embeddings, similarity search, hybrid search - monorepo-architect (developer-essentials): Nx, Turborepo, Bazel, pnpm workspaces - threat-modeling-expert (security-scanning): STRIDE, attack trees, security requirements Update all documentation to reflect correct counts: - 67 plugins, 99 agents, 107 skills, 71 commands
This commit is contained in:
@@ -0,0 +1,452 @@
|
||||
---
|
||||
name: nx-workspace-patterns
|
||||
description: Configure and optimize Nx monorepo workspaces. Use when setting up Nx, configuring project boundaries, optimizing build caching, or implementing affected commands.
|
||||
---
|
||||
|
||||
# Nx Workspace Patterns
|
||||
|
||||
Production patterns for Nx monorepo management.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Setting up new Nx workspaces
|
||||
- Configuring project boundaries
|
||||
- Optimizing CI with affected commands
|
||||
- Implementing remote caching
|
||||
- Managing dependencies between projects
|
||||
- Migrating to Nx
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### 1. Nx Architecture
|
||||
|
||||
```
|
||||
workspace/
|
||||
├── apps/ # Deployable applications
|
||||
│ ├── web/
|
||||
│ └── api/
|
||||
├── libs/ # Shared libraries
|
||||
│ ├── shared/
|
||||
│ │ ├── ui/
|
||||
│ │ └── utils/
|
||||
│ └── feature/
|
||||
│ ├── auth/
|
||||
│ └── dashboard/
|
||||
├── tools/ # Custom executors/generators
|
||||
├── nx.json # Nx configuration
|
||||
└── workspace.json # Project configuration
|
||||
```
|
||||
|
||||
### 2. Library Types
|
||||
|
||||
| Type | Purpose | Example |
|
||||
|------|---------|---------|
|
||||
| **feature** | Smart components, business logic | `feature-auth` |
|
||||
| **ui** | Presentational components | `ui-buttons` |
|
||||
| **data-access** | API calls, state management | `data-access-users` |
|
||||
| **util** | Pure functions, helpers | `util-formatting` |
|
||||
| **shell** | App bootstrapping | `shell-web` |
|
||||
|
||||
## Templates
|
||||
|
||||
### Template 1: nx.json Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
||||
"npmScope": "myorg",
|
||||
"affected": {
|
||||
"defaultBase": "main"
|
||||
},
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "nx/tasks-runners/default",
|
||||
"options": {
|
||||
"cacheableOperations": [
|
||||
"build",
|
||||
"lint",
|
||||
"test",
|
||||
"e2e",
|
||||
"build-storybook"
|
||||
],
|
||||
"parallel": 3
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["production", "^production"],
|
||||
"cache": true
|
||||
},
|
||||
"test": {
|
||||
"inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"],
|
||||
"cache": true
|
||||
},
|
||||
"lint": {
|
||||
"inputs": ["default", "{workspaceRoot}/.eslintrc.json"],
|
||||
"cache": true
|
||||
},
|
||||
"e2e": {
|
||||
"inputs": ["default", "^production"],
|
||||
"cache": true
|
||||
}
|
||||
},
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
||||
"production": [
|
||||
"default",
|
||||
"!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)",
|
||||
"!{projectRoot}/tsconfig.spec.json",
|
||||
"!{projectRoot}/jest.config.[jt]s",
|
||||
"!{projectRoot}/.eslintrc.json"
|
||||
],
|
||||
"sharedGlobals": [
|
||||
"{workspaceRoot}/babel.config.json",
|
||||
"{workspaceRoot}/tsconfig.base.json"
|
||||
]
|
||||
},
|
||||
"generators": {
|
||||
"@nx/react": {
|
||||
"application": {
|
||||
"style": "css",
|
||||
"linter": "eslint",
|
||||
"bundler": "webpack"
|
||||
},
|
||||
"library": {
|
||||
"style": "css",
|
||||
"linter": "eslint"
|
||||
},
|
||||
"component": {
|
||||
"style": "css"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Template 2: Project Configuration
|
||||
|
||||
```json
|
||||
// apps/web/project.json
|
||||
{
|
||||
"name": "web",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/web/src",
|
||||
"projectType": "application",
|
||||
"tags": ["type:app", "scope:web"],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"compiler": "babel",
|
||||
"outputPath": "dist/apps/web",
|
||||
"index": "apps/web/src/index.html",
|
||||
"main": "apps/web/src/main.tsx",
|
||||
"tsConfig": "apps/web/tsconfig.app.json",
|
||||
"assets": ["apps/web/src/assets"],
|
||||
"styles": ["apps/web/src/styles.css"]
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"extractLicenses": false,
|
||||
"optimization": false,
|
||||
"sourceMap": true
|
||||
},
|
||||
"production": {
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractLicenses": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nx/webpack:dev-server",
|
||||
"defaultConfiguration": "development",
|
||||
"options": {
|
||||
"buildTarget": "web:build"
|
||||
},
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "web:build:development"
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "web:build:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
|
||||
"options": {
|
||||
"jestConfig": "apps/web/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/web/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Template 3: Module Boundary Rules
|
||||
|
||||
```json
|
||||
// .eslintrc.json
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": ["**/*"],
|
||||
"plugins": ["@nx"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {
|
||||
"@nx/enforce-module-boundaries": [
|
||||
"error",
|
||||
{
|
||||
"enforceBuildableLibDependency": true,
|
||||
"allow": [],
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "type:app",
|
||||
"onlyDependOnLibsWithTags": [
|
||||
"type:feature",
|
||||
"type:ui",
|
||||
"type:data-access",
|
||||
"type:util"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:feature",
|
||||
"onlyDependOnLibsWithTags": [
|
||||
"type:ui",
|
||||
"type:data-access",
|
||||
"type:util"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:ui",
|
||||
"onlyDependOnLibsWithTags": ["type:ui", "type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:data-access",
|
||||
"onlyDependOnLibsWithTags": ["type:data-access", "type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "type:util",
|
||||
"onlyDependOnLibsWithTags": ["type:util"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:web",
|
||||
"onlyDependOnLibsWithTags": ["scope:web", "scope:shared"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:api",
|
||||
"onlyDependOnLibsWithTags": ["scope:api", "scope:shared"]
|
||||
},
|
||||
{
|
||||
"sourceTag": "scope:shared",
|
||||
"onlyDependOnLibsWithTags": ["scope:shared"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Template 4: Custom Generator
|
||||
|
||||
```typescript
|
||||
// tools/generators/feature-lib/index.ts
|
||||
import {
|
||||
Tree,
|
||||
formatFiles,
|
||||
generateFiles,
|
||||
joinPathFragments,
|
||||
names,
|
||||
readProjectConfiguration,
|
||||
} from '@nx/devkit';
|
||||
import { libraryGenerator } from '@nx/react';
|
||||
|
||||
interface FeatureLibraryGeneratorSchema {
|
||||
name: string;
|
||||
scope: string;
|
||||
directory?: string;
|
||||
}
|
||||
|
||||
export default async function featureLibraryGenerator(
|
||||
tree: Tree,
|
||||
options: FeatureLibraryGeneratorSchema
|
||||
) {
|
||||
const { name, scope, directory } = options;
|
||||
const projectDirectory = directory
|
||||
? `${directory}/${name}`
|
||||
: `libs/${scope}/feature-${name}`;
|
||||
|
||||
// Generate base library
|
||||
await libraryGenerator(tree, {
|
||||
name: `feature-${name}`,
|
||||
directory: projectDirectory,
|
||||
tags: `type:feature,scope:${scope}`,
|
||||
style: 'css',
|
||||
skipTsConfig: false,
|
||||
skipFormat: true,
|
||||
unitTestRunner: 'jest',
|
||||
linter: 'eslint',
|
||||
});
|
||||
|
||||
// Add custom files
|
||||
const projectConfig = readProjectConfiguration(tree, `${scope}-feature-${name}`);
|
||||
const projectNames = names(name);
|
||||
|
||||
generateFiles(
|
||||
tree,
|
||||
joinPathFragments(__dirname, 'files'),
|
||||
projectConfig.sourceRoot,
|
||||
{
|
||||
...projectNames,
|
||||
scope,
|
||||
tmpl: '',
|
||||
}
|
||||
);
|
||||
|
||||
await formatFiles(tree);
|
||||
}
|
||||
```
|
||||
|
||||
### Template 5: CI Configuration with Affected
|
||||
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
env:
|
||||
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
|
||||
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Derive SHAs for affected commands
|
||||
uses: nrwl/nx-set-shas@v4
|
||||
|
||||
- name: Run affected lint
|
||||
run: npx nx affected -t lint --parallel=3
|
||||
|
||||
- name: Run affected test
|
||||
run: npx nx affected -t test --parallel=3 --configuration=ci
|
||||
|
||||
- name: Run affected build
|
||||
run: npx nx affected -t build --parallel=3
|
||||
|
||||
- name: Run affected e2e
|
||||
run: npx nx affected -t e2e --parallel=1
|
||||
```
|
||||
|
||||
### Template 6: Remote Caching Setup
|
||||
|
||||
```typescript
|
||||
// nx.json with Nx Cloud
|
||||
{
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "nx-cloud",
|
||||
"options": {
|
||||
"cacheableOperations": ["build", "lint", "test", "e2e"],
|
||||
"accessToken": "your-nx-cloud-token",
|
||||
"parallel": 3,
|
||||
"cacheDirectory": ".nx/cache"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nxCloudAccessToken": "your-nx-cloud-token"
|
||||
}
|
||||
|
||||
// Self-hosted cache with S3
|
||||
{
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "@nx-aws-cache/nx-aws-cache",
|
||||
"options": {
|
||||
"cacheableOperations": ["build", "lint", "test"],
|
||||
"awsRegion": "us-east-1",
|
||||
"awsBucket": "my-nx-cache-bucket",
|
||||
"awsProfile": "default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Generate new library
|
||||
nx g @nx/react:lib feature-auth --directory=libs/web --tags=type:feature,scope:web
|
||||
|
||||
# Run affected tests
|
||||
nx affected -t test --base=main
|
||||
|
||||
# View dependency graph
|
||||
nx graph
|
||||
|
||||
# Run specific project
|
||||
nx build web --configuration=production
|
||||
|
||||
# Reset cache
|
||||
nx reset
|
||||
|
||||
# Run migrations
|
||||
nx migrate latest
|
||||
nx migrate --run-migrations
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Do's
|
||||
- **Use tags consistently** - Enforce with module boundaries
|
||||
- **Enable caching early** - Significant CI savings
|
||||
- **Keep libs focused** - Single responsibility
|
||||
- **Use generators** - Ensure consistency
|
||||
- **Document boundaries** - Help new developers
|
||||
|
||||
### Don'ts
|
||||
- **Don't create circular deps** - Graph should be acyclic
|
||||
- **Don't skip affected** - Test only what changed
|
||||
- **Don't ignore boundaries** - Tech debt accumulates
|
||||
- **Don't over-granularize** - Balance lib count
|
||||
|
||||
## Resources
|
||||
|
||||
- [Nx Documentation](https://nx.dev/getting-started/intro)
|
||||
- [Module Boundaries](https://nx.dev/core-features/enforce-module-boundaries)
|
||||
- [Nx Cloud](https://nx.app/)
|
||||
Reference in New Issue
Block a user