@slamb2k/mad-skills 2.0.13 → 2.0.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.
@@ -0,0 +1,474 @@
1
+ # Terraform Templates
2
+
3
+ Starter templates for common infrastructure components. Customize based on
4
+ INFRA_CONFIG from the interview. Each module is self-contained with its own
5
+ variables and outputs.
6
+
7
+ ---
8
+
9
+ ## Project Root
10
+
11
+ ### versions.tf
12
+
13
+ ```hcl
14
+ terraform {
15
+ required_version = ">= 1.5"
16
+
17
+ required_providers {
18
+ # Include only the provider(s) selected in the interview
19
+ azurerm = {
20
+ source = "hashicorp/azurerm"
21
+ version = "~> 4.0"
22
+ }
23
+ # aws = {
24
+ # source = "hashicorp/aws"
25
+ # version = "~> 5.0"
26
+ # }
27
+ # google = {
28
+ # source = "hashicorp/google"
29
+ # version = "~> 6.0"
30
+ # }
31
+ }
32
+ }
33
+ ```
34
+
35
+ ### main.tf — Azure
36
+
37
+ ```hcl
38
+ terraform {
39
+ backend "azurerm" {
40
+ resource_group_name = "{STATE_RG}"
41
+ storage_account_name = "{STATE_STORAGE}"
42
+ container_name = "tfstate"
43
+ key = "{PROJECT}.tfstate"
44
+ }
45
+ }
46
+
47
+ provider "azurerm" {
48
+ features {}
49
+ }
50
+
51
+ locals {
52
+ name_prefix = "{NAMING_PREFIX}-${var.environment}"
53
+ tags = {
54
+ project = "{PROJECT}"
55
+ environment = var.environment
56
+ managed_by = "terraform"
57
+ }
58
+ }
59
+
60
+ resource "azurerm_resource_group" "main" {
61
+ name = "rg-${local.name_prefix}"
62
+ location = var.location
63
+ tags = local.tags
64
+ }
65
+
66
+ module "registry" {
67
+ source = "./modules/registry"
68
+ name = "acr${replace(local.name_prefix, "-", "")}"
69
+ resource_group_name = azurerm_resource_group.main.name
70
+ location = azurerm_resource_group.main.location
71
+ sku = var.environment == "prod" ? "Premium" : "Basic"
72
+ tags = local.tags
73
+ }
74
+
75
+ # Add module calls for each selected component
76
+ ```
77
+
78
+ ### main.tf — AWS
79
+
80
+ ```hcl
81
+ terraform {
82
+ backend "s3" {
83
+ bucket = "{PROJECT}-tfstate"
84
+ key = "infra/{PROJECT}.tfstate"
85
+ region = "{REGION}"
86
+ dynamodb_table = "{PROJECT}-tflock"
87
+ encrypt = true
88
+ }
89
+ }
90
+
91
+ provider "aws" {
92
+ region = var.region
93
+
94
+ default_tags {
95
+ tags = {
96
+ Project = "{PROJECT}"
97
+ Environment = var.environment
98
+ ManagedBy = "terraform"
99
+ }
100
+ }
101
+ }
102
+
103
+ module "registry" {
104
+ source = "./modules/registry"
105
+ name = "{PROJECT}-${var.environment}"
106
+ }
107
+ ```
108
+
109
+ ### main.tf — GCP
110
+
111
+ ```hcl
112
+ terraform {
113
+ backend "gcs" {
114
+ bucket = "{PROJECT}-tfstate"
115
+ prefix = "infra"
116
+ }
117
+ }
118
+
119
+ provider "google" {
120
+ project = var.project_id
121
+ region = var.region
122
+ }
123
+
124
+ module "registry" {
125
+ source = "./modules/registry"
126
+ project_id = var.project_id
127
+ location = var.region
128
+ }
129
+ ```
130
+
131
+ ### variables.tf
132
+
133
+ ```hcl
134
+ variable "environment" {
135
+ description = "Deployment environment (dev, staging, prod)"
136
+ type = string
137
+ validation {
138
+ condition = contains(["dev", "staging", "prod"], var.environment)
139
+ error_message = "Environment must be dev, staging, or prod."
140
+ }
141
+ }
142
+
143
+ variable "location" {
144
+ description = "Cloud region"
145
+ type = string
146
+ default = "{DEFAULT_REGION}"
147
+ }
148
+
149
+ variable "project" {
150
+ description = "Project name"
151
+ type = string
152
+ default = "{PROJECT}"
153
+ }
154
+ ```
155
+
156
+ ### outputs.tf
157
+
158
+ ```hcl
159
+ output "registry_url" {
160
+ description = "Container registry login server URL"
161
+ value = module.registry.login_server
162
+ }
163
+
164
+ output "registry_name" {
165
+ description = "Container registry name"
166
+ value = module.registry.name
167
+ }
168
+
169
+ # Add outputs for each provisioned component
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Module: Container Registry
175
+
176
+ ### Azure (modules/registry/)
177
+
178
+ ```hcl
179
+ # modules/registry/main.tf
180
+ resource "azurerm_container_registry" "this" {
181
+ name = var.name
182
+ resource_group_name = var.resource_group_name
183
+ location = var.location
184
+ sku = var.sku
185
+ admin_enabled = false
186
+ tags = var.tags
187
+ }
188
+
189
+ output "login_server" { value = azurerm_container_registry.this.login_server }
190
+ output "name" { value = azurerm_container_registry.this.name }
191
+ output "id" { value = azurerm_container_registry.this.id }
192
+ ```
193
+
194
+ ### AWS (modules/registry/)
195
+
196
+ ```hcl
197
+ resource "aws_ecr_repository" "this" {
198
+ name = var.name
199
+ image_tag_mutability = "IMMUTABLE"
200
+
201
+ image_scanning_configuration {
202
+ scan_on_push = true
203
+ }
204
+
205
+ encryption_configuration {
206
+ encryption_type = "AES256"
207
+ }
208
+ }
209
+
210
+ resource "aws_ecr_lifecycle_policy" "this" {
211
+ repository = aws_ecr_repository.this.name
212
+ policy = jsonencode({
213
+ rules = [{
214
+ rulePriority = 1
215
+ description = "Keep last 50 images"
216
+ selection = {
217
+ tagStatus = "any"
218
+ countType = "imageCountMoreThan"
219
+ countNumber = 50
220
+ }
221
+ action = { type = "expire" }
222
+ }]
223
+ })
224
+ }
225
+
226
+ output "repository_url" { value = aws_ecr_repository.this.repository_url }
227
+ output "name" { value = aws_ecr_repository.this.name }
228
+ ```
229
+
230
+ ### GCP (modules/registry/)
231
+
232
+ ```hcl
233
+ resource "google_artifact_registry_repository" "this" {
234
+ location = var.location
235
+ repository_id = var.name
236
+ format = "DOCKER"
237
+ project = var.project_id
238
+ }
239
+
240
+ output "repository_url" {
241
+ value = "${var.location}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.this.repository_id}"
242
+ }
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Module: Managed Database
248
+
249
+ ### Azure PostgreSQL Flexible Server
250
+
251
+ ```hcl
252
+ # modules/database/main.tf
253
+ resource "azurerm_postgresql_flexible_server" "this" {
254
+ name = "psql-${var.name_prefix}"
255
+ resource_group_name = var.resource_group_name
256
+ location = var.location
257
+ version = "16"
258
+ administrator_login = var.admin_username
259
+ administrator_password = var.admin_password
260
+ storage_mb = var.environment == "prod" ? 65536 : 32768
261
+ sku_name = var.environment == "prod" ? "GP_Standard_D2s_v3" : "B_Standard_B1ms"
262
+ zone = var.environment == "prod" ? "1" : null
263
+ tags = var.tags
264
+
265
+ authentication {
266
+ active_directory_auth_enabled = true
267
+ password_auth_enabled = true
268
+ }
269
+ }
270
+
271
+ resource "azurerm_postgresql_flexible_server_database" "app" {
272
+ name = var.database_name
273
+ server_id = azurerm_postgresql_flexible_server.this.id
274
+ charset = "UTF8"
275
+ collation = "en_US.utf8"
276
+ }
277
+
278
+ resource "azurerm_postgresql_flexible_server_firewall_rule" "allow_azure" {
279
+ name = "AllowAzureServices"
280
+ server_id = azurerm_postgresql_flexible_server.this.id
281
+ start_ip_address = "0.0.0.0"
282
+ end_ip_address = "0.0.0.0"
283
+ }
284
+
285
+ output "fqdn" { value = azurerm_postgresql_flexible_server.this.fqdn }
286
+ output "connection_string" {
287
+ value = "postgresql://${var.admin_username}:${var.admin_password}@${azurerm_postgresql_flexible_server.this.fqdn}:5432/${var.database_name}?sslmode=require"
288
+ sensitive = true
289
+ }
290
+ ```
291
+
292
+ ### AWS RDS PostgreSQL
293
+
294
+ ```hcl
295
+ resource "aws_db_instance" "this" {
296
+ identifier = "${var.name_prefix}-db"
297
+ engine = "postgres"
298
+ engine_version = "16"
299
+ instance_class = var.environment == "prod" ? "db.t3.medium" : "db.t3.micro"
300
+
301
+ allocated_storage = var.environment == "prod" ? 100 : 20
302
+ max_allocated_storage = var.environment == "prod" ? 500 : 50
303
+ storage_encrypted = true
304
+
305
+ db_name = var.database_name
306
+ username = var.admin_username
307
+ password = var.admin_password
308
+
309
+ multi_az = var.environment == "prod"
310
+ backup_retention_period = var.environment == "prod" ? 14 : 1
311
+ skip_final_snapshot = var.environment != "prod"
312
+
313
+ vpc_security_group_ids = [var.db_security_group_id]
314
+ db_subnet_group_name = var.db_subnet_group_name
315
+
316
+ tags = var.tags
317
+ }
318
+
319
+ output "endpoint" { value = aws_db_instance.this.endpoint }
320
+ output "connection_string" {
321
+ value = "postgresql://${var.admin_username}:${var.admin_password}@${aws_db_instance.this.endpoint}/${var.database_name}"
322
+ sensitive = true
323
+ }
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Module: Serverless Containers
329
+
330
+ ### Azure Container Apps
331
+
332
+ ```hcl
333
+ resource "azurerm_container_app_environment" "this" {
334
+ name = "cae-${var.name_prefix}"
335
+ resource_group_name = var.resource_group_name
336
+ location = var.location
337
+ tags = var.tags
338
+ }
339
+
340
+ output "id" { value = azurerm_container_app_environment.this.id }
341
+ output "default_domain" { value = azurerm_container_app_environment.this.default_domain }
342
+ ```
343
+
344
+ ### AWS ECS Fargate Cluster
345
+
346
+ ```hcl
347
+ resource "aws_ecs_cluster" "this" {
348
+ name = "${var.name_prefix}-cluster"
349
+
350
+ setting {
351
+ name = "containerInsights"
352
+ value = var.environment == "prod" ? "enabled" : "disabled"
353
+ }
354
+ }
355
+
356
+ resource "aws_ecs_cluster_capacity_providers" "this" {
357
+ cluster_name = aws_ecs_cluster.this.name
358
+ capacity_providers = ["FARGATE", "FARGATE_SPOT"]
359
+
360
+ default_capacity_provider_strategy {
361
+ capacity_provider = var.environment == "prod" ? "FARGATE" : "FARGATE_SPOT"
362
+ weight = 1
363
+ }
364
+ }
365
+
366
+ output "cluster_arn" { value = aws_ecs_cluster.this.arn }
367
+ output "cluster_name" { value = aws_ecs_cluster.this.name }
368
+ ```
369
+
370
+ ---
371
+
372
+ ## Module: Networking (Azure)
373
+
374
+ ```hcl
375
+ resource "azurerm_virtual_network" "this" {
376
+ name = "vnet-${var.name_prefix}"
377
+ resource_group_name = var.resource_group_name
378
+ location = var.location
379
+ address_space = [var.address_space]
380
+ tags = var.tags
381
+ }
382
+
383
+ resource "azurerm_subnet" "app" {
384
+ name = "snet-app"
385
+ resource_group_name = var.resource_group_name
386
+ virtual_network_name = azurerm_virtual_network.this.name
387
+ address_prefixes = [cidrsubnet(var.address_space, 8, 1)]
388
+ }
389
+
390
+ resource "azurerm_subnet" "db" {
391
+ name = "snet-db"
392
+ resource_group_name = var.resource_group_name
393
+ virtual_network_name = azurerm_virtual_network.this.name
394
+ address_prefixes = [cidrsubnet(var.address_space, 8, 2)]
395
+
396
+ delegation {
397
+ name = "postgresql"
398
+ service_delegation {
399
+ name = "Microsoft.DBforPostgreSQL/flexibleServers"
400
+ }
401
+ }
402
+ }
403
+
404
+ output "vnet_id" { value = azurerm_virtual_network.this.id }
405
+ output "app_subnet_id" { value = azurerm_subnet.app.id }
406
+ output "db_subnet_id" { value = azurerm_subnet.db.id }
407
+ ```
408
+
409
+ ---
410
+
411
+ ## Module: Key Vault / Secrets
412
+
413
+ ### Azure Key Vault
414
+
415
+ ```hcl
416
+ data "azurerm_client_config" "current" {}
417
+
418
+ resource "azurerm_key_vault" "this" {
419
+ name = "kv-${var.name_prefix}"
420
+ resource_group_name = var.resource_group_name
421
+ location = var.location
422
+ tenant_id = data.azurerm_client_config.current.tenant_id
423
+ sku_name = "standard"
424
+
425
+ enable_rbac_authorization = true
426
+ purge_protection_enabled = var.environment == "prod"
427
+
428
+ tags = var.tags
429
+ }
430
+
431
+ output "vault_uri" { value = azurerm_key_vault.this.vault_uri }
432
+ output "vault_id" { value = azurerm_key_vault.this.id }
433
+ ```
434
+
435
+ ### AWS Secrets Manager
436
+
437
+ ```hcl
438
+ resource "aws_secretsmanager_secret" "app" {
439
+ name = "${var.name_prefix}/app-secrets"
440
+ description = "Application secrets for ${var.name_prefix}"
441
+
442
+ tags = var.tags
443
+ }
444
+
445
+ output "secret_arn" { value = aws_secretsmanager_secret.app.arn }
446
+ ```
447
+
448
+ ---
449
+
450
+ ## Environment Variable Files
451
+
452
+ ### dev.tfvars
453
+
454
+ ```hcl
455
+ environment = "dev"
456
+ location = "{REGION}"
457
+ # Minimal sizing — cost-optimized for development
458
+ ```
459
+
460
+ ### staging.tfvars
461
+
462
+ ```hcl
463
+ environment = "staging"
464
+ location = "{REGION}"
465
+ # Standard sizing — mirrors prod structure at lower scale
466
+ ```
467
+
468
+ ### prod.tfvars
469
+
470
+ ```hcl
471
+ environment = "prod"
472
+ location = "{REGION}"
473
+ # Production sizing — HA, redundancy, scaling enabled
474
+ ```
@@ -0,0 +1,35 @@
1
+ [
2
+ {
3
+ "name": "banner-display",
4
+ "prompt": "/keel",
5
+ "assertions": [
6
+ { "type": "contains", "value": "██" },
7
+ { "type": "regex", "value": "⚓|🏗️|🌍|🔩|☁️|🧱|📐|🗺️" },
8
+ { "type": "semantic", "value": "Displays an ASCII art banner for the keel skill before doing anything else" }
9
+ ]
10
+ },
11
+ {
12
+ "name": "iac-tool-selection",
13
+ "prompt": "/keel for an Azure-hosted Node.js app",
14
+ "assertions": [
15
+ { "type": "semantic", "value": "Suggests or asks about IaC tool choice, mentioning at least Terraform and Bicep as options" },
16
+ { "type": "semantic", "value": "Detects or mentions Azure as the cloud provider" }
17
+ ]
18
+ },
19
+ {
20
+ "name": "skill-ordering",
21
+ "prompt": "/keel",
22
+ "assertions": [
23
+ { "type": "semantic", "value": "Describes the recommended skill ordering where /keel runs before /dock to provision infrastructure" },
24
+ { "type": "regex", "value": "(?i)(keel.*dock|infrastructure.*deploy|provision.*before)" }
25
+ ]
26
+ },
27
+ {
28
+ "name": "plan-apply-pattern",
29
+ "prompt": "/keel --skip-interview for a Terraform project on AWS",
30
+ "assertions": [
31
+ { "type": "semantic", "value": "Describes or generates a CI/CD pipeline that plans on pull requests and applies on merge" },
32
+ { "type": "semantic", "value": "Mentions state management for Terraform such as S3 backend or remote state" }
33
+ ]
34
+ }
35
+ ]
@@ -1,6 +1,6 @@
1
1
  {
2
- "generated": "2026-03-09T14:07:03.881Z",
3
- "count": 8,
2
+ "generated": "2026-03-09T16:34:19.534Z",
3
+ "count": 10,
4
4
  "skills": [
5
5
  {
6
6
  "name": "brace",
@@ -32,6 +32,26 @@
32
32
  "hasAssets": true,
33
33
  "hasTests": true
34
34
  },
35
+ {
36
+ "name": "dock",
37
+ "directory": "dock",
38
+ "description": ">- Generate container-based release pipelines that build once and promote immutable artifacts through environments (dev → staging → prod). Detects your stack, interviews for infrastructure choices, then outputs deterministic CI/CD files (Dockerfile, workflows, deployment manifests) that run without an LLM. Use when setting up deployment pipelines, containerizing an app, creating release workflows, or connecting CI to container-friendly infrastructure (Azure Container Apps, AWS Fargate, Google Cloud Run, Kubernetes, Dokku, Coolify, CapRover, etc.).",
39
+ "lines": 349,
40
+ "hasScripts": false,
41
+ "hasReferences": true,
42
+ "hasAssets": false,
43
+ "hasTests": true
44
+ },
45
+ {
46
+ "name": "keel",
47
+ "directory": "keel",
48
+ "description": ">- Generate Infrastructure as Code (IaC) pipelines that provision the cloud and container infrastructure your app deploys to. Interview-driven: detects your stack and cloud provider, then outputs deterministic IaC files (Terraform, Bicep, Pulumi, or CDK) plus CI/CD pipelines that plan on PR and apply on merge. Use when setting up cloud infrastructure, provisioning container registries, databases, networking, DNS, or any infrastructure that containers deploy onto. Designed to run before /dock — /keel lays the infrastructure, /dock deploys to it.",
49
+ "lines": 495,
50
+ "hasScripts": false,
51
+ "hasReferences": true,
52
+ "hasAssets": false,
53
+ "hasTests": true
54
+ },
35
55
  {
36
56
  "name": "prime",
37
57
  "directory": "prime",