@slamb2k/mad-skills 2.0.14 → 2.0.16
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-plugin/plugin.json +1 -1
- package/README.md +390 -15
- package/package.json +1 -1
- package/skills/brace/SKILL.md +1 -1
- package/skills/build/SKILL.md +6 -2
- package/skills/distil/SKILL.md +1 -1
- package/skills/dock/SKILL.md +357 -0
- package/skills/dock/references/dockerfile-templates.md +358 -0
- package/skills/dock/references/interview-guide.md +209 -0
- package/skills/dock/references/pipeline-templates.md +398 -0
- package/skills/dock/references/platform-deploy-guides.md +457 -0
- package/skills/dock/tests/evals.json +36 -0
- package/skills/keel/SKILL.md +498 -0
- package/skills/keel/references/bicep-templates.md +359 -0
- package/skills/keel/references/iac-pipeline-templates.md +519 -0
- package/skills/keel/references/interview-guide.md +257 -0
- package/skills/keel/references/terraform-templates.md +474 -0
- package/skills/keel/tests/evals.json +35 -0
- package/skills/manifest.json +27 -7
- package/skills/prime/SKILL.md +15 -10
- package/skills/prime/references/domains.md +27 -30
- package/skills/rig/SKILL.md +10 -1
- package/skills/ship/SKILL.md +1 -1
- package/skills/ship/references/stage-prompts.md +5 -13
- package/skills/speccy/SKILL.md +6 -2
|
@@ -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
|
+
]
|
package/skills/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generated": "2026-03-
|
|
3
|
-
"count":
|
|
2
|
+
"generated": "2026-03-09T17:01:26.694Z",
|
|
3
|
+
"count": 10,
|
|
4
4
|
"skills": [
|
|
5
5
|
{
|
|
6
6
|
"name": "brace",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"name": "build",
|
|
17
17
|
"directory": "build",
|
|
18
18
|
"description": "Context-isolated feature development pipeline. Takes a detailed design/plan as argument and executes the full feature-dev lifecycle (explore, question, architect, implement, review, ship) inside subagents so the primary conversation stays compact. Use when you have a well-defined plan and want autonomous execution with minimal context window consumption.",
|
|
19
|
-
"lines":
|
|
19
|
+
"lines": 332,
|
|
20
20
|
"hasScripts": false,
|
|
21
21
|
"hasReferences": true,
|
|
22
22
|
"hasAssets": false,
|
|
@@ -32,11 +32,31 @@
|
|
|
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": 358,
|
|
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": 499,
|
|
50
|
+
"hasScripts": false,
|
|
51
|
+
"hasReferences": true,
|
|
52
|
+
"hasAssets": false,
|
|
53
|
+
"hasTests": true
|
|
54
|
+
},
|
|
35
55
|
{
|
|
36
56
|
"name": "prime",
|
|
37
57
|
"directory": "prime",
|
|
38
|
-
"description": "\"Load project context before implementing features or making architectural decisions. Invoke proactively
|
|
39
|
-
"lines":
|
|
58
|
+
"description": "\"Load project context before implementing features or making architectural decisions. Invoke proactively at the start of significant work on any project. Scans CLAUDE.md, README, goals/, specs/, docs/, and source structure to build a context summary. Supports optional domain hints to focus on specific areas of the codebase. Use when you need project conventions, architecture understanding, or domain context before coding.\"",
|
|
59
|
+
"lines": 113,
|
|
40
60
|
"hasScripts": false,
|
|
41
61
|
"hasReferences": true,
|
|
42
62
|
"hasAssets": false,
|
|
@@ -46,7 +66,7 @@
|
|
|
46
66
|
"name": "rig",
|
|
47
67
|
"directory": "rig",
|
|
48
68
|
"description": "'Idempotently bootstrap any repository with standard development tools, hooks, and workflows. Use when starting work on a new repo, onboarding to an existing project, or ensuring a repo has proper CI/CD setup. Configures: git hooks (lefthook), commit message templates, PR templates, and GitHub Actions for lint/format/type-check/build. Prompts for user confirmation before changes. Triggers: \"bootstrap repo\", \"setup hooks\", \"configure CI\", \"rig\", \"standardize repo\".'",
|
|
49
|
-
"lines":
|
|
69
|
+
"lines": 206,
|
|
50
70
|
"hasScripts": false,
|
|
51
71
|
"hasReferences": true,
|
|
52
72
|
"hasAssets": true,
|
|
@@ -66,7 +86,7 @@
|
|
|
66
86
|
"name": "speccy",
|
|
67
87
|
"directory": "speccy",
|
|
68
88
|
"description": "Deep-dive interview skill for creating comprehensive specifications. Reviews existing code and docs, then interviews the user through multiple rounds of targeted questions covering technical implementation, UI/UX, concerns, and tradeoffs. Produces a structured spec via create-specification. Use when starting a new feature, system, or major change that needs a spec.",
|
|
69
|
-
"lines":
|
|
89
|
+
"lines": 170,
|
|
70
90
|
"hasScripts": false,
|
|
71
91
|
"hasReferences": true,
|
|
72
92
|
"hasAssets": false,
|
package/skills/prime/SKILL.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prime
|
|
3
|
-
description: "Load project context before implementing features or making architectural decisions. Invoke proactively
|
|
4
|
-
argument-hint:
|
|
5
|
-
allowed-tools: Read, Glob, Grep, LS
|
|
3
|
+
description: "Load project context before implementing features or making architectural decisions. Invoke proactively at the start of significant work on any project. Scans CLAUDE.md, README, goals/, specs/, docs/, and source structure to build a context summary. Supports optional domain hints to focus on specific areas of the codebase. Use when you need project conventions, architecture understanding, or domain context before coding."
|
|
4
|
+
argument-hint: "[domain hints: comma-separated directory or topic names to focus on]"
|
|
5
|
+
allowed-tools: Read, Glob, Grep, LS, Agent
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Prime - Project Context Loader
|
|
@@ -39,8 +39,9 @@ subagent — the primary thread only sees a structured PRIME_REPORT.
|
|
|
39
39
|
|
|
40
40
|
## Step 1: Parse Arguments
|
|
41
41
|
|
|
42
|
-
Extract domain hints from the request (comma-separated).
|
|
43
|
-
|
|
42
|
+
Extract domain hints from the request (comma-separated). These are directory
|
|
43
|
+
names or topic keywords to focus the context scan on. If no domain specified,
|
|
44
|
+
load core context only (CLAUDE.md, README, goals/, specs/).
|
|
44
45
|
|
|
45
46
|
## Step 2: Load Context via Subagent
|
|
46
47
|
|
|
@@ -64,15 +65,19 @@ Limit PRIME_REPORT to 30 lines maximum.
|
|
|
64
65
|
|
|
65
66
|
## Core Files (always load)
|
|
66
67
|
|
|
67
|
-
1. CLAUDE.md —
|
|
68
|
-
2.
|
|
69
|
-
3.
|
|
68
|
+
1. CLAUDE.md — Project conventions, architecture, instructions
|
|
69
|
+
2. README.md — Project overview, setup, usage
|
|
70
|
+
3. goals/ or specs/ — Project goals, specs, roadmap (scan directory if present)
|
|
71
|
+
4. docs/ — Documentation directory (scan if present)
|
|
70
72
|
|
|
71
|
-
If
|
|
73
|
+
If a file is missing, record as NOT FOUND and continue.
|
|
72
74
|
|
|
73
75
|
## Domain Files
|
|
74
76
|
|
|
75
|
-
{For each requested domain,
|
|
77
|
+
{For each requested domain hint, use Glob to find relevant files:}
|
|
78
|
+
- Search for directories matching the hint name (e.g., "auth" → src/auth/, lib/auth/)
|
|
79
|
+
- Search for files matching *{hint}*.md, *{hint}*.yaml, *{hint}*.json
|
|
80
|
+
- Read the most relevant matches (max 5 files per domain)
|
|
76
81
|
|
|
77
82
|
For each file:
|
|
78
83
|
- If it exists: read and summarise (2-3 lines max per domain)
|