contextos-agents 2.0.0 → 2.1.1
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/.agents/AGENTS.md +53 -33
- package/.agents/adapters/aider/export.js +41 -14
- package/.agents/adapters/claude/export.js +54 -3
- package/.agents/adapters/copilot/export.js +1 -1
- package/.agents/adapters/cursor/export.js +1 -1
- package/.agents/adapters/drift-detector.js +86 -10
- package/.agents/adapters/gemini/export.js +1 -1
- package/.agents/adapters/pure-compiler.js +28 -6
- package/.agents/adapters/shared.js +13 -4
- package/.agents/adapters/zed/export.js +1 -1
- package/.agents/compiled/registry.v2.json +29 -25
- package/.agents/compiled/registry.v2.sha256 +1 -1
- package/.agents/core/skills/context-os/SKILL.md +34 -37
- package/.agents/core/skills/engineering-workflow/SKILL.md +24 -24
- package/.agents/core/skills/gemini-precision/EXAMPLES.md +72 -0
- package/.agents/core/skills/gemini-precision/SKILL.md +2 -1
- package/.agents/core/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
- package/.agents/core/skills/gemini-precision/skill.yaml +2 -0
- package/.agents/core/skills/gstack-roles/SKILL.md +7 -6
- package/.agents/core/skills/security/SKILL.md +44 -16
- package/.agents/core/skills/security/skill.yaml +0 -1
- package/.agents/ctx.js +20 -14
- package/.agents/generated/claude/skills/context-os/SKILL.md +34 -37
- package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +24 -24
- package/.agents/generated/claude/skills/gemini-precision/SKILL.md +102 -1
- package/.agents/generated/claude/skills/gstack-roles/SKILL.md +7 -6
- package/.agents/generated/claude/skills/security/SKILL.md +44 -16
- package/.agents/generated/gemini/skills/context-os/SKILL.md +34 -37
- package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +24 -24
- package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +105 -1
- package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +7 -6
- package/.agents/generated/gemini/skills/security/SKILL.md +44 -125
- package/.agents/plugins.js +105 -8
- package/.agents/profiles.js +32 -11
- package/.agents/resolver/canonical-resolver.js +7 -7
- package/.agents/validate.js +69 -1
- package/README.md +81 -24
- package/bin/commands/hook.js +167 -0
- package/bin/commands/scan.js +77 -0
- package/bin/commands.js +39 -1
- package/bin/index.js +151 -34
- package/bin/lib/gate.js +171 -0
- package/bin/lib/git-snapshot.js +214 -0
- package/bin/lib/scan.js +461 -0
- package/catalog/skills/adapters/EXAMPLES.md +19 -0
- package/catalog/skills/adapters/SKILL.md +101 -0
- package/catalog/skills/adapters/TROUBLESHOOTING.md +7 -0
- package/catalog/skills/adapters/VALIDATION.json +12 -0
- package/catalog/skills/adapters/skill.yaml +13 -0
- package/catalog/skills/api-design/EXAMPLES.md +91 -0
- package/catalog/skills/api-design/SKILL.md +63 -0
- package/catalog/skills/api-design/TROUBLESHOOTING.md +54 -0
- package/catalog/skills/api-design/VALIDATION.json +11 -0
- package/catalog/skills/api-design/skill.yaml +14 -0
- package/catalog/skills/architecture-diagrams/SKILL.md +108 -0
- package/catalog/skills/architecture-diagrams/VALIDATION.json +12 -0
- package/catalog/skills/architecture-diagrams/skill.yaml +9 -0
- package/catalog/skills/brutalist-design/EXAMPLES.md +59 -0
- package/catalog/skills/brutalist-design/SKILL.md +150 -0
- package/catalog/skills/brutalist-design/VALIDATION.json +12 -0
- package/catalog/skills/brutalist-design/skill.yaml +10 -0
- package/catalog/skills/ci-cd/EXAMPLES.md +79 -0
- package/catalog/skills/ci-cd/SKILL.md +69 -0
- package/catalog/skills/ci-cd/TROUBLESHOOTING.md +52 -0
- package/catalog/skills/ci-cd/VALIDATION.json +11 -0
- package/catalog/skills/ci-cd/skill.yaml +13 -0
- package/catalog/skills/database/EXAMPLES.md +74 -0
- package/catalog/skills/database/SKILL.md +101 -0
- package/catalog/skills/database/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/database/VALIDATION.json +11 -0
- package/catalog/skills/database/skill.yaml +14 -0
- package/catalog/skills/ddd/EXAMPLES.md +42 -0
- package/catalog/skills/ddd/SKILL.md +247 -0
- package/catalog/skills/ddd/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ddd/VALIDATION.json +12 -0
- package/catalog/skills/ddd/skill.yaml +14 -0
- package/catalog/skills/decisions/EXAMPLES.md +35 -0
- package/catalog/skills/decisions/SKILL.md +90 -0
- package/catalog/skills/decisions/TROUBLESHOOTING.md +13 -0
- package/catalog/skills/decisions/VALIDATION.json +12 -0
- package/catalog/skills/decisions/skill.yaml +13 -0
- package/catalog/skills/docker/EXAMPLES.md +56 -0
- package/catalog/skills/docker/SKILL.md +169 -0
- package/catalog/skills/docker/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/docker/VALIDATION.json +11 -0
- package/catalog/skills/docker/skill.yaml +13 -0
- package/catalog/skills/fastapi/EXAMPLES.md +36 -0
- package/catalog/skills/fastapi/SKILL.md +171 -0
- package/catalog/skills/fastapi/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/fastapi/VALIDATION.json +12 -0
- package/catalog/skills/fastapi/skill.yaml +14 -0
- package/catalog/skills/generators/EXAMPLES.md +19 -0
- package/catalog/skills/generators/SKILL.md +110 -0
- package/catalog/skills/generators/TROUBLESHOOTING.md +7 -0
- package/catalog/skills/generators/VALIDATION.json +12 -0
- package/catalog/skills/generators/skill.yaml +22 -0
- package/catalog/skills/generators/templates/API.md +77 -0
- package/catalog/skills/generators/templates/ARCHITECTURE.md +70 -0
- package/catalog/skills/generators/templates/DATABASE.md +42 -0
- package/catalog/skills/generators/templates/DECISION.md +46 -0
- package/catalog/skills/generators/templates/PRD.md +67 -0
- package/catalog/skills/generators/templates/PROJECT_GRAPH.md +56 -0
- package/catalog/skills/generators/templates/ROADMAP.md +51 -0
- package/catalog/skills/generators/templates/TASKS.md +43 -0
- package/catalog/skills/generators/templates/UI.md +73 -0
- package/catalog/skills/graphify/EXAMPLES.md +73 -0
- package/catalog/skills/graphify/SKILL.md +130 -0
- package/catalog/skills/graphify/VALIDATION.json +12 -0
- package/catalog/skills/graphify/skill.yaml +13 -0
- package/catalog/skills/impeccable-design/EXAMPLES.md +26 -0
- package/catalog/skills/impeccable-design/SKILL.md +201 -0
- package/catalog/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/impeccable-design/VALIDATION.json +12 -0
- package/catalog/skills/impeccable-design/skill.yaml +15 -0
- package/catalog/skills/interview-me/SKILL.md +97 -0
- package/catalog/skills/interview-me/VALIDATION.json +12 -0
- package/catalog/skills/interview-me/skill.yaml +9 -0
- package/catalog/skills/microservices/EXAMPLES.md +38 -0
- package/catalog/skills/microservices/SKILL.md +164 -0
- package/catalog/skills/microservices/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/microservices/VALIDATION.json +12 -0
- package/catalog/skills/microservices/skill.yaml +14 -0
- package/catalog/skills/minimalist-design/EXAMPLES.md +58 -0
- package/catalog/skills/minimalist-design/SKILL.md +113 -0
- package/catalog/skills/minimalist-design/VALIDATION.json +12 -0
- package/catalog/skills/minimalist-design/skill.yaml +10 -0
- package/catalog/skills/nestjs/EXAMPLES.md +40 -0
- package/catalog/skills/nestjs/SKILL.md +139 -0
- package/catalog/skills/nestjs/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/nestjs/VALIDATION.json +12 -0
- package/catalog/skills/nestjs/skill.yaml +14 -0
- package/catalog/skills/nextjs/EXAMPLES.md +40 -0
- package/catalog/skills/nextjs/SKILL.md +163 -0
- package/catalog/skills/nextjs/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/nextjs/VALIDATION.json +12 -0
- package/catalog/skills/nextjs/skill.yaml +14 -0
- package/catalog/skills/node/EXAMPLES.md +80 -0
- package/catalog/skills/node/SKILL.md +128 -0
- package/catalog/skills/node/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/node/VALIDATION.json +12 -0
- package/catalog/skills/node/skill.yaml +14 -0
- package/catalog/skills/performance/EXAMPLES.md +30 -0
- package/catalog/skills/performance/SKILL.md +75 -0
- package/catalog/skills/performance/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/performance/VALIDATION.json +12 -0
- package/catalog/skills/performance/skill.yaml +14 -0
- package/catalog/skills/react/EXAMPLES.md +79 -0
- package/catalog/skills/react/SKILL.md +132 -0
- package/catalog/skills/react/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/react/VALIDATION.json +12 -0
- package/catalog/skills/react/skill.yaml +14 -0
- package/catalog/skills/react-best-practices/SKILL.md +158 -0
- package/catalog/skills/react-best-practices/VALIDATION.json +12 -0
- package/catalog/skills/react-best-practices/skill.yaml +13 -0
- package/catalog/skills/redesign-audit/SKILL.md +117 -0
- package/catalog/skills/redesign-audit/VALIDATION.json +12 -0
- package/catalog/skills/redesign-audit/skill.yaml +9 -0
- package/catalog/skills/security-audit/EXAMPLES.md +79 -0
- package/catalog/skills/security-audit/SKILL.md +91 -0
- package/catalog/skills/security-audit/TROUBLESHOOTING.md +46 -0
- package/catalog/skills/security-audit/VALIDATION.json +11 -0
- package/catalog/skills/security-audit/skill.yaml +14 -0
- package/catalog/skills/soft-design/EXAMPLES.md +51 -0
- package/catalog/skills/soft-design/SKILL.md +108 -0
- package/catalog/skills/soft-design/VALIDATION.json +12 -0
- package/catalog/skills/soft-design/skill.yaml +10 -0
- package/catalog/skills/state-management/EXAMPLES.md +56 -0
- package/catalog/skills/state-management/SKILL.md +168 -0
- package/catalog/skills/state-management/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/state-management/VALIDATION.json +11 -0
- package/catalog/skills/state-management/skill.yaml +14 -0
- package/catalog/skills/subagent-orchestrator/SKILL.md +117 -0
- package/catalog/skills/subagent-orchestrator/VALIDATION.json +12 -0
- package/catalog/skills/subagent-orchestrator/skill.yaml +9 -0
- package/catalog/skills/system-design/EXAMPLES.md +75 -0
- package/catalog/skills/system-design/SKILL.md +419 -0
- package/catalog/skills/system-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/system-design/VALIDATION.json +12 -0
- package/catalog/skills/system-design/skill.yaml +14 -0
- package/catalog/skills/terraform/EXAMPLES.md +74 -0
- package/catalog/skills/terraform/SKILL.md +55 -0
- package/catalog/skills/terraform/TROUBLESHOOTING.md +53 -0
- package/catalog/skills/terraform/VALIDATION.json +11 -0
- package/catalog/skills/terraform/skill.yaml +14 -0
- package/catalog/skills/testing/EXAMPLES.md +122 -0
- package/catalog/skills/testing/SKILL.md +70 -0
- package/catalog/skills/testing/TROUBLESHOOTING.md +18 -0
- package/catalog/skills/testing/VALIDATION.json +11 -0
- package/catalog/skills/testing/skill.yaml +14 -0
- package/catalog/skills/typescript/EXAMPLES.md +64 -0
- package/catalog/skills/typescript/SKILL.md +112 -0
- package/catalog/skills/typescript/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/typescript/VALIDATION.json +12 -0
- package/catalog/skills/typescript/skill.yaml +14 -0
- package/catalog/skills/ui-design/EXAMPLES.md +21 -0
- package/catalog/skills/ui-design/SKILL.md +124 -0
- package/catalog/skills/ui-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ui-design/VALIDATION.json +12 -0
- package/catalog/skills/ui-design/skill.yaml +16 -0
- package/catalog/skills/ui-ux-pro/EXAMPLES.md +62 -0
- package/catalog/skills/ui-ux-pro/SKILL.md +418 -0
- package/catalog/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ui-ux-pro/VALIDATION.json +12 -0
- package/catalog/skills/ui-ux-pro/skill.yaml +14 -0
- package/catalog/skills/ux-design/EXAMPLES.md +36 -0
- package/catalog/skills/ux-design/SKILL.md +116 -0
- package/catalog/skills/ux-design/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/ux-design/VALIDATION.json +12 -0
- package/catalog/skills/ux-design/skill.yaml +16 -0
- package/catalog/skills/vercel-optimize/SKILL.md +83 -0
- package/catalog/skills/vercel-optimize/VALIDATION.json +12 -0
- package/catalog/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
- package/catalog/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
- package/catalog/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
- package/catalog/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
- package/catalog/skills/vercel-optimize/skill.yaml +15 -0
- package/catalog/skills/web-accessibility/EXAMPLES.md +39 -0
- package/catalog/skills/web-accessibility/SKILL.md +151 -0
- package/catalog/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
- package/catalog/skills/web-accessibility/VALIDATION.json +12 -0
- package/catalog/skills/web-accessibility/skill.yaml +14 -0
- package/package.json +5 -2
- package/.agents/core/skills/security/security.md +0 -106
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Terraform - Examples & Refactoring Scenarios
|
|
2
|
+
|
|
3
|
+
## Example 1: Zero-Downtime Address Refactoring with `moved` Blocks
|
|
4
|
+
|
|
5
|
+
When moving an inline resource into a dedicated child module, never allow Terraform to destroy and recreate it:
|
|
6
|
+
|
|
7
|
+
```hcl
|
|
8
|
+
# Before refactor (in root main.tf):
|
|
9
|
+
# resource "aws_s3_bucket" "assets" {
|
|
10
|
+
# bucket = "company-production-assets"
|
|
11
|
+
# }
|
|
12
|
+
|
|
13
|
+
# After refactor:
|
|
14
|
+
module "storage" {
|
|
15
|
+
source = "../../modules/storage"
|
|
16
|
+
bucket_name = "company-production-assets"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
# Refactor migration declaration (prevents destructive delete/recreate):
|
|
20
|
+
moved {
|
|
21
|
+
from = aws_s3_bucket.assets
|
|
22
|
+
to = module.storage.aws_s3_bucket.this
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Example 2: Safe Environment Module Pattern
|
|
29
|
+
|
|
30
|
+
```hcl
|
|
31
|
+
# environments/prod/versions.tf
|
|
32
|
+
terraform {
|
|
33
|
+
required_version = ">= 1.9.0"
|
|
34
|
+
|
|
35
|
+
required_providers {
|
|
36
|
+
aws = {
|
|
37
|
+
source = "hashicorp/aws"
|
|
38
|
+
version = "~> 5.50.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
backend "s3" {
|
|
43
|
+
bucket = "tf-state-prod-lock"
|
|
44
|
+
key = "core/terraform.tfstate"
|
|
45
|
+
region = "us-east-1"
|
|
46
|
+
dynamodb_table = "tf-state-locks"
|
|
47
|
+
encrypt = true
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Example 3: Safe Destroy Verification Script
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
#!/usr/bin/env bash
|
|
58
|
+
set -euo pipefail
|
|
59
|
+
|
|
60
|
+
TARGET_RESOURCE="${1:-}"
|
|
61
|
+
|
|
62
|
+
if [[ -z "$TARGET_RESOURCE" ]]; then
|
|
63
|
+
echo "Error: Target resource address must be specified."
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo "Running safe destroy inspection for: $TARGET_RESOURCE"
|
|
68
|
+
terraform plan -destroy -target="$TARGET_RESOURCE" -out="destroy.tfplan"
|
|
69
|
+
|
|
70
|
+
# Display affected resources
|
|
71
|
+
terraform show -json destroy.tfplan | jq -r '.resource_changes[] | select(.change.actions[] == "delete") | .address'
|
|
72
|
+
|
|
73
|
+
echo "Carefully inspect the resources above. Run terraform apply destroy.tfplan only after manual confirmation."
|
|
74
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: terraform
|
|
3
|
+
description: Production-grade Terraform and OpenTofu IaC guidance. Enforces diagnose-first failure mode analysis, Safe Destroy Protocol, state management, and modular architecture.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Terraform and OpenTofu
|
|
7
|
+
|
|
8
|
+
Diagnose-first guidance for Terraform and OpenTofu infrastructure as code, inspired by Anton Babenko's engineering standards.
|
|
9
|
+
|
|
10
|
+
## Response Contract
|
|
11
|
+
|
|
12
|
+
Every Terraform or OpenTofu modification must declare:
|
|
13
|
+
1. **Assumptions & Version Floor**: Runtime (`terraform` or `tofu`), exact version, providers, backend type, and environment criticality.
|
|
14
|
+
2. **Risk Category Addressed**: Identify whether the change impacts identity churn, secret exposure, blast radius, destroy cascades, or CI drift.
|
|
15
|
+
3. **Chosen Remediation & Trade-offs**: Why this approach was selected over alternatives.
|
|
16
|
+
4. **Validation Plan**: Exact commands (`terraform fmt -check`, `validate`, `plan -out=tfplan`) tailored to the change.
|
|
17
|
+
5. **Rollback Notes**: Clear procedure for reverting any state or resource mutation.
|
|
18
|
+
|
|
19
|
+
## Safe Destroy Protocol
|
|
20
|
+
|
|
21
|
+
Never run `terraform destroy` or remove state without strict guards:
|
|
22
|
+
- **Mandatory Plan-Destroy**: Never execute a destroy operation without first running `terraform plan -destroy` and displaying every single resource marked for deletion.
|
|
23
|
+
- **Check Implicit Dependents**: Review `locals` and `for_each` consumers referencing targeted resources to ensure no unexpected cascading deletions occur.
|
|
24
|
+
- **Zero Auto-Approve on Destroy**: The `-auto-approve` flag is strictly forbidden on destroy operations.
|
|
25
|
+
|
|
26
|
+
## Diagnose Before Generating
|
|
27
|
+
|
|
28
|
+
| Failure Category | Symptoms | Prevention Strategy |
|
|
29
|
+
|------------------|----------|---------------------|
|
|
30
|
+
| **Identity Churn** | Resource addresses shift after refactoring, recreation of stateful resources | Use `for_each` instead of numeric `count`; apply `moved` blocks for refactored addresses |
|
|
31
|
+
| **Secret Exposure** | Sensitive tokens in variables, plan outputs, or unencrypted state | Mark outputs/variables with `sensitive = true`; use KMS-encrypted remote backends |
|
|
32
|
+
| **Blast Radius** | Oversized monolithic state files, shared dev/prod configurations | Isolate state per environment and bounded context; keep modules focused |
|
|
33
|
+
| **Destroy Cascade** | Targeted destruction deletes dependent databases or networks | Run `plan -destroy` first; inspect dependency DAG |
|
|
34
|
+
| **CI Drift** | Local plan differs from CI runner; unpinned providers | Pin exact provider and module versions; run plans strictly against reviewed commit SHA |
|
|
35
|
+
|
|
36
|
+
## Module Hierarchy & Directory Layout
|
|
37
|
+
|
|
38
|
+
Structure infrastructure into three distinct layers:
|
|
39
|
+
1. **Resource Module**: Single logical grouping of closely connected resources (e.g. VPC + subnets, or S3 bucket + bucket policy).
|
|
40
|
+
2. **Infrastructure Module**: Collection of resource modules fulfilling a sub-system (e.g. multi-region compute cluster with monitoring).
|
|
41
|
+
3. **Composition**: Environment-level assembly tying modules together for a specific environment (`dev`, `staging`, `prod`).
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
environments/
|
|
45
|
+
prod/
|
|
46
|
+
main.tf # Calls reusable modules
|
|
47
|
+
variables.tf
|
|
48
|
+
outputs.tf
|
|
49
|
+
versions.tf # Exact provider pins & backend configuration
|
|
50
|
+
modules/
|
|
51
|
+
networking/
|
|
52
|
+
main.tf
|
|
53
|
+
variables.tf
|
|
54
|
+
outputs.tf
|
|
55
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Terraform - Troubleshooting & Common Edge Cases
|
|
2
|
+
|
|
3
|
+
## Common Diagnostic Scenarios
|
|
4
|
+
|
|
5
|
+
### 1. Stuck Remote State Lock (`Error acquiring the state lock`)
|
|
6
|
+
|
|
7
|
+
- **Symptom**: Terraform commands abort with `Error message: ConditionalCheckFailedException: The conditional request failed` or `Lock Info: ID: <lock-id>`.
|
|
8
|
+
- **Root Cause**: A previous CI runner or local process crashed, timed out, or was killed before releasing the DynamoDB or backend lock.
|
|
9
|
+
- **Fix Protocol**:
|
|
10
|
+
1. Inspect the Lock Info: verify the lock owner and creation timestamp.
|
|
11
|
+
2. Confirm that no active pipeline or engineer is running an apply on this workspace.
|
|
12
|
+
3. Force-unlock using the exact Lock ID:
|
|
13
|
+
```bash
|
|
14
|
+
terraform force-unlock <lock-id>
|
|
15
|
+
```
|
|
16
|
+
4. Never disable locks by setting `-lock=false`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
### 2. Cascading Destruction of Dependent Resources via `for_each` / `locals`
|
|
21
|
+
|
|
22
|
+
- **Symptom**: Destroying a single resource triggers planned deletion of dozens of downstream resources.
|
|
23
|
+
- **Root Cause**: Downstream resources reference the targeted resource in a `for_each` map or local projection. Removing the upstream resource causes keys in `for_each` to disappear, queueing destruction of all instances.
|
|
24
|
+
- **Fix Protocol**:
|
|
25
|
+
1. Always run `terraform plan -destroy -target=<resource>` first.
|
|
26
|
+
2. Inspect the resource changes list for unexpected deletions.
|
|
27
|
+
3. Decouple downstream configurations or provide static placeholder values in `locals` before attempting targeted deletion.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### 3. Identity Churn on Refactoring Module Paths
|
|
32
|
+
|
|
33
|
+
- **Symptom**: After restructuring modules, `terraform plan` reports: `Plan: 5 to add, 0 to change, 5 to destroy` for existing stateful resources.
|
|
34
|
+
- **Root Cause**: Changing module names or nesting paths changes the resource addresses in the Terraform state file.
|
|
35
|
+
- **Fix Protocol**:
|
|
36
|
+
- Use `moved` blocks to cleanly inform Terraform of the address change:
|
|
37
|
+
```hcl
|
|
38
|
+
moved {
|
|
39
|
+
from = module.old_network.aws_vpc.main
|
|
40
|
+
to = module.vpc.aws_vpc.this
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
- Re-run `terraform plan`. It should now report `Plan: 0 to add, 0 to change, 0 to destroy` with a clear notice of moved resource addresses.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
### 4. Cyclic Dependency Errors (`Cycle: module.a, module.b`)
|
|
48
|
+
|
|
49
|
+
- **Symptom**: Terraform graph computation aborts with a cyclic dependency error.
|
|
50
|
+
- **Root Cause**: Module A references outputs from Module B, while Module B references outputs from Module A.
|
|
51
|
+
- **Fix Protocol**:
|
|
52
|
+
1. Break bidirectional coupling by extracting the shared configuration or data resource into a dedicated upstream module (e.g. `module.shared_networking`).
|
|
53
|
+
2. Pass IDs downward; never allow lower-tier modules to depend on upper-tier compositions.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "terraform",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"checks": [
|
|
5
|
+
"Response contract declared with assumptions, risk category, and rollback plan",
|
|
6
|
+
"Safe destroy protocol strictly enforced without -auto-approve",
|
|
7
|
+
"Module hierarchy maintained (resource -> infrastructure -> composition)",
|
|
8
|
+
"Remote backend configured with state locking and encryption at rest",
|
|
9
|
+
"Resource refactoring uses moved blocks to prevent identity churn"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
schemaVersion: 2
|
|
2
|
+
name: terraform
|
|
3
|
+
description: Production-grade Terraform and OpenTofu IaC guidance inspired by Anton Babenko. Enforces diagnose-first failure mode analysis, Safe Destroy Protocol, and modular composition.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: devops
|
|
6
|
+
type: instruction-only
|
|
7
|
+
requires:
|
|
8
|
+
- engineering-workflow
|
|
9
|
+
- decisions
|
|
10
|
+
resources:
|
|
11
|
+
- EXAMPLES.md
|
|
12
|
+
- SKILL.md
|
|
13
|
+
- TROUBLESHOOTING.md
|
|
14
|
+
- VALIDATION.json
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Testing Examples - Anti-patterns vs ContextOS Standard
|
|
2
|
+
|
|
3
|
+
## Example 1: React Component Testing
|
|
4
|
+
|
|
5
|
+
### Anti-pattern: Anti-pattern (Brittle query & implementation coupling)
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// BAD: querying by CSS class or test-id and testing internal state
|
|
9
|
+
test('submits form', async () => {
|
|
10
|
+
const wrapper = render(<LoginForm />);
|
|
11
|
+
const input = wrapper.container.querySelector('.email-input');
|
|
12
|
+
fireEvent.change(input, { target: { value: 'user@test.com' } });
|
|
13
|
+
fireEvent.click(wrapper.container.querySelector('#submit-btn'));
|
|
14
|
+
expect(wrapper.state().isSubmitted).toBe(true); // Brittle!
|
|
15
|
+
});
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Best practice: ContextOS Standard (User-centric role queries & userEvent)
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// GOOD: user-facing roles, userEvent, async wait
|
|
22
|
+
import { render, screen } from '@testing-library/react';
|
|
23
|
+
import userEvent from '@testing-library/user-event';
|
|
24
|
+
import { LoginForm } from './LoginForm';
|
|
25
|
+
|
|
26
|
+
test('submits form with valid user credentials', async () => {
|
|
27
|
+
const user = userEvent.setup();
|
|
28
|
+
const onSubmit = vi.fn();
|
|
29
|
+
render(<LoginForm onSubmit={onSubmit} />);
|
|
30
|
+
|
|
31
|
+
await user.type(screen.getByLabelText(/email address/i), 'user@test.com');
|
|
32
|
+
await user.type(screen.getByLabelText(/password/i), 'SecureP@ss123!');
|
|
33
|
+
await user.click(screen.getByRole('button', { name: /sign in/i }));
|
|
34
|
+
|
|
35
|
+
expect(onSubmit).toHaveBeenCalledWith({
|
|
36
|
+
email: 'user@test.com',
|
|
37
|
+
password: 'SecureP@ss123!'
|
|
38
|
+
});
|
|
39
|
+
expect(screen.queryByRole('alert')).not.toBeInTheDocument();
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Example 2: API Mocking with MSW (Mock Service Worker)
|
|
46
|
+
|
|
47
|
+
### Anti-pattern: Anti-pattern (Hardcoded global fetch monkey-patching)
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// BAD: globally overwriting fetch breaks other tests and hides actual contract
|
|
51
|
+
global.fetch = vi.fn().mockResolvedValue({
|
|
52
|
+
json: () => Promise.resolve({ data: 'ok' })
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Best practice: ContextOS Standard (Network boundary mocking)
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// GOOD: declarative MSW network handler
|
|
60
|
+
import { http, HttpResponse } from 'msw';
|
|
61
|
+
import { setupServer } from 'msw/node';
|
|
62
|
+
|
|
63
|
+
export const server = setupServer(
|
|
64
|
+
http.get('/api/users/:id', ({ params }) => {
|
|
65
|
+
if (params.id === '404') {
|
|
66
|
+
return new HttpResponse(null, { status: 404 });
|
|
67
|
+
}
|
|
68
|
+
return HttpResponse.json({ id: params.id, name: 'Alice Smith' });
|
|
69
|
+
})
|
|
70
|
+
);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Example 3: End-to-End User Journey with Playwright
|
|
76
|
+
|
|
77
|
+
### Anti-pattern (Brittle CSS selectors and explicit sleeps)
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// BAD: XPath / brittle class selectors and fixed timer sleeps
|
|
81
|
+
test('creates new task', async ({ page }) => {
|
|
82
|
+
await page.goto('http://localhost:3000');
|
|
83
|
+
await page.waitForTimeout(5000); // Brittle!
|
|
84
|
+
await page.click('.btn-primary-small'); // Class name will change with CSS refactoring
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Best practice: ContextOS Standard (Accessible locators & auto-waiting)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { test, expect } from '@playwright/test';
|
|
92
|
+
|
|
93
|
+
test.describe('Task Management Journey', () => {
|
|
94
|
+
test.beforeEach(async ({ page }) => {
|
|
95
|
+
// Navigate using baseURL configured in playwright.config.ts
|
|
96
|
+
await page.goto('/tasks');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('creates, completes, and deletes a task', async ({ page }) => {
|
|
100
|
+
// 1. Fill input using accessible label
|
|
101
|
+
const input = page.getByRole('textbox', { name: /new task title/i });
|
|
102
|
+
await input.fill('Deploy production release');
|
|
103
|
+
|
|
104
|
+
// 2. Click button using accessible role
|
|
105
|
+
await page.getByRole('button', { name: /add task/i }).click();
|
|
106
|
+
|
|
107
|
+
// 3. Auto-waiting assertion for item appearance
|
|
108
|
+
const taskItem = page.getByRole('listitem').filter({ hasText: 'Deploy production release' });
|
|
109
|
+
await expect(taskItem).toBeVisible();
|
|
110
|
+
|
|
111
|
+
// 4. Toggle completion checkbox
|
|
112
|
+
const checkbox = taskItem.getByRole('checkbox', { name: /mark as done/i });
|
|
113
|
+
await checkbox.check();
|
|
114
|
+
await expect(checkbox).toBeChecked();
|
|
115
|
+
|
|
116
|
+
// 5. Delete task and verify disappearance
|
|
117
|
+
await taskItem.getByRole('button', { name: /delete task/i }).click();
|
|
118
|
+
await expect(taskItem).not.toBeVisible();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
```
|
|
122
|
+
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
description: Vitest, React Testing Library, and Playwright testing standards. Enforces TDD/BDD, test pyramid, zero brittle mocks, and complete assertion coverage.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Testing
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Testing strategy across unit, component, integration, and end-to-end testing suites using Vitest, React Testing Library, and Playwright.
|
|
11
|
+
|
|
12
|
+
## When to Use
|
|
13
|
+
|
|
14
|
+
Activate for any task involving unit tests, integration tests, E2E testing, TDD/BDD workflows, or fixing regression bugs.
|
|
15
|
+
|
|
16
|
+
## Rules & Patterns
|
|
17
|
+
|
|
18
|
+
### ️ The ContextOS Testing Pyramid
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
/\
|
|
22
|
+
/E2E\ 10% - Playwright (Critical user journeys, auth, checkout)
|
|
23
|
+
/-----\
|
|
24
|
+
/ Integ \ 20% - API & Component Integration (RTL + MSW / Supertest)
|
|
25
|
+
/---------\
|
|
26
|
+
/ Unit \ 70% - Pure functions, Domain Entities, Utils (Vitest)
|
|
27
|
+
/-------------\
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Negative Constraints (What NOT to Do)
|
|
31
|
+
|
|
32
|
+
1. **NEVER mock internal implementation details**: Mock ONLY external I/O boundaries (HTTP network requests via MSW, Database via test containers or in-memory DB).
|
|
33
|
+
2. **NEVER test implementation details**: In React Testing Library, query by user-facing roles (`getByRole`, `getByLabelText`), NEVER by CSS selectors or internal component state.
|
|
34
|
+
3. **NEVER write assertions without an expected failure mode**: Each test must test a single logical behavior and fail if that behavior breaks.
|
|
35
|
+
4. **NEVER leave flaky tests or arbitrary sleep (`await delay(1000)`)**: Always use `waitFor()` or explicit event triggers with timeouts.
|
|
36
|
+
5. **NEVER share mutable state between tests**: Every test must have isolated state via `beforeEach()` setup and clean reset.
|
|
37
|
+
|
|
38
|
+
### AAA Standard Pattern
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
describe('Feature / Unit', () => {
|
|
42
|
+
it('should achieve expected outcome when given specific condition', async () => {
|
|
43
|
+
// 1. ARRANGE
|
|
44
|
+
const user = createTestUser({ role: 'admin' });
|
|
45
|
+
// 2. ACT
|
|
46
|
+
const result = await processOrder(user, sampleCart);
|
|
47
|
+
// 3. ASSERT
|
|
48
|
+
expect(result.status).toBe('confirmed');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Code Examples
|
|
54
|
+
|
|
55
|
+
See `EXAMPLES.md` for detailed anti-patterns and production testing code.
|
|
56
|
+
|
|
57
|
+
## Validation Checklist
|
|
58
|
+
|
|
59
|
+
- [ ] Tests follow Arrange-Act-Assert (AAA) structure
|
|
60
|
+
- [ ] No brittle CSS selectors or private state inspections
|
|
61
|
+
- [ ] Mocks isolated strictly to network/IO boundaries (MSW)
|
|
62
|
+
- [ ] Fast execution (< 5s for unit suite) with zero flaky sleeps
|
|
63
|
+
|
|
64
|
+
## Common Mistakes
|
|
65
|
+
|
|
66
|
+
- Over-mocking modules instead of running real pure logic. See `TROUBLESHOOTING.md`.
|
|
67
|
+
|
|
68
|
+
## Integration Notes
|
|
69
|
+
|
|
70
|
+
Interacts directly with `engineering-workflow` (Verify phase), `react`, and `typescript`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Testing Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## Common Issues & Fixes
|
|
4
|
+
|
|
5
|
+
### 1. `act(...)` warning in React Testing Library
|
|
6
|
+
|
|
7
|
+
- **Cause**: An asynchronous state update triggered after the test completed.
|
|
8
|
+
- **Fix**: Ensure all async operations are awaited using `await waitFor(() => ...)` or `await screen.findByRole(...)`.
|
|
9
|
+
|
|
10
|
+
### 2. Tests pass in isolation but fail in concurrent test runs
|
|
11
|
+
|
|
12
|
+
- **Cause**: Shared in-memory state or un-reset singleton.
|
|
13
|
+
- **Fix**: Reset all mocks and in-memory databases in `beforeEach(() => vi.clearAllMocks())` and `afterEach(() => cleanup())`.
|
|
14
|
+
|
|
15
|
+
### 3. Playwright timeout waiting for selector
|
|
16
|
+
|
|
17
|
+
- **Cause**: Element is animating or blocked behind a modal/overlay.
|
|
18
|
+
- **Fix**: Use web-first assertions like `await expect(page.getByRole('button')).toBeVisible()` which automatically retry until timeout.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill": "testing",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"checks": [
|
|
5
|
+
"Test pyramid ratio enforced (70% unit/integration)",
|
|
6
|
+
"AAA (Arrange-Act-Assert) pattern implemented",
|
|
7
|
+
"No internal state inspection or brittle selectors",
|
|
8
|
+
"MSW used for network boundaries",
|
|
9
|
+
"Zero shared state between test executions"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
schemaVersion: 2
|
|
2
|
+
name: testing
|
|
3
|
+
description: Vitest, React Testing Library, and Playwright testing standards. Enforces TDD/BDD, test pyramid, zero brittle mocks, and complete assertion coverage.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: engineering
|
|
6
|
+
type: instruction-only
|
|
7
|
+
requires:
|
|
8
|
+
- engineering-workflow
|
|
9
|
+
- typescript
|
|
10
|
+
resources:
|
|
11
|
+
- EXAMPLES.md
|
|
12
|
+
- SKILL.md
|
|
13
|
+
- TROUBLESHOOTING.md
|
|
14
|
+
- VALIDATION.json
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# TypeScript Examples - Anti-patterns vs ContextOS Standard
|
|
2
|
+
|
|
3
|
+
## Example 1: Type-Safe Parsing with Zod (No `any`)
|
|
4
|
+
|
|
5
|
+
### Anti-pattern: Anti-pattern (Blind type assertion with `as`)
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
// BAD: using 'as User' bypasses runtime validation completely
|
|
9
|
+
async function fetchUser(id: string): Promise<User> {
|
|
10
|
+
const res = await fetch(`/api/users/${id}`);
|
|
11
|
+
const data = await res.json();
|
|
12
|
+
return data as User; // Runtime crash if payload changes!
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Best practice: ContextOS Standard (Runtime schema validation with Zod)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// GOOD: guaranteed runtime and compile-time type safety
|
|
20
|
+
import { z } from 'zod';
|
|
21
|
+
|
|
22
|
+
export const UserSchema = z.object({
|
|
23
|
+
id: z.string().uuid(),
|
|
24
|
+
name: z.string().min(1),
|
|
25
|
+
email: z.string().email(),
|
|
26
|
+
role: z.enum(['admin', 'member', 'guest']),
|
|
27
|
+
createdAt: z.string().datetime(),
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export type User = z.infer<typeof UserSchema>;
|
|
31
|
+
|
|
32
|
+
export async function fetchUser(id: string): Promise<User> {
|
|
33
|
+
const res = await fetch(`/api/users/${id}`);
|
|
34
|
+
if (!res.ok) throw new Error(`Fetch failed with status ${res.status}`);
|
|
35
|
+
const raw: unknown = await res.json();
|
|
36
|
+
return UserSchema.parse(raw);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Example 2: Discriminated Unions for State Handling
|
|
43
|
+
|
|
44
|
+
### Anti-pattern: Anti-pattern (Optional soup with boolean flags)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// BAD: impossible states can be represented (e.g. isLoading: true AND error: 'Failed')
|
|
48
|
+
interface AsyncState<T> {
|
|
49
|
+
data?: T;
|
|
50
|
+
isLoading: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Best practice: ContextOS Standard (Discriminated Union)
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// GOOD: impossible states are impossible at compile-time
|
|
59
|
+
export type AsyncState<T> =
|
|
60
|
+
| { readonly status: 'idle' }
|
|
61
|
+
| { readonly status: 'loading' }
|
|
62
|
+
| { readonly status: 'success'; readonly data: T }
|
|
63
|
+
| { readonly status: 'error'; readonly error: Error };
|
|
64
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: TypeScript
|
|
3
|
+
description: >
|
|
4
|
+
ContextOS skill for TypeScript
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TypeScript
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Strict TypeScript engineering standard. Enforces noImplicitAny, discriminated unions, branded types, immutability, exhaustive switch checks, and zero unsafe any or as unknown as T casts.
|
|
12
|
+
|
|
13
|
+
## When to Use
|
|
14
|
+
|
|
15
|
+
Activate on all TypeScript and JavaScript codebases to ensure compile-time type safety, robust domain modeling, and foolproof function contracts.
|
|
16
|
+
|
|
17
|
+
## Negative Constraints (What NOT to Do)
|
|
18
|
+
|
|
19
|
+
1. **NEVER use `any`**: Use `unknown` with type guards, discriminated unions, or Zod schemas.
|
|
20
|
+
2. **NEVER use type assertions (`as Type` or `as unknown as Type`) to bypass safety**: Fix the underlying type signature or use runtime narrowing (`instanceof`, `typeof`, `in`).
|
|
21
|
+
3. **NEVER use non-null assertions (`foo!.bar`)**: Handle `null` and `undefined` with optional chaining (`?.`) or explicit error guards.
|
|
22
|
+
4. **NEVER export mutable global arrays or object constants**: Always mark constant objects and arrays with `as const` and `readonly`.
|
|
23
|
+
5. **NEVER omit explicit return types on exported functions**: Exported public APIs must declare explicit return types to protect consumers.
|
|
24
|
+
|
|
25
|
+
## Rules & Patterns
|
|
26
|
+
|
|
27
|
+
## Strict Mode
|
|
28
|
+
|
|
29
|
+
Always use strict TypeScript configuration:
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"compilerOptions": {
|
|
34
|
+
"strict": true,
|
|
35
|
+
"noUncheckedIndexedAccess": true,
|
|
36
|
+
"noImplicitReturns": true,
|
|
37
|
+
"noFallthroughCasesInSwitch": true
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Types
|
|
43
|
+
|
|
44
|
+
- **Prefer `interface`** for object shapes, `type` for unions/intersections
|
|
45
|
+
- **No `any`** - use `unknown` if type is truly unknown, then narrow
|
|
46
|
+
- **Explicit return types** for exported functions
|
|
47
|
+
- **Const assertions** - `as const` for literal types
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// Good
|
|
51
|
+
interface User {
|
|
52
|
+
id: string;
|
|
53
|
+
name: string;
|
|
54
|
+
role: 'admin' | 'user';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Unions
|
|
58
|
+
type Result<T> = { ok: true; data: T } | { ok: false; error: string };
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Utility Types
|
|
62
|
+
|
|
63
|
+
- `Partial<T>` - all properties optional
|
|
64
|
+
- `Required<T>` - all properties required
|
|
65
|
+
- `Pick<T, K>` - select specific properties
|
|
66
|
+
- `Omit<T, K>` - remove specific properties
|
|
67
|
+
- `Record<K, V>` - key-value map
|
|
68
|
+
|
|
69
|
+
## Type Guards
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
function isUser(value: unknown): value is User {
|
|
73
|
+
return typeof value === 'object' && value !== null && 'id' in value;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Generic Patterns
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Repository pattern
|
|
81
|
+
interface Repository<T extends { id: string }> {
|
|
82
|
+
findById(id: string): Promise<T | null>;
|
|
83
|
+
create(data: Omit<T, 'id'>): Promise<T>;
|
|
84
|
+
update(id: string, data: Partial<T>): Promise<T>;
|
|
85
|
+
delete(id: string): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Anti-Patterns
|
|
90
|
+
|
|
91
|
+
- [FAIL] `any` - use `unknown` + type guards
|
|
92
|
+
- [FAIL] Type assertions (`as`) - prefer type guards
|
|
93
|
+
- [FAIL] Non-null assertions (`!`) - handle null explicitly
|
|
94
|
+
- [FAIL] Enums - prefer union types or `as const` objects
|
|
95
|
+
- [FAIL] Complex generics without JSDoc - document intent
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Code Examples
|
|
99
|
+
|
|
100
|
+
See `EXAMPLES.md` for detailed code examples.
|
|
101
|
+
|
|
102
|
+
## Validation Checklist
|
|
103
|
+
|
|
104
|
+
What to verify during the review phase before completing the task.
|
|
105
|
+
|
|
106
|
+
## Common Mistakes
|
|
107
|
+
|
|
108
|
+
Anti-patterns and things to explicitly avoid. See `TROUBLESHOOTING.md`.
|
|
109
|
+
|
|
110
|
+
## Integration Notes
|
|
111
|
+
|
|
112
|
+
How this skill interacts with other skills.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# typescript Troubleshooting & Common Mistakes
|
|
2
|
+
|
|
3
|
+
## 1. Excessive Use of `any` or `as unknown as T`
|
|
4
|
+
|
|
5
|
+
- **Symptom**: Runtime `TypeError: Cannot read properties of undefined` in supposedly typed TypeScript code.
|
|
6
|
+
- **Root Cause**: Bypassing type checking with `any` or forceful type assertions.
|
|
7
|
+
- **Fix**: Use `unknown` with type guards, Zod schemas, or discriminated unions.
|
|
8
|
+
|
|
9
|
+
## 2. Non-Exhaustive Switch on Unions
|
|
10
|
+
|
|
11
|
+
- **Symptom**: New union member added but some switch statements fail to handle it, producing bugs.
|
|
12
|
+
- **Root Cause**: Missing exhaustive type checking in `default:` case.
|
|
13
|
+
- **Fix**: Add `default: const _exhaustive: never = action; throw new Error(_exhaustive);` to let the compiler catch missing branches.
|
|
14
|
+
|
|
15
|
+
## 3. Inaccurate Generics Constraints
|
|
16
|
+
|
|
17
|
+
- **Symptom**: Generic functions that lose type inference and resolve to `unknown`.
|
|
18
|
+
- **Root Cause**: Over-specifying generics or missing `extends` constraints.
|
|
19
|
+
- **Fix**: Constrain generics narrowly: `function get<T, K extends keyof T>(obj: T, key: K): T[K]`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
schemaVersion: 2
|
|
2
|
+
id: typescript
|
|
3
|
+
name: TypeScript
|
|
4
|
+
category: frontend
|
|
5
|
+
type: instruction-only
|
|
6
|
+
requires: []
|
|
7
|
+
optional: [zod, prisma]
|
|
8
|
+
conflicts: []
|
|
9
|
+
weight: 9
|
|
10
|
+
resources:
|
|
11
|
+
- EXAMPLES.md
|
|
12
|
+
- SKILL.md
|
|
13
|
+
- TROUBLESHOOTING.md
|
|
14
|
+
- VALIDATION.json
|