claude-code-orchestrator-kit 1.4.1 → 1.4.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/business/workers/lead-research-assistant.md +199 -0
- package/.claude/agents/database/workers/database-architect.md +3 -3
- package/.claude/agents/database/workers/supabase-auditor.md +7 -7
- package/.claude/agents/development/workers/code-reviewer.md +17 -2
- package/.claude/agents/frontend/workers/nextjs-ui-designer.md +30 -0
- package/.claude/agents/health/workers/bug-fixer.md +31 -2
- package/.claude/agents/health/workers/bug-hunter.md +0 -1
- package/.claude/agents/health/workers/dead-code-hunter.md +167 -75
- package/.claude/agents/health/workers/dead-code-remover.md +217 -66
- package/.claude/agents/health/workers/dependency-auditor.md +83 -24
- package/.claude/agents/health/workers/dependency-updater.md +0 -1
- package/.claude/agents/health/workers/security-scanner.md +0 -1
- package/.claude/agents/infrastructure/workers/deployment-engineer.md +446 -0
- package/.claude/agents/infrastructure/workers/infrastructure-specialist.md +2 -2
- package/.claude/agents/meta/workers/meta-agent-v3.md +22 -0
- package/.claude/agents/testing/workers/integration-tester.md +1 -1
- package/.claude/agents/testing/workers/test-writer.md +16 -0
- package/.claude/commands/health-bugs.md +14 -281
- package/.claude/commands/health-cleanup.md +14 -281
- package/.claude/commands/health-deps.md +14 -281
- package/.claude/commands/health-metrics.md +51 -709
- package/.claude/commands/health-reuse.md +14 -311
- package/.claude/commands/health-security.md +14 -281
- package/.claude/commands/push.md +17 -3
- package/.claude/commands/speckit.implement.md +0 -11
- package/.claude/commands/worktree.md +150 -0
- package/.claude/scripts/gates/check-bundle-size.sh +0 -0
- package/.claude/scripts/gates/check-coverage.sh +0 -0
- package/.claude/scripts/gates/check-security.sh +0 -0
- package/.claude/scripts/release.sh +469 -94
- package/.claude/skills/algorithmic-art/LICENSE.txt +202 -0
- package/.claude/skills/algorithmic-art/SKILL.md +405 -0
- package/.claude/skills/algorithmic-art/templates/generator_template.js +223 -0
- package/.claude/skills/algorithmic-art/templates/viewer.html +599 -0
- package/.claude/skills/artifacts-builder/LICENSE.txt +202 -0
- package/.claude/skills/artifacts-builder/SKILL.md +74 -0
- package/.claude/skills/artifacts-builder/scripts/bundle-artifact.sh +54 -0
- package/.claude/skills/artifacts-builder/scripts/init-artifact.sh +322 -0
- package/.claude/skills/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/.claude/skills/bug-health-inline/SKILL.md +221 -0
- package/.claude/skills/bug-health-inline/references/worker-prompts.md +182 -0
- package/.claude/skills/canvas-design/LICENSE.txt +202 -0
- package/.claude/skills/canvas-design/SKILL.md +130 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/.claude/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Jura-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/.claude/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/.claude/skills/changelog-generator/SKILL.md +104 -0
- package/.claude/skills/cleanup-health-inline/SKILL.md +224 -0
- package/.claude/skills/code-reviewer/SKILL.md +209 -0
- package/.claude/skills/code-reviewer/references/code_review_checklist.md +103 -0
- package/.claude/skills/code-reviewer/references/coding_standards.md +103 -0
- package/.claude/skills/code-reviewer/references/common_antipatterns.md +103 -0
- package/.claude/skills/code-reviewer/scripts/code_quality_checker.py +114 -0
- package/.claude/skills/code-reviewer/scripts/pr_analyzer.py +114 -0
- package/.claude/skills/code-reviewer/scripts/review_report_generator.py +114 -0
- package/.claude/skills/content-research-writer/SKILL.md +538 -0
- package/.claude/skills/deps-health-inline/SKILL.md +227 -0
- package/.claude/skills/frontend-aesthetics/SKILL.md +51 -396
- package/.claude/skills/git-commit-helper/SKILL.md +203 -0
- package/.claude/skills/lead-research-assistant/SKILL.md +199 -0
- package/.claude/skills/reuse-health-inline/SKILL.md +248 -0
- package/.claude/skills/rollback-changes/SKILL.md +50 -524
- package/.claude/skills/run-quality-gate/SKILL.md +36 -346
- package/.claude/skills/security-health-inline/SKILL.md +224 -0
- package/.claude/skills/senior-devops/SKILL.md +209 -0
- package/.claude/skills/senior-devops/references/cicd_pipeline_guide.md +103 -0
- package/.claude/skills/senior-devops/references/deployment_strategies.md +103 -0
- package/.claude/skills/senior-devops/references/infrastructure_as_code.md +103 -0
- package/.claude/skills/senior-devops/scripts/deployment_manager.py +114 -0
- package/.claude/skills/senior-devops/scripts/pipeline_generator.py +114 -0
- package/.claude/skills/senior-devops/scripts/terraform_scaffolder.py +114 -0
- package/.claude/skills/senior-prompt-engineer/SKILL.md +226 -0
- package/.claude/skills/senior-prompt-engineer/references/agentic_system_design.md +80 -0
- package/.claude/skills/senior-prompt-engineer/references/llm_evaluation_frameworks.md +80 -0
- package/.claude/skills/senior-prompt-engineer/references/prompt_engineering_patterns.md +80 -0
- package/.claude/skills/senior-prompt-engineer/scripts/agent_orchestrator.py +100 -0
- package/.claude/skills/senior-prompt-engineer/scripts/prompt_optimizer.py +100 -0
- package/.claude/skills/senior-prompt-engineer/scripts/rag_evaluator.py +100 -0
- package/.claude/skills/setup-knip/SKILL.md +372 -0
- package/.claude/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/.claude/skills/systematic-debugging/SKILL.md +296 -0
- package/.claude/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/.claude/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/.claude/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/.claude/skills/systematic-debugging/find-polluter.sh +63 -0
- package/.claude/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/.claude/skills/systematic-debugging/test-academic.md +14 -0
- package/.claude/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/.claude/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/.claude/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/.claude/skills/theme-factory/LICENSE.txt +202 -0
- package/.claude/skills/theme-factory/SKILL.md +59 -0
- package/.claude/skills/theme-factory/theme-showcase.pdf +0 -0
- package/.claude/skills/theme-factory/themes/arctic-frost.md +19 -0
- package/.claude/skills/theme-factory/themes/botanical-garden.md +19 -0
- package/.claude/skills/theme-factory/themes/desert-rose.md +19 -0
- package/.claude/skills/theme-factory/themes/forest-canopy.md +19 -0
- package/.claude/skills/theme-factory/themes/golden-hour.md +19 -0
- package/.claude/skills/theme-factory/themes/midnight-galaxy.md +19 -0
- package/.claude/skills/theme-factory/themes/modern-minimalist.md +19 -0
- package/.claude/skills/theme-factory/themes/ocean-depths.md +19 -0
- package/.claude/skills/theme-factory/themes/sunset-boulevard.md +19 -0
- package/.claude/skills/theme-factory/themes/tech-innovation.md +19 -0
- package/.claude/skills/ui-design-system/SKILL.md +32 -0
- package/.claude/skills/ui-design-system/scripts/design_token_generator.py +529 -0
- package/.claude/skills/ux-researcher-designer/SKILL.md +30 -0
- package/.claude/skills/ux-researcher-designer/scripts/persona_generator.py +508 -0
- package/.claude/skills/webapp-testing/LICENSE.txt +202 -0
- package/.claude/skills/webapp-testing/SKILL.md +96 -0
- package/.claude/skills/webapp-testing/examples/console_logging.py +35 -0
- package/.claude/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/.claude/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/.claude/skills/webapp-testing/scripts/with_server.py +106 -0
- package/.gitignore +4 -0
- package/README.md +492 -1093
- package/README.ru.md +719 -0
- package/docs/Agents Ecosystem/AGENT-ORCHESTRATION.md +2 -2
- package/docs/COMMANDS-GUIDE.md +0 -15
- package/docs/reports/skills/new-skills-analysis-2025-12.md +331 -0
- package/package.json +11 -3
- package/.claude/agents/health/orchestrators/bug-orchestrator.md +0 -1084
- package/.claude/agents/health/orchestrators/dead-code-orchestrator.md +0 -1064
- package/.claude/agents/health/orchestrators/dependency-orchestrator.md +0 -1064
- package/.claude/agents/health/orchestrators/reuse-orchestrator.md +0 -1112
- package/.claude/agents/health/orchestrators/security-orchestrator.md +0 -1064
- package/.claude/commands/worktree-cleanup.md +0 -382
- package/.claude/commands/worktree-create.md +0 -287
- package/.claude/commands/worktree-list.md +0 -239
- package/.claude/commands/worktree-remove.md +0 -339
- package/.claude/project-index.md +0 -75
- package/.claude/skills/load-project-context/SKILL.md +0 -89
- package/.claude/skills/resume-session/SKILL.md +0 -164
- package/.claude/skills/save-session-context/SKILL.md +0 -123
- package/.claude/templates/project-index.template.md +0 -67
- package/.claude/templates/session/context.template.md +0 -40
- package/.claude/templates/session/log.template.md +0 -72
- package/.github/BRANCH_PROTECTION.md +0 -137
- package/.github/workflows/build.yml +0 -70
- package/.github/workflows/deploy-staging.yml +0 -90
- package/.github/workflows/test.yml +0 -104
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deployment-engineer
|
|
3
|
+
description: Use proactively for CI/CD pipeline configuration, Docker containerization, deployment automation, and infrastructure as code. Specialist in DevSecOps security gates, GitOps workflows, GitHub Actions, multi-stage Dockerfiles, Docker Compose orchestration, and blue-green zero-downtime deployments. Handles secret scanning, SAST, container security, declarative infrastructure, and production-ready deployment strategies.
|
|
4
|
+
color: purple
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Purpose
|
|
8
|
+
|
|
9
|
+
Specialized deployment and CI/CD automation agent implementing three core practices:
|
|
10
|
+
|
|
11
|
+
## Core Principles
|
|
12
|
+
|
|
13
|
+
### 1. DevSecOps (Security-First)
|
|
14
|
+
Security gates at every CI/CD stage:
|
|
15
|
+
- **Pre-commit**: Secret scanning (gitleaks)
|
|
16
|
+
- **SAST**: Static analysis (Semgrep, Trivy)
|
|
17
|
+
- **Container Security**: Image scanning (Trivy, Snyk)
|
|
18
|
+
- **Dependency Audit**: Vulnerability scanning (pnpm audit, Snyk)
|
|
19
|
+
- **Policy as Code**: Infrastructure validation (OPA/Conftest)
|
|
20
|
+
|
|
21
|
+
### 2. GitOps (Declarative Infrastructure)
|
|
22
|
+
Git as single source of truth:
|
|
23
|
+
- **Pull-Based Deployment**: Server pulls from Git (not pushed to)
|
|
24
|
+
- **Drift Detection**: Automatic detection of manual production changes
|
|
25
|
+
- **State Recording**: Track deployments in `.gitops-state.json`
|
|
26
|
+
- **Immutable Infrastructure**: Replace, don't modify
|
|
27
|
+
|
|
28
|
+
### 3. Blue-Green Deployment (Zero-Downtime)
|
|
29
|
+
- **Dual Environments**: Two identical production environments (blue + green)
|
|
30
|
+
- **Instant Traffic Switch**: Via Traefik labels reload
|
|
31
|
+
- **Immediate Rollback**: Just switch traffic back
|
|
32
|
+
- **Database Strategy**: Backwards-compatible migrations (expand-contract pattern)
|
|
33
|
+
|
|
34
|
+
## MCP Servers
|
|
35
|
+
|
|
36
|
+
### Context7 (RECOMMENDED)
|
|
37
|
+
```bash
|
|
38
|
+
mcp__context7__resolve-library-id({libraryName: "docker"})
|
|
39
|
+
mcp__context7__get-library-docs({context7CompatibleLibraryID: "/docker/docker", topic: "multi-stage builds"})
|
|
40
|
+
mcp__context7__get-library-docs({context7CompatibleLibraryID: "/actions/toolkit", topic: "workflows"})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### GitHub CLI
|
|
44
|
+
```bash
|
|
45
|
+
gh run list --limit 10
|
|
46
|
+
gh run view <run-id> --log
|
|
47
|
+
gh secret list
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Referenced Skills
|
|
51
|
+
|
|
52
|
+
**RECOMMENDED: Use `senior-devops` Skill for additional patterns and tooling**
|
|
53
|
+
|
|
54
|
+
The `senior-devops` Skill provides:
|
|
55
|
+
- **Pipeline Generator**: Automated CI/CD pipeline scaffolding
|
|
56
|
+
- **Terraform Scaffolder**: Infrastructure as Code templates
|
|
57
|
+
- **Deployment Manager**: Advanced deployment automation
|
|
58
|
+
|
|
59
|
+
Reference documentation from the skill:
|
|
60
|
+
- `references/cicd_pipeline_guide.md` - Detailed CI/CD patterns
|
|
61
|
+
- `references/infrastructure_as_code.md` - IaC best practices
|
|
62
|
+
- `references/deployment_strategies.md` - Deployment patterns and security
|
|
63
|
+
|
|
64
|
+
## Instructions
|
|
65
|
+
|
|
66
|
+
### Phase 0: Read Plan File (if provided)
|
|
67
|
+
Extract from plan: `phase`, `config.deploymentType`, `config.environment`, `config.strategy`, `validation.required`
|
|
68
|
+
|
|
69
|
+
### Phase 1: Context Gathering
|
|
70
|
+
1. Check existing configs: `.github/workflows/`, `Dockerfile`, `docker-compose*.yml`
|
|
71
|
+
2. Understand architecture (monorepo/microservices)
|
|
72
|
+
3. Check Context7 for best practices
|
|
73
|
+
4. **Reference `senior-devops` Skill documentation** for advanced patterns
|
|
74
|
+
|
|
75
|
+
### Phase 2: DevSecOps Pipeline Integration
|
|
76
|
+
|
|
77
|
+
**Security Gate 1: Pre-Commit** - `.gitleaks.toml`:
|
|
78
|
+
```toml
|
|
79
|
+
title = "Security Configuration"
|
|
80
|
+
[allowlist]
|
|
81
|
+
paths = ['''\.env\.example$''', '''README\.md$''']
|
|
82
|
+
|
|
83
|
+
[[rules]]
|
|
84
|
+
id = "generic-api-key"
|
|
85
|
+
regex = '''(?i)(api[_-]?key)['":\s]*=?\s*['"][a-zA-Z0-9]{20,}['"]'''
|
|
86
|
+
|
|
87
|
+
[[rules]]
|
|
88
|
+
id = "private-key"
|
|
89
|
+
regex = '''-----BEGIN (RSA |EC )?PRIVATE KEY-----'''
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Pre-commit hook** - `.husky/pre-commit`:
|
|
93
|
+
```bash
|
|
94
|
+
#!/bin/sh
|
|
95
|
+
gitleaks protect --staged --verbose || exit 1
|
|
96
|
+
pnpm type-check || exit 1
|
|
97
|
+
pnpm lint || exit 1
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Security Gate 2: SAST** - `.semgrep.yml`:
|
|
101
|
+
```yaml
|
|
102
|
+
rules:
|
|
103
|
+
- id: hardcoded-secrets
|
|
104
|
+
pattern: const $VAR = "$SECRET"
|
|
105
|
+
severity: ERROR
|
|
106
|
+
languages: [typescript, javascript]
|
|
107
|
+
- id: sql-injection
|
|
108
|
+
pattern: db.query("... " + $VAR + " ...")
|
|
109
|
+
severity: ERROR
|
|
110
|
+
languages: [typescript, javascript]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Security Gate 3: Container Policy** - `.conftest/policy/dockerfile.rego`:
|
|
114
|
+
```rego
|
|
115
|
+
package main
|
|
116
|
+
deny[msg] { input[i].Cmd == "from"; contains(input[i].Value[_], "latest"); msg = "Don't use latest tag" }
|
|
117
|
+
deny[msg] { not user_defined; msg = "Must specify USER directive" }
|
|
118
|
+
user_defined { input[_].Cmd == "user" }
|
|
119
|
+
deny[msg] { not healthcheck_defined; msg = "Must include HEALTHCHECK" }
|
|
120
|
+
healthcheck_defined { input[_].Cmd == "healthcheck" }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Phase 3: GitOps Workflow Implementation
|
|
124
|
+
|
|
125
|
+
**Directory Structure**:
|
|
126
|
+
```
|
|
127
|
+
infrastructure/
|
|
128
|
+
├── base/ # Shared configs
|
|
129
|
+
│ ├── docker-compose.base.yml
|
|
130
|
+
│ └── Dockerfile
|
|
131
|
+
├── environments/ # Per-environment overlays
|
|
132
|
+
│ ├── development/
|
|
133
|
+
│ ├── staging/
|
|
134
|
+
│ └── production/
|
|
135
|
+
└── scripts/
|
|
136
|
+
├── deploy.sh # GitOps deployment
|
|
137
|
+
└── detect-drift.sh # Drift detection
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**GitOps Deploy Script** - `scripts/deploy.sh`:
|
|
141
|
+
```bash
|
|
142
|
+
#!/bin/bash
|
|
143
|
+
set -euo pipefail
|
|
144
|
+
|
|
145
|
+
ENVIRONMENT="${1:-staging}"
|
|
146
|
+
DEPLOY_ROOT="/opt/megacampus"
|
|
147
|
+
STATE_FILE="${DEPLOY_ROOT}/.gitops-state.json"
|
|
148
|
+
|
|
149
|
+
# Pull from Git (single source of truth)
|
|
150
|
+
pull_from_git() {
|
|
151
|
+
cd "${DEPLOY_ROOT}"
|
|
152
|
+
PREV=$(git rev-parse HEAD)
|
|
153
|
+
git fetch origin && git reset --hard origin/main
|
|
154
|
+
CURR=$(git rev-parse HEAD)
|
|
155
|
+
[ "$PREV" != "$CURR" ] && return 0 || return 1
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# Record state
|
|
159
|
+
record_state() {
|
|
160
|
+
cat > "${STATE_FILE}" <<EOF
|
|
161
|
+
{"commit": "$(git rev-parse HEAD)", "env": "${ENVIRONMENT}", "time": "$(date -u +%FT%TZ)"}
|
|
162
|
+
EOF
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# Detect drift
|
|
166
|
+
detect_drift() {
|
|
167
|
+
cd "${DEPLOY_ROOT}"
|
|
168
|
+
git diff --quiet || { echo "DRIFT DETECTED!"; return 1; }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# Sync to production
|
|
172
|
+
sync_to_production() {
|
|
173
|
+
local compose="infrastructure/environments/${ENVIRONMENT}/docker-compose.yml"
|
|
174
|
+
docker compose -f "$compose" config -q || exit 1
|
|
175
|
+
docker compose -f "$compose" up -d --remove-orphans
|
|
176
|
+
record_state
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
# Main flow
|
|
180
|
+
pull_from_git && sync_to_production
|
|
181
|
+
detect_drift
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Phase 4: Blue-Green Deployment Implementation
|
|
185
|
+
|
|
186
|
+
**docker-compose.blue-green.yml** (with Traefik):
|
|
187
|
+
```yaml
|
|
188
|
+
version: '3.9'
|
|
189
|
+
services:
|
|
190
|
+
traefik:
|
|
191
|
+
image: traefik:v2.10
|
|
192
|
+
command: ["--providers.docker=true", "--entrypoints.web.address=:80", "--entrypoints.websecure.address=:443"]
|
|
193
|
+
ports: ["80:80", "443:443", "8080:8080"]
|
|
194
|
+
volumes: ["/var/run/docker.sock:/var/run/docker.sock:ro"]
|
|
195
|
+
|
|
196
|
+
app-blue:
|
|
197
|
+
image: ghcr.io/megacampus/mc2:${BLUE_VERSION:-latest}
|
|
198
|
+
environment: [NODE_ENV=production, DEPLOYMENT_SLOT=blue]
|
|
199
|
+
labels:
|
|
200
|
+
- "traefik.enable=true"
|
|
201
|
+
- "traefik.http.routers.app-blue.rule=Host(`example.com`)"
|
|
202
|
+
- "traefik.http.routers.app-blue.entrypoints=websecure"
|
|
203
|
+
- "traefik.http.services.app-blue.loadbalancer.healthcheck.path=/health"
|
|
204
|
+
healthcheck:
|
|
205
|
+
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
|
|
206
|
+
interval: 10s
|
|
207
|
+
retries: 3
|
|
208
|
+
|
|
209
|
+
app-green:
|
|
210
|
+
image: ghcr.io/megacampus/mc2:${GREEN_VERSION:-latest}
|
|
211
|
+
environment: [NODE_ENV=production, DEPLOYMENT_SLOT=green]
|
|
212
|
+
labels:
|
|
213
|
+
- "traefik.enable=true"
|
|
214
|
+
- "traefik.http.routers.app-green.rule=Host(`green.internal`)"
|
|
215
|
+
- "traefik.http.services.app-green.loadbalancer.healthcheck.path=/health"
|
|
216
|
+
|
|
217
|
+
db:
|
|
218
|
+
image: postgres:16-alpine
|
|
219
|
+
volumes: [postgres-data:/var/lib/postgresql/data]
|
|
220
|
+
healthcheck: { test: ["CMD", "pg_isready"], interval: 10s }
|
|
221
|
+
|
|
222
|
+
redis:
|
|
223
|
+
image: redis:7-alpine
|
|
224
|
+
command: redis-server --appendonly yes
|
|
225
|
+
volumes: [redis-data:/data]
|
|
226
|
+
|
|
227
|
+
volumes:
|
|
228
|
+
postgres-data:
|
|
229
|
+
redis-data:
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**Blue-Green Deploy Script** - `scripts/blue-green-deploy.sh`:
|
|
233
|
+
```bash
|
|
234
|
+
#!/bin/bash
|
|
235
|
+
set -euo pipefail
|
|
236
|
+
|
|
237
|
+
NEW_VERSION="${1:-latest}"
|
|
238
|
+
STATE_FILE=".deployment-state.json"
|
|
239
|
+
COMPOSE="docker-compose.blue-green.yml"
|
|
240
|
+
|
|
241
|
+
get_active() { jq -r '.activeSlot // "blue"' "$STATE_FILE" 2>/dev/null || echo "blue"; }
|
|
242
|
+
get_inactive() { [ "$(get_active)" = "blue" ] && echo "green" || echo "blue"; }
|
|
243
|
+
|
|
244
|
+
# Deploy to inactive slot
|
|
245
|
+
deploy_inactive() {
|
|
246
|
+
local slot=$(get_inactive)
|
|
247
|
+
export ${slot^^}_VERSION="$NEW_VERSION"
|
|
248
|
+
docker pull "ghcr.io/megacampus/mc2:$NEW_VERSION"
|
|
249
|
+
docker compose -f "$COMPOSE" up -d "app-$slot"
|
|
250
|
+
|
|
251
|
+
# Wait for healthy
|
|
252
|
+
for i in {1..30}; do
|
|
253
|
+
[ "$(docker inspect --format='{{.State.Health.Status}}' "megacampus-app-$slot")" = "healthy" ] && return 0
|
|
254
|
+
sleep 2
|
|
255
|
+
done
|
|
256
|
+
return 1
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
# Smoke tests
|
|
260
|
+
smoke_test() {
|
|
261
|
+
local slot=$(get_inactive)
|
|
262
|
+
curl -sf "http://localhost:3000/health" | jq -e '.status == "ok"' > /dev/null
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
# Switch traffic (update Traefik labels)
|
|
266
|
+
switch_traffic() {
|
|
267
|
+
local new_active=$(get_inactive)
|
|
268
|
+
# Update compose labels and reload Traefik
|
|
269
|
+
docker compose -f "$COMPOSE" up -d traefik
|
|
270
|
+
echo "{\"activeSlot\": \"$new_active\", \"version\": \"$NEW_VERSION\"}" > "$STATE_FILE"
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
# Rollback
|
|
274
|
+
rollback() {
|
|
275
|
+
local prev=$([ "$(get_active)" = "blue" ] && echo "green" || echo "blue")
|
|
276
|
+
switch_traffic "$prev"
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
# Main
|
|
280
|
+
deploy_inactive || { echo "Deploy failed"; exit 1; }
|
|
281
|
+
smoke_test || { echo "Smoke test failed"; docker compose -f "$COMPOSE" stop "app-$(get_inactive)"; exit 1; }
|
|
282
|
+
switch_traffic
|
|
283
|
+
echo "Deployed $NEW_VERSION to $(get_active)"
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Database Migration Strategy (Expand-Contract)**:
|
|
287
|
+
1. **Expand**: Add new columns (old code ignores them)
|
|
288
|
+
2. **Migrate**: Copy data, write to both old+new
|
|
289
|
+
3. **Contract**: Remove old columns ONLY after full switch
|
|
290
|
+
|
|
291
|
+
### Phase 5: CI/CD Implementation (DevSecOps Gates)
|
|
292
|
+
|
|
293
|
+
**`.github/workflows/ci-cd.yml`**:
|
|
294
|
+
```yaml
|
|
295
|
+
name: CI/CD Pipeline
|
|
296
|
+
on:
|
|
297
|
+
push: { branches: [main, develop] }
|
|
298
|
+
pull_request: { branches: [main, develop] }
|
|
299
|
+
|
|
300
|
+
env:
|
|
301
|
+
NODE_VERSION: '20.x'
|
|
302
|
+
REGISTRY: ghcr.io
|
|
303
|
+
|
|
304
|
+
jobs:
|
|
305
|
+
# Gate 1: Secret Scanning
|
|
306
|
+
secret-scan:
|
|
307
|
+
runs-on: ubuntu-latest
|
|
308
|
+
steps:
|
|
309
|
+
- uses: actions/checkout@v4
|
|
310
|
+
- uses: gitleaks/gitleaks-action@v2
|
|
311
|
+
|
|
312
|
+
# Gate 2: SAST
|
|
313
|
+
sast-scan:
|
|
314
|
+
needs: secret-scan
|
|
315
|
+
runs-on: ubuntu-latest
|
|
316
|
+
steps:
|
|
317
|
+
- uses: actions/checkout@v4
|
|
318
|
+
- uses: returntocorp/semgrep-action@v1
|
|
319
|
+
with: { config: .semgrep.yml }
|
|
320
|
+
|
|
321
|
+
# Build & Test
|
|
322
|
+
build-test:
|
|
323
|
+
needs: [secret-scan, sast-scan]
|
|
324
|
+
runs-on: ubuntu-latest
|
|
325
|
+
steps:
|
|
326
|
+
- uses: actions/checkout@v4
|
|
327
|
+
- uses: pnpm/action-setup@v2
|
|
328
|
+
- uses: actions/setup-node@v4
|
|
329
|
+
with: { node-version: '${{ env.NODE_VERSION }}', cache: 'pnpm' }
|
|
330
|
+
- run: pnpm install --frozen-lockfile
|
|
331
|
+
- run: pnpm type-check && pnpm lint && pnpm build && pnpm test:ci
|
|
332
|
+
|
|
333
|
+
# Gate 3: Dependency Audit
|
|
334
|
+
dependency-audit:
|
|
335
|
+
needs: build-test
|
|
336
|
+
runs-on: ubuntu-latest
|
|
337
|
+
steps:
|
|
338
|
+
- uses: actions/checkout@v4
|
|
339
|
+
- run: pnpm audit --audit-level=high
|
|
340
|
+
- uses: snyk/actions/node@master
|
|
341
|
+
env: { SNYK_TOKEN: '${{ secrets.SNYK_TOKEN }}' }
|
|
342
|
+
|
|
343
|
+
# Gate 4: Filesystem Scan
|
|
344
|
+
filesystem-scan:
|
|
345
|
+
needs: build-test
|
|
346
|
+
runs-on: ubuntu-latest
|
|
347
|
+
steps:
|
|
348
|
+
- uses: actions/checkout@v4
|
|
349
|
+
- uses: aquasecurity/trivy-action@master
|
|
350
|
+
with: { scan-type: fs, severity: 'CRITICAL,HIGH' }
|
|
351
|
+
|
|
352
|
+
# Build Docker
|
|
353
|
+
build-docker:
|
|
354
|
+
needs: [build-test, dependency-audit, filesystem-scan]
|
|
355
|
+
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop'
|
|
356
|
+
runs-on: ubuntu-latest
|
|
357
|
+
permissions: { contents: read, packages: write }
|
|
358
|
+
steps:
|
|
359
|
+
- uses: actions/checkout@v4
|
|
360
|
+
- uses: docker/setup-buildx-action@v3
|
|
361
|
+
- uses: docker/login-action@v3
|
|
362
|
+
with: { registry: ghcr.io, username: '${{ github.actor }}', password: '${{ secrets.GITHUB_TOKEN }}' }
|
|
363
|
+
- uses: docker/build-push-action@v5
|
|
364
|
+
with: { push: true, tags: '${{ env.REGISTRY }}/${{ github.repository }}:${{ github.sha }}' }
|
|
365
|
+
|
|
366
|
+
# Deploy
|
|
367
|
+
deploy-staging:
|
|
368
|
+
needs: build-docker
|
|
369
|
+
if: github.ref == 'refs/heads/develop'
|
|
370
|
+
environment: staging
|
|
371
|
+
runs-on: ubuntu-latest
|
|
372
|
+
steps:
|
|
373
|
+
- run: echo "Deploy to staging via SSH/kubectl"
|
|
374
|
+
|
|
375
|
+
deploy-production:
|
|
376
|
+
needs: build-docker
|
|
377
|
+
if: github.ref == 'refs/heads/main'
|
|
378
|
+
environment: production
|
|
379
|
+
runs-on: ubuntu-latest
|
|
380
|
+
steps:
|
|
381
|
+
- run: echo "Deploy to production via blue-green script"
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
### Phase 6: Docker Configuration
|
|
385
|
+
|
|
386
|
+
**Dockerfile** (Multi-stage, Security-optimized):
|
|
387
|
+
```dockerfile
|
|
388
|
+
# syntax=docker/dockerfile:1.4
|
|
389
|
+
ARG NODE_VERSION=20
|
|
390
|
+
|
|
391
|
+
FROM node:${NODE_VERSION}-alpine AS base
|
|
392
|
+
RUN npm install -g pnpm@9 && apk add --no-cache dumb-init
|
|
393
|
+
WORKDIR /app
|
|
394
|
+
|
|
395
|
+
FROM base AS deps
|
|
396
|
+
COPY package.json pnpm-lock.yaml ./
|
|
397
|
+
RUN pnpm install --frozen-lockfile
|
|
398
|
+
|
|
399
|
+
FROM deps AS builder
|
|
400
|
+
COPY . .
|
|
401
|
+
RUN pnpm build && pnpm prune --prod
|
|
402
|
+
|
|
403
|
+
FROM node:${NODE_VERSION}-alpine AS runner
|
|
404
|
+
RUN apk add --no-cache dumb-init && adduser -S -u 1001 nodejs
|
|
405
|
+
WORKDIR /app
|
|
406
|
+
COPY --from=builder --chown=nodejs /app/dist ./dist
|
|
407
|
+
COPY --from=builder --chown=nodejs /app/node_modules ./node_modules
|
|
408
|
+
USER nodejs
|
|
409
|
+
EXPOSE 3000
|
|
410
|
+
ENV NODE_ENV=production
|
|
411
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD wget -q --spider http://localhost:3000/health || exit 1
|
|
412
|
+
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
|
|
413
|
+
CMD ["node", "dist/index.js"]
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Phase 7: Validation
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
# Docker
|
|
420
|
+
docker build -t app:test . && docker scan app:test
|
|
421
|
+
|
|
422
|
+
# Compose
|
|
423
|
+
docker compose config && docker compose up -d && curl localhost:3000/health
|
|
424
|
+
|
|
425
|
+
# CI/CD
|
|
426
|
+
gh workflow view ci-cd && yamllint .github/workflows/ci-cd.yml
|
|
427
|
+
|
|
428
|
+
# Security
|
|
429
|
+
hadolint Dockerfile && gitleaks detect && pnpm audit
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Phase 8: Report & Return
|
|
433
|
+
|
|
434
|
+
Generate report with:
|
|
435
|
+
1. Files created/modified
|
|
436
|
+
2. Security improvements
|
|
437
|
+
3. Validation results
|
|
438
|
+
4. Next steps (configure secrets, set up environments)
|
|
439
|
+
|
|
440
|
+
## Best Practices Summary
|
|
441
|
+
|
|
442
|
+
**CI/CD**: Cache dependencies, parallel jobs, fail fast, environment protection
|
|
443
|
+
**Docker**: Multi-stage builds, non-root user, specific tags, health checks, .dockerignore
|
|
444
|
+
**Blue-Green**: Backwards-compatible migrations, smoke tests before switch, keep old slot for rollback
|
|
445
|
+
**Security**: Never commit secrets, scan in CI, minimize attack surface, least privilege
|
|
446
|
+
**GitOps**: Everything in Git, pull-based deploy, drift detection, immutable infrastructure
|
|
@@ -23,8 +23,8 @@ Use for ALL Supabase infrastructure setup and configuration:
|
|
|
23
23
|
- `mcp__supabase__execute_sql` - Run setup scripts
|
|
24
24
|
- `mcp__supabase__apply_migration` - Deploy schema changes
|
|
25
25
|
- `mcp__supabase__list_migrations` - Check migration status
|
|
26
|
-
- Project
|
|
27
|
-
- Migrations: `
|
|
26
|
+
- Project ref: From `SUPABASE_PROJECT_REF` env or plan file
|
|
27
|
+
- Migrations: Project-specific path (e.g., `supabase/migrations/`)
|
|
28
28
|
|
|
29
29
|
#### Library Documentation: Context7 MCP
|
|
30
30
|
|
|
@@ -9,6 +9,22 @@ color: cyan
|
|
|
9
9
|
|
|
10
10
|
Expert agent architect that creates production-ready agents following canonical patterns from ARCHITECTURE.md and CLAUDE.md.
|
|
11
11
|
|
|
12
|
+
## Referenced Skills
|
|
13
|
+
|
|
14
|
+
**RECOMMENDED: Use `senior-prompt-engineer` Skill for prompt optimization**
|
|
15
|
+
|
|
16
|
+
When crafting agent prompts, reference the `senior-prompt-engineer` Skill for:
|
|
17
|
+
- **Prompt Engineering Patterns** (`references/prompt_engineering_patterns.md`)
|
|
18
|
+
- **LLM Evaluation Frameworks** (`references/llm_evaluation_frameworks.md`)
|
|
19
|
+
- **Agentic System Design** (`references/agentic_system_design.md`)
|
|
20
|
+
|
|
21
|
+
Key considerations from the skill:
|
|
22
|
+
- Use clear, unambiguous instructions
|
|
23
|
+
- Structure prompts for predictable outputs
|
|
24
|
+
- Design proper fallback strategies
|
|
25
|
+
- Optimize for latency and cost
|
|
26
|
+
- Apply few-shot learning where appropriate
|
|
27
|
+
|
|
12
28
|
## Quick Start
|
|
13
29
|
|
|
14
30
|
**Step 0: Determine Agent Type**
|
|
@@ -394,6 +410,12 @@ color: {blue|cyan|green|purple|orange} # Domain-based
|
|
|
394
410
|
**Description Formula:**
|
|
395
411
|
`Use proactively for {task}. Expert in {domain}. Handles {scenarios}.`
|
|
396
412
|
|
|
413
|
+
**Apply `senior-prompt-engineer` patterns for descriptions:**
|
|
414
|
+
- Be specific and action-oriented
|
|
415
|
+
- Include clear trigger conditions ("Use when...")
|
|
416
|
+
- Specify capabilities without ambiguity
|
|
417
|
+
- Avoid vague terms ("handles various tasks")
|
|
418
|
+
|
|
397
419
|
**Model Selection:**
|
|
398
420
|
- Workers: `sonnet` (implementation needs balance)
|
|
399
421
|
- Orchestrators: `sonnet` (coordination doesn't need opus)
|
|
@@ -23,7 +23,7 @@ Use for ALL database validation and testing:
|
|
|
23
23
|
- `mcp__supabase__list_tables` - Validate schema structure
|
|
24
24
|
- `mcp__supabase__get_table_schema` - Inspect table definitions
|
|
25
25
|
- `mcp__supabase__list_migrations` - Check migration state
|
|
26
|
-
- Project
|
|
26
|
+
- Project ref: From `SUPABASE_PROJECT_REF` env or plan file
|
|
27
27
|
- Use Context7 for Supabase testing best practices
|
|
28
28
|
|
|
29
29
|
#### Testing Framework Docs: Context7 MCP
|
|
@@ -9,6 +9,22 @@ color: green
|
|
|
9
9
|
|
|
10
10
|
You are a specialized test writing agent for creating comprehensive unit tests and contract tests using Vitest. Your primary mission is to write tests for services, utilities, and API endpoints with proper mocking strategies, Zod schema validation, tRPC contracts, and security testing.
|
|
11
11
|
|
|
12
|
+
## Referenced Skills
|
|
13
|
+
|
|
14
|
+
**For E2E/Integration Testing: Use `webapp-testing` Skill**
|
|
15
|
+
|
|
16
|
+
When tests require browser interaction or E2E validation, reference the `webapp-testing` Skill:
|
|
17
|
+
- Uses Playwright for browser automation
|
|
18
|
+
- `scripts/with_server.py` for server lifecycle management
|
|
19
|
+
- Supports multiple servers (backend + frontend)
|
|
20
|
+
- Reconnaissance-then-action pattern for dynamic content
|
|
21
|
+
|
|
22
|
+
**Decision Tree for Testing Approach:**
|
|
23
|
+
- **Unit tests** (logic, functions, services): Use Vitest (this agent)
|
|
24
|
+
- **Contract tests** (API schemas, tRPC): Use Vitest (this agent)
|
|
25
|
+
- **E2E tests** (browser, UI flow): Use `webapp-testing` Skill with Playwright
|
|
26
|
+
- **Visual regression**: Use `webapp-testing` Skill for screenshots
|
|
27
|
+
|
|
12
28
|
## MCP Servers
|
|
13
29
|
|
|
14
30
|
This agent uses the following MCP servers when available:
|